Claude Code Sandboxing: What It Blocks and How to Turn It On
Claude Code’s sandbox puts an operating-system boundary around every shell command Claude runs: where it can write, and which hosts it can reach. What it blocks by default, how to switch it on, the settings that matter, and what it leaves uncovered.
7 min read
The Claude Code sandbox is an operating-system boundary around the shell commands Claude runs, and around every process those commands start. With it on, a command can write only to your working directory, directories you have added and a per-user temp directory, and it can reach only network hosts you have allowed. Turn it on with /sandbox on macOS, Linux or WSL2 (native Windows is not supported), then choose auto-allow, which runs sandboxed commands without asking, or regular permissions, which still asks. It is not a permission mode: permission rules decide whether Claude may run something, and the sandbox decides what a running command can touch. It does not cover Claude’s own file tools, MCP servers or hooks.
What the sandbox blocks by default
The boundary applies to Bash, PowerShell and Monitor commands, and Anthropic’s sandboxing documentation (opens in a new tab) says the operating system enforces it: Seatbelt on macOS, bubblewrap on Linux and WSL2. Out of the box, a sandboxed command:
- Cannot write outside the working directory, the directories you added with
--add-diror/add-dir, and the per-user temp directory that$TMPDIRpoints to. That includes shell configuration such as~/.bashrcand system binaries in/bin/. - Cannot write to protected paths even inside those directories: the
.claudesettings files and its skills, agents, commands and hooks folders,.mcp.json, shell startup files,.gitconfig,.vscode,.idea, andhooksandconfiginside.git. A command that could edit those could grant itself permissions or add a hook that runs outside the sandbox. No setting exempts one path. - Cannot reach any host that has not been allowed. No domains are pre-allowed; the first time a command needs one, Claude Code asks. “Yes” allows it for the session, and “Yes, and don’t ask again” saves a
WebFetch(domain:...)rule.
Just as important is what it allows. Sandboxed commands can read the whole machine except a few denied directories, and that still includes files such as ~/.ssh/ and ~/.aws/credentials. They also inherit your environment variables. Closing those gaps with the credentials settings is covered in security controls for AI coding agents.
How to turn it on
- On Linux or WSL2, install the two packages the sandbox needs:
bubblewrapandsocat. On macOS there is nothing to install. On Ubuntu 24.04 and later, the default AppArmor policy may also need a profile that letsbwrapcreate user namespaces; the documentation gives it. - Run
/sandboxin a session. The panel has Mode, Overrides and Config tabs. If it shows only a Dependencies tab, a required package is missing. - Choose a mode. Claude Code saves it to
.claude/settings.local.jsonfor this project. - To sandbox every project, set
sandbox.enabledtotruein~/.claude/settings.json. To try it for one session, pass it with--settings.
# Ubuntu or Debian (Fedora: sudo dnf install bubblewrap socat)
sudo apt-get install bubblewrap socat
# One sandboxed session, with no unsandboxed retries
claude --settings '{"sandbox": {"enabled": true, "allowUnsandboxedCommands": false}}'If the sandbox cannot start, because a package is missing or the platform is unsupported, Claude Code warns you and runs commands without it. Set sandbox.failIfUnavailable to true if you would rather it refused to start. On Windows, run Claude Code inside WSL2 or a container; Claude Code on Windows covers the setup.
Auto-allow or regular permissions
Both modes enforce the same boundary. They differ only in whether a sandboxed command still needs your yes.
- Auto-allow: a command that can run sandboxed runs without a prompt, even in Manual mode, where Claude’s own file edits would still ask. Deny rules still apply,
rmorrmdiraimed at a critical path still goes through the normal permission flow, and content-scoped ask rules such asBash(git push *)still prompt. In plan mode, auto-allow does not widen approvals. - Regular permissions: every command goes through the usual prompts, sandboxed or not. More control, more approvals.
Auto-allow is not auto mode. Auto mode is a permission mode in which a classifier model reviews each action; auto-allow approves shell commands because the boundary contains them. They work independently and can be combined. The permission modes themselves, and the rules that shape them, are in auto-approve in Claude Code.
Claude Code sandbox settings worth knowing
Everything lives under sandbox in a settings file. This example from the settings reference (opens in a new tab) turns the sandbox on, skips prompts for sandboxed commands, runs docker outside it, opens two extra write paths, hides the AWS credentials file and pre-allows GitHub and npm:
{
"sandbox": {
"enabled": true,
"autoAllowBashIfSandboxed": true,
"excludedCommands": ["docker *"],
"filesystem": {
"allowWrite": ["/tmp/build", "~/.kube"],
"denyRead": ["~/.aws/credentials"]
},
"network": {
"allowedDomains": ["github.com", "*.npmjs.org"]
}
}
}filesystem.allowWriteis the right answer when a tool such askubectlorterraformmust write elsewhere. It is better than excluding the tool, because the rest of the boundary still holds.filesystem.denyReadandallowReadoverlap by specificity: the narrower path wins. Deny~/and allow.in project settings to hide your home directory but keep the project readable.- Sandbox paths use ordinary conventions, so
/tmp/buildis absolute. Permission rules differ: there//is the filesystem root and/is relative to the project. excludedCommandsruns matching commands outside the sandbox entirely. Keep it short.network.strictAllowlistrefuses hosts outside the allowlist instead of asking. It works from user, managed or--settingssettings, not from a repository’s own settings.- Array settings merge across every settings file, so a developer can append to them. Boolean settings take the highest-priority value, so a managed
enabledwins.
The documentation adds a warning worth repeating: a broad domain such as github.com can itself be a path for data to leave, because the proxy decides on the hostname and does not inspect encrypted traffic by default.
The escape hatch, and strict mode
When the sandbox blocks a command, Claude sees what was denied and may retry it outside the sandbox. That retry goes through the normal permission flow, under a prompt titled “Bash command (unsandboxed)”, so in Manual mode you decide. Set allowUnsandboxedCommands to false and Claude Code ignores those retries altogether; the Overrides tab calls this strict sandbox mode. Strict mode covers commands Claude runs. Commands you type yourself after ! run outside the sandbox, except in a background session or on Linux with CLAUDE_CODE_SUBPROCESS_ENV_SCRUB set.
Sandbox vs permissions
- Permission rules (opens in a new tab) cover every tool, including Read, Edit, WebFetch and MCP, and are checked before a tool runs, against the command as written.
- The sandbox covers shell commands and their child processes only, and the operating system enforces it on the running process. It holds whatever the model chose to run, and even when an allowed command does more than its name suggests.
- Permission modes decide whether a call runs and whether you are asked. The sandbox is not one of them.
The two also feed each other: Edit allow rules grant write paths and WebFetch(domain:...) rules grant hosts, and both are merged into the sandbox’s configuration. Use rules for intent and the sandbox for the boundary.
What the sandbox does not cover
- Claude’s own Read, Edit and Write tools, which follow permission rules instead.
- MCP servers and command hooks, which run as separate processes directly on your machine.
- Computer use, which runs on your actual desktop.
- Anything you run with
--dangerously-skip-permissions. Anthropic’s guide to choosing a sandbox environment (opens in a new tab) says to run those sessions inside a container, a virtual machine or the sandbox runtime, so file tools, MCP servers and hooks are inside the boundary too.
For a boundary around the whole Claude Code process, the options run from the sandbox runtime (npx @anthropic-ai/sandbox-runtime claude, a beta research preview that uses the same Seatbelt or bubblewrap isolation), to a dev container, a virtual machine, or a cloud session hosted by Anthropic, covered in Claude Code on the web.
When something breaks inside the sandbox
dockerdoes not work in the sandbox. Adddocker *toexcludedCommands.jesthangs becausewatchmanis incompatible. Runjest --no-watchman.- On macOS, Go-based tools such as
gh,gcloudandterraformcan fail TLS verification. List them inexcludedCommands. - In an unprivileged container, bubblewrap cannot mount
/proc.enableWeakerNestedSandboxworks around it, but only use it when the container already provides the isolation. git mergeorgit checkoutfailing withunable to unlink oldmeans it needed to replace a file the sandbox protects. Run that git command yourself.
Where a task board sits
An MCP server is outside the Bash sandbox, so the sandbox is not what limits an assistant on your board. That holds for fenbs whichever way you connect: Claude Code talks to https://fenbs.ai/api/mcp itself, and the stdio bridge, npx -y fenbs-mcp, runs as its own process on your machine. The limits live on the fenbs side instead. The token Claude holds carries only the scopes you gave it (read, write, comment), it can never do more than your own role allows, revoking it in Settings stops it without signing you out, and History records every change as the assistant acting for you. Roles and permissions for humans and AI agents explains how the two layers fit.
Related
Credentials, egress and branch rules: security controls for AI coding agents. Permission modes and rules: auto-approve in Claude Code. Undoing an agent’s file edits: Claude Code checkpoints. Scopes on the board: assistant tokens and scopes.