Security, privacy and procurement

What leaves your machine, and when.

Bandura runs entirely on the computer it is installed on. This page is the detail behind that sentence, written for the person who has to approve the tool rather than the person who wants to use it.

The short version

  • No account, no sign-in, no telemetry, no crash reporting, no analytics in the app.
  • Flows, secrets, run history and settings are files on the user's own disk. We hold no copy and operate no server that stores customer data.
  • The app itself contacts exactly two things: the AI provider you configure, and GitHub's public releases page. Both are named below, and both can be turned off.
  • Licences verify offline against a key compiled into the binary. There is no activation call and no kill switch.
  • No SOC 2, no ISO 27001, no penetration-test report. Said plainly rather than implied away.

A question this page does not answer: [email protected]. Answers come from the person who wrote the code.

Checkable against v1.0.0-rc.7, the build the download page serves. Every statement here was read out of the source files named in this page's own markup on 9 August 2026. Where the current release and this page disagree, this page is the one that is wrong, and it is worth an email.

Data flow

Everything that crosses the network boundary.

The complete list, not the highlights. If a row is missing from this table, it is a bug in the table or a bug in the app, and either one is worth an email.

Network requests Bandura makes, what triggers each one, what it carries, and how to stop it
Request When What it carries Turn it off
The requests in your flows When you press Run, or the CLI runs Exactly what the flow describes, to exactly the hosts it names. Nothing is mirrored, proxied or logged anywhere else. Do not run the flow
Your AI provider Only when you use chat, flow generation, inline completion or an ai-action node The prompt and the flow context that feature needs, sent with your key to the endpoint you configured. Never to us. Do not configure a provider, or point it at a local model and it stays on the machine
The version check At most once a day, at startup A plain GET for the public releases list. No identifier, no licence key, nothing about the machine, nothing about your flows. updates.checkOnStartup: false in settings
The update download Only after you press the button, or turn on automatic downloads The installer for the version you were told about, from the same public releases page. Fetching a file tells GitHub which file, so it reveals the operating system, the processor architecture and the version. No identifier, no account, no licence key. The same disclosure as downloading it from this site in a browser. On a Linux .deb and on macOS it does not run at all: those builds are sent here instead. Off by default (updates.autoDownload), and updates.checkOnStartup: false stops it too

That is the whole table, and it reaches two destinations: a provider you chose, and GitHub. There is no fourth row, and adding a new destination would be a licence amendment rather than a code change: §7 of the agreement names every self-initiated request explicitly, which is what makes the promise enforceable rather than merely stated. Updates are also the one place we do not claim more than we can check: the download is verified against the checksum published beside it, over HTTPS, which catches a corrupted or truncated transfer. It is not a signature of ours, so it does not prove the file was not replaced at the source. We would rather say that than imply an integrity guarantee we have not built yet.

Storage

Where every piece of it actually sits.

All of it is on the user's disk, under their own account. None of it is encrypted at rest by Bandura except where noted, because the file-system permissions and the disk encryption your fleet already enforces are the right layer for that.

