Skip to main content

Trust & Security

Trust, but verify

Canopy is open source and MIT 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.

Your code never leaves your machine

Canopy is a local desktop app. It never reads, uploads, or transmits your source code anywhere. Agents run locally in your terminal, and any context they send to a provider API is between you and that CLI, not routed through Canopy.

No Canopy backend receives your files, prompts, or agent output.

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://canopy 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_NODE
enableCookieEncryption true Encrypts cookies using OS-level credential storage
enableNodeOptionsEnvironmentVariable false Blocks NODE_OPTIONS injection from the environment
enableNodeCliInspectArguments false Blocks --inspect from the command line
enableEmbeddedAsarIntegrityValidation true Detects tampered ASAR bundles before loading them
onlyLoadAppFromAsar true Prevents loading the app from unpacked filesystem paths
grantFileProtocolExtraPrivileges false Removes special privileges from the file:// protocol
loadBrowserProcessSpecificV8Snapshot false Disables loading a separate V8 snapshot for the browser process

Code signing & notarization

macOS binaries are built with hardenedRuntime: true and forceCodeSigning: true, then notarized with Apple. Hardened runtime entitlements are limited to exactly what Canopy 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.

Telemetry: off by default

Telemetry defaults to disabled (enabled: false hardcoded in the store). Canopy supports three levels: off, errors-only (crash reports via Sentry at 10% sample rate), and full (usage analytics). Nothing leaves your machine without your explicit opt-in.

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 are passed directly to the CLI tools you run. They are never sent to or stored by any Canopy server.

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 ~/.canopy/mcp.json.

IPC rate limiting

Canopy 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.

Open source

Don't take our word for it

Canopy is fully open source. Clone the repo and ask your favourite AI agent to audit it. The same tools Canopy runs can verify its safety.

01

Clone the repository

git clone https://github.com/canopyide/canopy.git && cd canopy
02

Open your agent

Claude Code claude
Gemini CLI gemini
Codex CLI codex
OpenCode opencode
03

Ask it to audit the code

Paste this prompt into the agent. It'll read the source and give you an independent security assessment.

Perform a security audit of this Electron application. Check for: hardcoded secrets or credentials; data exfiltration or telemetry that sends user data to external servers without consent; insecure Electron configuration including nodeIntegration, disabled contextIsolation, or Electron Fuses (verify runAsNode=false, ASAR integrity validation enabled, cookie encryption enabled, nodeOptionsEnvironmentVariable disabled); IPC handler vulnerabilities and whether rate limiting is enforced for fileOps, gitOps, and terminalSpawn categories; the local MCP server exposed at localhost:45454 and the discovery file at ~/.canopy/mcp.json (assess the attack surface and whether connections are properly scoped); unsafe use of shell.openExternal; remote code execution risks; overly broad file system access; any behavior that could compromise user privacy or security. Summarize your findings with severity levels and provide a final recommendation on whether this application is safe to install and run on my machine.