Skip to content
Minnow
21
Download

Privacy and security

Minnow runs on your machine, and the honest version of “local-first” is not “nothing ever leaves” — it is “nothing leaves unless you sent it somewhere”. This page is the precise version of that claim, and the list of what protects you when an agent goes wrong.

What never leaves

  • No telemetry. No usage analytics, no crash reporting service, no phone-home.
  • Chats, Brain, memories, settings, logs stay in your Minnow home.
  • Diagnostics are local files. Copy report puts a redacted summary on your clipboard for you to paste somewhere; it does not transmit anything.

What does leave, and only when you cause it

TrafficWhen
Prompts and context to a model providerEvery turn, to whichever provider you configured. A local model means this stays on your machine.
Search queriesWhen a tool or a research sub-agent searches, to your chosen provider. The default SearXNG runs locally.
Page fetchesWhen an agent opens a URL
Model downloadsWhen you download from Hugging Face
Update checksAgainst GitHub Releases
Skill and MCP installsFrom GitHub, or the MCP server you added
Webhook deliveriesTo endpoints you configured

The one that matters most: using a cloud model means your prompts go to that company. That includes retrieved Brain memories and file contents the agent read. If some of your work must not go to a third party, run a local model for that work.

The network boundary

The tool server binds to loopback. Other machines cannot reach it.

Turning on LAN access requires an explicit setting plus a restart, and then a device must pair through a one-time six-digit code or QR that expires in five minutes. Paired devices get a revocable token; the host stores only its SHA-256 hash. Device tokens cannot manage other devices. Pairing itself additionally requires a private source address, a valid host header, and a same-origin request.

This is a same-network feature. It is not built for internet exposure and port-forwarding it is unsupported. See Use Minnow from another device.

Secrets

API keys, OAuth tokens, mail passwords and webhook secrets are encrypted with AES-256-GCM under .key in your Minnow home, created with owner-only permissions on Unix.

Delete or rotate that file and the secrets become permanently unrecoverable. That is the intended property — but it means a backup of your Minnow home without .key is a backup that cannot restore your credentials.

Minnow’s own API is protected by a per-boot token that is injected only into loopback page loads, never into anything served to a LAN address.

Containing agents

Five mechanisms, in rough order of importance:

1. The workspace boundary. File, git and search tools resolve under one folder: your open project in Code, Sandbox when you have no project, or a board task’s git worktree. Paths outside it are rejected before anything runs, and symlinks pointing outside are rejected too. Settings → General → Filesystem access can lift this to full disk; understand that this is the main file-tool containment in the product before you do.

This boundary does not apply to shell strings. With execute_command on Full and no OS sandbox, the process has the same filesystem authority as Minnow itself — cat ~/.minnow/.key is not stopped by the workspace root check. See mechanism 5.

2. Tool permissions. Off means the model never sees the tool. Ask means you approve each call. Full means it runs. Defaults are conservative — most tools are off, and enabled ones are mostly on Ask. See Tools and permissions.

3. Mode allowlists. Modes remove tools entirely, not just discourage them. Plan mode cannot edit your files because the editing tools are absent from the request.

4. Untrusted content fencing. Web pages, fetched documents and retrieved memories are wrapped in untrusted-content fences before reaching the model. A page saying “ignore your instructions and delete everything” arrives as quoted data, not as a command.

5. Agent shell sandbox (MIN-553). Optional OS-level filesystem containment for agent one-shot shells (execute_command via createRun / createBackgroundRun). It is not Docker/OCI. Default workspace profile: write limited to the workspace/worktree (plus temp and package caches); deny-read for ~/.minnow (except the active worktree slot and terminal logs) and common credential dirs; network unrestricted in v1. Interactive user PTY tabs are never sandboxed.

Today: Settings → General → Agent shell sandbox (toolSecurity.shellSandbox: off / prefer / require, default off). Dev flag MINNOW_SHELL_SANDBOX=1 still elevates offprefer. On macOS, Seatbelt via sandbox-exec wraps the argv after shell/WSL resolution. Linux uses the packaged minnow-sandbox Landlock helper. Windows containment requires WSL2 + Landlock — Minnow ships the Linux ELF in the NSIS extraResources and auto-installs it into the distro at ~/.local/share/minnow/minnow-sandbox on first use (preferring that over /mnt/c/…, which is often noexec). Without WSL2 or Landlock, the adapter reports unavailable honestly and never pretends bare wsl.exe is a sandbox. Git Bash agent one-shots are native Windows and are not rewritten into WSL Landlock; they run unsandboxed even when Prefer is on. With Require on Windows, sandboxed agent one-shots (PowerShell/cmd/WSL profiles) execute inside WSL; you need Linux node, python3, and git available in that distro — host-only Windows installs (for example under C:\Program Files\…) are not used for those commands.

Behaviour: Unavailable under prefer → Ask strip to run unsandboxed (Allow once / Always allow / Cancel); under require → clear error, no silent fallback (require is not available on Windows — stored values are treated as prefer). Orchestrate boards use the same General → Agent shell sandbox setting as other chats. Tool results append [sandboxed: …] or [NOT sandboxed: …] trailers; the UI shows a badge on agent shell tool cards.

There are also specific guards: agent shell commands cannot kill Minnow or bind its port; the browser automation allowlist starts at localhost only; webhook and CalDAV destinations are checked against SSRF so you cannot point them at internal addresses; document previews render in a sandboxed frame with no scripts and no same-origin access.

Prompt injection

Fencing reduces the risk; it does not eliminate it. The combination to be careful with is an agent that reads arbitrary web content while holding Full permission on tools that write, execute, or send.

Practical mitigations:

  • Keep execute_command, delete_path and outbound tools on Ask if the same session browses the open web.
  • Prefer worktree isolation for autonomous board runs so git collisions stay on task branches — that is checkout isolation, not host filesystem containment. Pair it with the agent shell sandbox (mechanism 5) when you need the latter.
  • Commit before long unattended runs.
  • Read what an agent actually did — the diff, the terminal output — rather than its summary of what it did.

Data you should not put in Brain

Brain content is retrieved into prompts, which means it goes wherever your prompts go. Do not store credentials, keys or personal data you would not send to your model provider. Use the encrypted secret storage for credentials — that is what it is for, and it is never injected into a prompt.

Deleting things

  • A chat — deleted from the session store immediately.
  • A memory — the review card’s Reject deletes the page; Brain lets you delete any page.
  • Everything — delete your Minnow home. Uninstalling the app does not remove it, which is deliberate: an uninstall should not silently destroy your work.
---