Security & Sandboxing
A coding agent is a process that runs arbitrary shell commands. It edits files, installs packages, and executes whatever its plan calls for — and one wrong tool call (or one poisoned instruction in a file it read) can write anywhere your user account can write: your repo’s history, another agent’s half-finished work, your dotfiles. Running one agent unsandboxed is a calculated risk. Running ten at once is not a risk you can watch closely enough to take.
Fletch’s answer is structural: every agent runs inside a sandbox, in its own checkout, from the moment it spawns. You never opt in to isolation — you’d have to work to get out of it.
Two sandbox engines
Section titled “Two sandbox engines”Fletch has two interchangeable sandbox engines, chosen under Settings › General › Sandbox. The engine applies to newly created agents; an existing agent keeps the engine it started with for its whole life, so flipping the setting never changes a running agent.
Seatbelt (sandbox-exec) — the default
Section titled “Seatbelt (sandbox-exec) — the default”Each agent process runs as your user under a per-agent macOS sandbox-exec profile that
denies file writes by default and re-allows only what that agent legitimately needs:
- its own workspace at
~/.fletch/workspaces/<id>/and its RPC mailbox - temp directories and the PTY/device files terminal programs need
- the agent CLI’s own config and cache directories (so it can keep its login and state)
Deliberately not granted: executable directories on your PATH (a write there would let
an agent plant a binary you’d run later), and Fletch’s own app database — the agent can’t
even read your other agents’ transcripts. Everything else on disk is readable but not
writable.
Seatbelt is native to macOS: no install, no daemon, no image to build, and effectively no performance overhead — the agent runs directly on your machine with your toolchains already available.
Its limit is what it is: a write-protection boundary, not a VM. A Seatbelt agent can read anything your user can read and can reach the network. It can’t trash your repo or your machine, but it isn’t air-gapped.
Docker — opt-in, full container isolation
Section titled “Docker — opt-in, full container isolation”With the Docker engine, each agent runs in its own Linux container (docker run --rm --init, one container per agent). The container sees only what’s mounted into it: the
agent’s writable workspace, its RPC mailbox, and a read-only view of the borrowed git
object store. Your wider filesystem simply isn’t there — the reading-and-network caveat
of Seatbelt narrows to the mounts you can enumerate.
The trade-offs are the ones containers always have:
- Setup. Docker Desktop must be installed and running; Fletch probes the daemon and disables the option (with a one-click Start Docker Desktop) when it’s down. The first agent launch builds the agent image, with progress shown in a toast.
- Linux, not macOS. Builds and tests run on Linux inside the container. That’s a feature if you ship to Linux, a surprise if your project needs Xcode.
- Resources. Containers default to 4 GB memory and 2 CPUs; both, and the image itself, can be changed under Settings › Experimental.
- Provider coverage. Claude Code, Codex, OpenCode, Pi, and Cursor Agent run in
containers. Antigravity stays on Seatbelt (its CLI has no non-interactive login, so a
fresh container can’t authenticate). Claude in a container also needs credentials the
container can reach — see the Connect Claude for containers flow in
Settings › General › Sandbox, which automates
claude setup-token.
One honesty note: in this version, containers run as root and are a live-process containment measure, not a hardened trust boundary. The isolated clone and the review-before-merge flow remain the real gate on what lands in your repo.
Which one should you use?
Section titled “Which one should you use?”Start with Seatbelt. It’s zero-setup, fast, and its write-deny profile already makes the fleet safe against the failure that actually happens — an agent writing where it shouldn’t. Switch an agent to Docker when you want a hard boundary around what it can read as well as write, when the task involves running untrusted or unfamiliar code, or when you want builds and tests to run on Linux. Because the engine is stamped per agent, you can mix: everyday agents on Seatbelt, one Docker agent for the sketchy dependency upgrade.
Workspaces are clones with their own .git
Section titled “Workspaces are clones with their own .git”Isolation only holds if the sandbox has nothing sensitive inside it — and a git checkout
usually smuggles in the most sensitive thing of all: your repository’s .git directory.
A linked git worktree (the common approach to parallel checkouts) has a .git file
that points back inside your real repo’s .git. Give an agent a worktree and you must
give it write access there — and a writable .git/hooks means arbitrary code execution
on your machine the next time you run git.
Fletch provisions each workspace as a git clone --shared instead. The clone has its
own real, writable .git, entirely inside the sandboxed workspace, so your repo’s
.git is never writable by an agent — no hook-planting, no config rewriting, no
history surgery on the original. The clone borrows your repo’s object store through
git’s alternates mechanism rather than copying it, so spawning an agent costs kilobytes
and milliseconds regardless of history size. New objects the agent creates land in its
own .git; your repo stays byte-for-byte untouched — no worktree entries, no “branch
already checked out elsewhere” errors — and discarding an agent is just deleting a
directory.
Each checkout starts detached at a pinned fork-point commit taken from the freshest state of your base branch, so an agent’s diff is always measured against exactly where it started. The one constraint of borrowing objects is that the workspace depends on the source repo staying in place, which Fletch manages for you.
Credentials never enter the sandbox
Section titled “Credentials never enter the sandbox”Pushing and opening pull requests need your GitHub credentials, and those must not live where an agent can read them. So agents don’t hold credentials at all: when an agent needs a remote action, it asks the host through a broker that accepts only a small, fixed set of operations — push, PR creation, and a credentialed fetch — which run host-side with your token. An agent can therefore publish code and open PRs under your identity (choose tasks and repos accordingly), but it can never exfiltrate the token itself, because it never has it.