Trust & Security
Trust, but verify
Daintree is open source and Apache 2.0 licensed. The security properties described here are enforced by architecture and Electron Fuses, not by policy. Every claim links back to the source on GitHub. For a full technical deep-dive, see the security reference.
Last reviewed , against Daintree v0.32
At a glance
| Question | Answer |
|---|---|
| Does a Daintree service see my source, prompts, diffs or terminal output? | No. There is no Daintree backend in that path. How, and the one exception coming |
| Is an account required? | No. Downloading and running the app requires no account. |
| Is telemetry on? | Off by default, opt-in, three levels. Details |
| Is the source public? | Yes, Apache 2.0. daintreehq/daintree |
| Are releases signed? | macOS: signed and notarized. Windows: not yet signed. Linux: unsigned packages. Per platform |
| Where are my API keys stored? | In a local config file readable only by your user account, not the OS keychain. Privacy policy |
| Has there been a third-party security audit? | No. None has been commissioned, and nothing on this page is a substitute for one. |
| How do I report a vulnerability? | security@daintree.org. Process |
There is no Daintree server
Daintree runs on your machine. There is no relay, no hosted control plane and no account to create in order to use the app, so your source, your diffs, your terminal output and your agent traffic have no Daintree backend to be sent to. The app does reach the network for two narrow things it tells you about: checking for updates, and fetching the plugin blocklist.
Running agents on a machine other than the one in front of you does not change that. Daintree never proxies remote work through infrastructure we operate. Remote compute is a per-worktree lifecycle hook: the environment is a Docker stack, a cloud VM or a sandbox that you describe in .daintree/config.json, and Daintree runs the commands you wrote against the hardware you chose.
Agents run locally in your terminal, and any context they send to a provider API is between you and that CLI. Daintree reads your files locally where you ask it to, in the file viewer and in Review Hub, and it never uploads or transmits them. No Daintree backend receives your files, prompts or agent output.
The Daintree Assistant service
The Daintree Assistant is a purpose-built CLI that will be able to back the in-app Assistant panel, and it is the only component we build that puts a service we operate in the path of your work. Its model traffic runs from the CLI to a Daintree-operated backend, which owns the system prompt and selects the model, and on to OpenRouter using your own API key. That backend sees the conversation, a project snapshot, your DAINTREE.md, and the output of any tool it ran on your behalf.
It is in private testing and is not shipping today, so nothing on this page is currently qualified by it. Backing the Assistant panel with a coding CLI you already have, which is how it works now, adds no endpoint and is covered by everything above. When the purpose-built engine ships it will carry its own data policy, this page will say so in the present tense, and choosing it will stay a choice.
Renderer sandboxing
All Electron renderer processes run with contextIsolation: true, nodeIntegration: false, and sandbox: true. These values are hardcoded in the source, not user-configurable. Every embedded webview enforces the same flags.
Communication between the UI and the main process passes through a contextBridge preload. IPC messages are validated by sender origin and checked against Zod schemas before any handler runs.
Navigation lockdown
The main renderer window is locked to the app://daintree protocol (and the localhost dev server in development). All other navigations are blocked via will-navigate and will-redirect. window.open is denied for all origins. shell.openExternal only permits http:, https:, and mailto: schemes. The Portal browser panel allows full http:/https: navigation by design, but runs in a sandboxed webview with the same isolation flags.
Electron Fuses
Electron Fuses are compile-time binary flags that permanently disable attack surfaces. They cannot be overridden at runtime, which means even if an attacker gains code execution, these protections hold.
runAsNode false Prevents the binary from being abused as a generic Node.js runtime via ELECTRON_RUN_AS_NODEenableCookieEncryption true Encrypts cookies using OS-level credential storageenableNodeOptionsEnvironmentVariable false Blocks NODE_OPTIONS injection from the environmentenableNodeCliInspectArguments false Blocks --inspect from the command lineenableEmbeddedAsarIntegrityValidation true Detects tampered ASAR bundles before loading themonlyLoadAppFromAsar true Prevents loading the app from unpacked filesystem pathsgrantFileProtocolExtraPrivileges false Removes special privileges from the file:// protocolloadBrowserProcessSpecificV8Snapshot false Disables loading a separate V8 snapshot for the browser processCode signing & notarization
macOS binaries are built with hardenedRuntime: true and forceCodeSigning: true, then notarized with Apple. Hardened runtime entitlements are limited to exactly what Daintree needs:
- JIT (required by the V8 JavaScript engine)
- Unsigned executable memory (required by node-pty native modules)
- Disable library validation (required by the Electron framework)
- Microphone (voice input only)
- Camera: explicitly false
SHA-512 checksums for all release binaries are published on the GitHub releases page.
The other two platforms are not at parity, and saying so is more useful than implying they are:
- Windows. The installer is not code signed. SmartScreen will warn on first run, and you should verify the published checksum before installing. A signing certificate is being arranged.
- Linux. Packages are unsigned; verify the published checksum. Distribution coverage is narrower than macOS.
Telemetry: off by default
Telemetry defaults to disabled (enabled: false hardcoded in the store). Daintree supports three levels: off, errors-only (scrubbed error events via Sentry), and full (adds a small set of anonymous usage analytics). No diagnostic or usage event is sent at the default setting. The two network calls Daintree makes regardless are the update check and the plugin blocklist fetch described above; agent CLIs you launch continue to talk to their own providers on their own terms.
Before any event is sent to Sentry, a beforeSend hook strips your home directory path from all stack traces and breadcrumbs. Your local filesystem paths never appear in crash reports. The pre-consent event buffer caps at 100 events and is never flushed without consent.
API keys you give to an agent CLI are passed straight to that CLI. Keys you give to Daintree itself, for the optional voice and MCP features, are stored locally and sent only to the provider they belong to. Neither passes through a Daintree service, because there is not one. The Daintree Assistant is the exception on the horizon, and it holds your key request-scoped rather than storing it.
Local MCP server
The MCP server is opt-in and disabled by default. When enabled, it binds to 127.0.0.1 (localhost only, not 0.0.0.0), so it is not reachable from the network or other machines. The default port is 45454.
If no API key is configured, any local process can connect to the MCP server. Set an API key in Settings → MCP Server to require Bearer token authentication.
Host header validation is enforced: only requests with 127.0.0.1:{port} or localhost:{port} in the Host header are accepted. The discovery file is written to ~/.daintree/mcp.json.
IPC rate limiting
Daintree applies per-category rate limiting to IPC handlers to prevent runaway or malicious usage patterns from the renderer process. Three categories are enforced:
fileOps(CopyTree operations)gitOps(worktree and git operations)terminalSpawn(terminal process creation)
Each category enforces a maximum queue depth of 50.
What this does not guarantee
Every mechanism above prevents something specific. None of them makes arbitrary code harmless, and it is worth being exact about where each one stops.
- A worktree is Git isolation, not process isolation. Each task gets its own branch and checkout, so agents do not overwrite each other's work. The agent process still runs as your user and can read and write anything your user can.
- An agent CLI keeps its own capabilities. Daintree launches the real binary you already have. Whatever that tool can do, and whatever it sends to its provider, is governed by that tool, not by Daintree.
- Plugins execute code. A manifest declares intent; it does not confine behavior. Install plugins from sources you would trust with a shell script.
- Electron Fuses close packaging and runtime paths. They stop the packaged app being re-used as a generic Node runtime and detect tampering with the archive. They do not contain code that is already running.
- Local-first reduces server-side exposure, not local exposure. Nothing on this page protects a machine that is already compromised.
- Public source is not an audit. Anyone can read the code. Nobody independent has been paid to.
- A capability tier bounds the Daintree tool surface, not the model process. It governs what the Assistant can call through Daintree. The CLI backing it is still a process on your machine with whatever else that binary can reach.
- The local audit log records Daintree tool calls. It is a complete record of what the Assistant asked Daintree to do, and not a record of everything the underlying CLI did outside that surface.
Report a vulnerability
Email security@daintree.org, or open a private advisory through GitHub Security Advisories. Please do not open a public issue for a security report.
Include the affected version, the platform, and enough detail to reproduce the issue. Expect an acknowledgement within three working days. Fixes ship in the next release; if a report warrants it, one goes out sooner and is called out in the changelog.
The most recent release is the supported version. There is no long-term-support branch, and older releases do not receive backported fixes.
The machine-readable version of this is at /.well-known/security.txt.
Open source
Don't take our word for it
Daintree is fully open source. Clone the repo and point one of your own agents at it. The prompt below is a starting point for a source review, not a security audit: an automated read can surface things worth checking, and it cannot certify that an application is safe to run.
Clone the repository
git clone https://github.com/daintreehq/daintree.git && cd daintree Open your agent
claude gemini codex opencode Ask it to audit the code
Paste this prompt into the agent. It asks for cited findings separated into what the model verified and what it only suspects, and no install verdict.
Review the source of this Electron application and tell me what a human reviewer should look at. Cover: hardcoded secrets or credentials; any network call that sends user data off the machine, and whether it is opt-in; Electron configuration including nodeIntegration, contextIsolation, and the Fuses (runAsNode, ASAR integrity validation, cookie encryption, nodeOptionsEnvironmentVariable); IPC handler surface and whether rate limiting is enforced for the fileOps, gitOps and terminalSpawn categories; the local MCP server on port 45454 and the discovery file at ~/.daintree/mcp.json; uses of shell.openExternal; paths that could lead to remote code execution; and the breadth of filesystem access. For every finding, cite the file and line, and label it as VERIFIED (you read the code that proves it) or HYPOTHESIS (it looks plausible but you did not confirm it). Rank findings by severity and list the areas you could not assess. Do not give a verdict on whether the application is safe to install; that is not something a source read can establish.