What Bandura stores, where it stores it, and how it is protected
What Where Protection
Flows .aether files in your own repository, wherever you put it Whatever your repository and disk already do. We add nothing and take nothing.
API keys and provider secrets secrets.json in the app's data directory Encrypted through the OS secret store: Keychain on macOS, DPAPI on Windows, the Secret Service API on Linux. The file is owner-only (mode 0600), and a file created by an earlier version is tightened the first time this one opens it. On Linux with no keyring installed (no gnome-keyring, no kwallet), the OS reports encryption as available while actually using a key that is public in Chromium's source, which is not meaningful protection. Bandura detects that configuration and records a warning in its error log rather than implying a keychain is holding them; installing a keyring is the fix.
Licence key Kept apart from both settings and secrets Signed, and verified in-app against a compiled-in public key. Portable to a new machine, and quotable in a support email
Run history history.db, a local SQLite file Local file permissions. Delete the file and the history is gone; nothing replicates it
AI chat history chat.db, a local SQLite file Your conversations with the assistant, kept so you can reopen one. Turn it off with the "Remember chat history" setting, which stops new writes. Delete the file and they are gone; nothing replicates it
Workspace search index retrieval.db, a local SQLite full-text index Lets the assistant find relevant flows without reading every file. Built on your machine with no network request and no embedding service. Two filters run before anything is written: values under credential-shaped field names (Authorization, api-key, client_secret and the like) are never indexed, and text matching common credential formats (bearer tokens, JWTs, private keys, the major providers' key formats) is dropped. Neither filter can recognise a bespoke secret, so a custom opaque value under an ordinary field name would be indexed
Settings settings.json, hand-editable JSON with comments Deliberately plain text, and deliberately holds no secret of any kind. Writes are atomic, so an interrupted save cannot truncate it
Feedback reports bandura-feedback-<timestamp>.txt, beside the error log Written only when you use "Send Feedback", and only when the report is too long to carry in the mail itself. Nothing is transmitted from here: the app hands the report to your own mail client as a draft, and you decide whether to send it. Credentials are stripped before the file is written, not on the way out, so what you read in the review panel is what the file holds. Delete it whenever you like
Error log logs/error.log in the app's data directory Append-only, local, never transmitted. It exists so a bug report can carry a stack trace that you chose to paste

Environment values that flows read come from a git-ignored .env or from your own shell, never from a Bandura file. A project manifest declares variable names so a teammate knows what to fill in; it never carries values. Details in variables and environments.

Application hardening

The desktop app is locked down where an Electron app usually isn't.

Most of the well-known Electron footguns are configuration, and configuration is checkable. Here is ours, stated so you can hold the shipped binary to it.

The window cannot reach Node

Context isolation on, node integration off, renderer sandbox on. The page that draws the UI has no direct access to the file system or to any Node API; everything it can do arrives through a narrow, validated bridge.

No eval in the shipped app

The packaged build serves a Content-Security-Policy with script-src 'self' and no unsafe-eval. Features that would have been easier with a live evaluator are written not to need one, which is why the editor's expression checker scans rather than executes.

Flows execute in a separate process

A run is forked into its own child process, not the window and not the app's main process. That is fault isolation rather than an OS sandbox, and worth stating as what it is: a flow that hangs, exhausts memory, or throws takes that process down and the app reports it, instead of the app going with it.

Binary fuses are blown at package time

Four Electron fuses are flipped in the shipped artifact: the binary refuses to run as a plain Node interpreter, ignores NODE_OPTIONS, rejects the inspector flags, and encrypts its cookie store. A separate verifier checks the packaged app against the same list, so the build fails rather than shipping unhardened.

Agent file access is fenced

When an AI agent reads or writes flows, every path is resolved and checked against the open workspace before anything touches disk. An agent cannot be talked into reading ~/.ssh because the path never gets that far.

An installed build carries no developer tools

Chrome DevTools is disabled in a packaged build, application code is compiled, and no source maps are shipped. A build check reads the finished package back open and fails the release if any of that is untrue. Worth stating the limit in the same breath: this is not a secrecy boundary, since a desktop app of this kind ships JavaScript and its archive can be unpacked. Nothing about the product's security rests on the code being unreadable, which is why licence keys are verified by signature offline rather than by a check that would need hiding.

Privileged messages are schema-checked

Requests that carry arguments from the window into a file-system, database or operating-system call are validated against a schema on arrival and rejected if they do not match, rather than trusted for having come from our own window. Not every channel is covered, because most of them take no arguments at all, so we say "the ones that carry input" rather than "every message".

Distribution and supply chain

How the bytes you install are produced.

  1. built on the OS it targets

    Nothing is cross-compiled. The Windows installer comes off Windows and the Linux artifacts off Linux, in CI, because the app embeds a native module that cannot be faked from another host.

  2. published to a releases-only public repository

    Downloads are served from GitHub Releases on a repository that exists purely to host artifacts. Old versions stay up permanently, so a rollback never depends on us keeping a file around.

  3. code signing: not yet, and here is where it stands

    The current Windows and Linux builds are unsigned, which is why SmartScreen warns on first run. macOS is deliberately not published at all until it is signed and notarized, because the alternative is asking you to walk users around Gatekeeper, and teaching people to bypass an OS security control is worse than shipping later.

Current public build: v1.0.0-rc.8, on Windows and Linux, with macOS held back until it is signed. What changed in it is on the changelog, and the files themselves are on the download page, which also publishes the SHA-512 of each asset and how to check it.

This website

The site you are reading has the same posture.

  • No cookies. Not even "essential" ones. Two localStorage entries exist, both a preference rather than an identifier: your light or dark theme choice, and a note that you have already given us an email address so the download page does not ask twice. Neither leaves your browser. That is why there is no consent banner: there is nothing to consent to.
  • No third-party scripts, fonts or images. Every font, stylesheet, script, image and video is served from this origin. Google's advertising conversion tag was the one exception and was removed on 14 August 2026, along with the five Google hosts the Content-Security-Policy used to permit for it. The policy is written to what the site loads, so a new external dependency fails loudly instead of arriving unnoticed. What the site does collect is in the privacy policy.
  • Strict response headers: CSP with frame-ancestors 'none', nosniff, HSTS, a same-origin opener policy, and a Permissions-Policy that denies every capability the site has no use for, including interest-cohort tracking.
  • One form, one destination. The early-access form POSTs to this origin and nowhere else. What it collects, and for how long, is in the privacy policy.

What we do not claim

We have no SOC 2 report, no ISO 27001 certificate, no HIPAA or PCI attestation, and no third-party penetration test. Nobody has audited this code but the person who wrote it.

Those frameworks certify how an organisation handles customer data on infrastructure it runs. Bandura holds no customer data and runs no such infrastructure, so there would be nothing for an auditor to examine except this website's contact form. When the hosted tier ships and that stops being true, the answer changes and this paragraph changes with it.

What stands in its place is everything above: a short, complete list of what crosses the network, and a set of hardening choices you can hold the binary to.

For the vendor form

The answers most questionnaires want, in one place.

Copy these. If your form asks something not covered, ask us and we will add it here rather than answering once in private.

Does the vendor process, store or transmit customer data?
No. The software runs locally and we operate no service that receives customer data. The only personal data we hold is an email address, if someone chose to join the early-access list.
Sub-processors
For the website and its one form: Cloudflare (hosting) and Linear (where a signup is filed). For the product: none, because nothing reaches us. Payments, once buying opens, go through Paddle as merchant of record.
Data residency
Customer data stays on the customer's machine, so residency is wherever that machine is. There is no region to select and no copy to relocate.
Authentication, SSO and provisioning
None, because there are no accounts. A licence is a signed key, one per seat, checked offline. Removing someone's access is removing the software, the same as any other locally licensed desktop tool.
Encryption
In transit: whatever the endpoint your flow calls negotiates, plus TLS to the AI provider you configured. At rest: credentials in the OS secret store; everything else is a file protected by your own disk encryption and file permissions.
Business continuity
Flows are documented plain YAML in your repository, the runner is a published npm package you hold a copy of, and licences verify with no server. A vendor failure costs you support, not access.
Installation privileges
The Windows installer is per-user and needs no administrator rights and no elevation prompt, and it lets you choose the directory. On Linux the AppImage is a single portable file that installs nothing; the .deb is an ordinary package. Nothing installs a service, a driver, a background agent or a browser extension, and nothing runs when the app is closed.
Egress, for a firewall allowlist
For the version check and any update you ask for: GitHub's API and release download hosts. For AI features: whichever endpoint you configured, which can be a model on your own machine or your own network. Nothing else. If all outbound traffic is blocked, the app still starts, edits and runs flows against whatever your own network permits, because none of those features depends on reaching us.
Logging and audit trail
Local only. The app keeps a run history and an append-only error log on the user's own disk, listed in the storage table above, and neither is transmitted. There is no central log to request, and equally none to subpoena. If your controls require centralised audit logging of developer tools, this tool cannot supply it, which is worth knowing before the evaluation rather than after.
Offboarding and data deletion
Uninstall the application and delete its data directory. That is the whole procedure, because everything in the storage table is a file under the user's own account. There is no account to close, no data of ours to request the deletion of, and no retention period to wait out. The one exception is an email address, if someone joined the early-access list, which is deleted on request per the privacy policy.
Vulnerability disclosure
[email protected] or /.well-known/security.txt. Human acknowledgement within three working days, credit in the release notes if you want it. There is no bug bounty and no budget for one, which is said here rather than left for a researcher to discover after doing the work.
Licence terms and audit rights
The full agreement is at /eula, and it is the same file that ships inside the app. Seat counting is on trust: there is no phone-home to audit with, by design.

Questions, answered straight

FAQ

Does Bandura send our API requests, responses, or credentials anywhere?

No. Requests your flows make go to the hosts your flows name, and nothing else is copied anywhere. There is no account, no sync, no telemetry and no crash reporting, so there is no channel over which a payload could reach us even accidentally. The two requests the app makes on its own behalf are named on this page, and neither carries a request body, a credential, or an identifier.

What happens if we point the AI features at a third-party model?

Then the prompt and whatever flow context the feature needs goes to that provider, under that provider's terms, using your key. That is the one place API-shaped data can leave the machine, and it is why the local-model path exists: pointed at Ollama or LM Studio on your own hardware, nothing leaves at all. The deterministic half of the intelligence, meaning import, drift detection, self-healing and mock generation, never calls a model under any configuration.

Where are API keys and licence keys stored?

API keys go to the operating system's own encrypted store through Electron safeStorage: Keychain on macOS, DPAPI on Windows, and the Secret Service API on Linux. They are deliberately not in settings.json, which is a hand-editable plain-text file. The licence key is kept separately again, so editing settings by hand can never invalidate it.

Can Bandura keep working if your company stops existing?

Yes, and that is a design constraint rather than a promise. Licences are Ed25519 keys verified in the app against a public key compiled into the binary, so no server exists whose shutdown could disable software you paid for. Flows are documented plain YAML, and the runner is a published npm package you already hold a copy of.

Do you have SOC 2, ISO 27001, or a penetration test report?

No, none of the three, and we would rather say so than imply otherwise. Those frameworks certify how an organisation handles customer data on infrastructure it operates, and Bandura holds no customer data and operates no such infrastructure: no account, no server-side storage, no telemetry. There is nothing an auditor could scope. What a reviewer gets instead is the concrete list on this page, sourced to named files in the codebase: what leaves the machine, when, where everything is stored, and how the application is sandboxed. The full disclosure, including the fact that nobody has audited this code but the person who wrote it, is under 'What we do not claim' above.

How do we report a vulnerability?

Email [email protected] with the details, or use the contact in /.well-known/security.txt. You get a human acknowledgement within three working days. Please give us a reasonable window to ship a fix before publishing, and we will credit you in the release notes unless you would rather we did not.

Still need something

Send the questionnaire. It is read by the person who wrote the code, so the answers come back specific rather than routed, and anything worth answering once gets added to this page so the next reviewer does not have to ask.

Email [email protected]

Related: the privacy policy covers this website and the early-access list, the licence is the binding version of the network promise above, and the download page has the installers and their caveats.