Claude Code Sandbox Mode: Exact Config and What It Blocks
Originally published at Unattended . Claude Code sandbox mode is a built-in, OS-enforced boundary around the Bash commands Claude runs. You turn it on with /sandbox or "sandbox": {"enabled": true} in settings.json. Anthropic's docs describe it as "a boundary that the operating system enforces aroun

Posted on Oct 28 • Originally published at en.aobaworks.com
Claude Code sandbox mode is a built-in, OS-enforced boundary around the Bash commands Claude runs. You turn it on with /sandbox or "sandbox": {"enabled": true} in settings.json. Anthropic's docs describe it as "a boundary that the operating system enforces around the shell commands Claude runs on your machine". It limits where those commands can write and which hosts they can reach. It does not cover Claude's own file tools, hooks or MCP servers. That gap matters most if you plan to leave an agent running unattended.
On macOS, Linux or WSL2, turn on the built-in sandbox in auto-allow mode. Use a container or VM only if you need stronger isolation than that.
Why these picks: on macOS the sandbox needs no setup. On Linux the most common failure is missing dependencies, and failIfUnavailable makes that failure loud. Windows needs WSL2 before any sandbox setting does anything.
Claude Code sandbox mode wraps every Bash command Claude runs in an OS-level jail that controls filesystem writes and outbound network access. The point is to let Claude run commands without asking you each time, while capping the damage a bad command can do.
It's built on standard OS tools. On macOS it uses the built-in Seatbelt framework. On Linux and WSL2 it needs the bubblewrap and socat packages ( Claude Code docs ). Anthropic published the sandbox runtime as open source in the @anthropic-ai/sandbox-runtime package ( GitHub ).
When Anthropic introduced it on October 20, 2025, the engineering team wrote: "In our internal usage, we've found that sandboxing safely reduces permission prompts by 84%." That number comes from Anthropic's own internal use. It is not a benchmark.
Here is what the sandbox allows by default ( docs ):
Pitfall: many people assume a sandbox means "can't see my secrets." By default the sandbox restricts writes, not reads. If you want credential files hidden, you must deny them explicitly (see the config section below).
Yes. Claude Code has a built-in sandbox that you enable with the /sandbox command or the sandbox.enabled key in settings.json. It works on macOS, Linux and WSL2, but not on native Windows.
There are three official ways to turn it on ( docs ):
Some third-party guides mention a claude --sandbox startup flag. The official sandboxing page lists no such flag, so use --settings for one-off runs and scripts.
Once it's on, you choose one of two modes. In auto-allow mode, "Claude Code approves a command automatically, with no prompt, when the command runs inside the sandbox". In regular permissions mode, every Bash command still goes through the normal approval flow, but it runs inside the boundary. The filesystem and network limits are the same in both modes. The only difference is whether you get prompted.
Claude Code auto mode decides whether an action needs your approval. Sandbox mode limits what a command can reach once it runs. They solve different problems, and you can use them together.
The permission modes page puts it this way: "the Bash sandbox and outer isolation boundaries decide what an action can reach once it runs." Permission modes only decide whether Claude asks first.
A common mix-up is treating auto mode and "YOLO mode" as the same thing. They aren't. Auto mode sends actions to a separate classifier model, Claude Sonnet 5 by default, which blocks things like curl | bash, force pushes and terraform destroy. YOLO is bypassPermissions (alias --dangerously-skip-permissions ), which approves everything ( permission modes docs ).
The docs say plainly: "Auto mode reduces permission prompts but does not guarantee safety." Auto mode also pauses and goes back to prompting after 3 blocks in a row or 20 blocks in total in a session ( same page ). For unattended runs, that means a "stuck" job can actually be a job waiting at a prompt. See why Claude Code stops mid-automation.
How they combine. With auto mode and the sandbox both on, sandboxed Bash commands run inside the boundary. If a command fails because of the sandbox and Claude retries it with dangerouslyDisableSandbox, the classifier reviews the retry. In bypassPermissions mode, that unsandboxed retry runs with no prompt at all ( sandboxing docs ). So if you combine YOLO with the sandbox, also set allowUnsandboxedCommands: false. Otherwise the sandbox has an exit you never see.
Which to choose: for daily interactive work, use the sandbox in auto-allow mode plus auto mode. For unattended jobs, use the sandbox in strict mode plus explicit permission rules. Don't rely on a classifier in a job nobody is watching.
Type /sandbox in a session and choose auto-allow mode. For a persistent setup, enable sandbox in settings.json, then check that a forbidden command fails.
If either command succeeds, the sandbox isn't active. Check /sandbox → Config.
This example combines keys from the official sandboxing page. The domain names and paths are sample values to replace with your own:
{ "sandbox": { "enabled": true, "autoAllowBashIfSandboxed": true, "allowUnsandboxedCommands": false, "failIfUnavailable": true, "filesystem": { "allowWrite": [ "/tmp/build" ], "denyRead": [ "~/private" ] }, "network": { "allowedDomains": [ "github.com", "*.npmjs.org" ], "strictAllowlist": true }, "credentials": { "files": [ { "path": "~/.aws/credentials", "mode": "deny" }, { "path": "~/.ssh", "mode": "deny" } ], "envVars": [ { "name": "GITHUB_TOKEN", "mode": "deny" } ] } } } Enter fullscreen mode Exit fullscreen mode What each piece does:
Settings precedence, from highest to lowest, is: CLI --settings, managed, user ( ~/.claude/settings.json ), project (.claude/settings.json ), local project. Filesystem arrays from different scopes are merged, not replaced ( docs ). For cron and claude -p runs, keep the sandbox block in user settings or pass it with --settings. The headless guide covers the rest of the flags: /claude-code-headless-mode-flags-auth-and-cost-2026/.
Not natively. On native Windows, Claude Code runs commands unsandboxed, so you need to run Claude Code inside WSL2 to get the sandbox.
The docs say it directly: "Claude Code runs commands unsandboxed. To use the sandbox on a Windows machine, run Claude Code inside a WSL2 distribution". Inside WSL2 the setup is the same as on Linux: install bubblewrap and socat, and apply the AppArmor fix if your distro is Ubuntu 24.04 or newer.
There's one WSL2-specific catch. Setting network.allowAllUnixSockets: true opens every Unix socket to sandboxed commands. On WSL2 that includes the socket WSL uses to launch Windows binaries, so a sandboxed command could start a Windows program outside the boundary ( docs ). Leave that setting off unless you know which socket you need.
Pitfall: turning on sandbox.enabled in native Windows PowerShell gives no error and no protection. Add failIfUnavailable: true so a misconfigured machine fails loudly instead of quietly running everything unsandboxed.
Claude Code sandbox mode blocks Bash writes outside allowed paths and network traffic to hosts not on the allowlist. Built-in tools, hooks, MCP servers, excluded commands and default reads all fall outside it.
This is the part most guides skip. The docs list everything the sandbox does not wrap: built-in tools like Read, Edit, Write, WebFetch and WebSearch "follow permission rules instead," and "a denyRead entry doesn't stop the Read tool, and allowedDomains doesn't limit WebFetch" ( sandboxing docs ). Command hooks, local MCP servers, plugin monitors, LSP servers, your status line command and apiKeyHelper all "run with your full access."
Excluded commands are fully outside. "An excluded command runs with your full access." A broad pattern like docker * hands Claude everything Docker can do, and that includes mounting your home directory into a container. Write the narrowest pattern that works, such as docker compose up * rather than docker *.
The proxy only checks the hostname. By default the proxy "does not terminate or inspect TLS traffic" ( docs ). If you allow github.com, a command can push anything to any repo on github.com. The experimental network.tlsTerminate setting lets the proxy inspect traffic, and credential masking depends on it.
Some settings weaken the boundary. allowNestedUserNamespaces (Linux/WSL2) lets code end up outside the sandbox. allowAppleEvents (macOS) lets commands launch other apps unsandboxed. enableWeakerNestedSandbox exposes process information. Only turn these on for a specific tool that needs them.
What it does protect well. Writes to protected paths are denied even inside your project. That covers.claude settings,.mcp.json,.gitconfig,.bashrc,.zshrc,.vscode,.idea, and Git internals like HEAD, refs and.git/hooks. If a symlink appears at a protected settings file's path mid-session, writes to its target are denied too ( docs ). So a prompt-injected command can't quietly rewrite your settings or plant a Git hook.
Example of a full closure (sample values): to keep a nightly job from reading your AWS keys through any route, you need two things. A sandbox credentials.files entry with "mode": "deny" stops Bash. A permission deny rule for the Read tool on that path stops the Read tool. You can copy deny-rule templates from /ai-agent-guardrails-example-copy-paste-claude-code-rules/.
Claude Code hooks are scripts that run at lifecycle events like PreToolUse. They can block tool calls the sandbox ignores, but they run outside the sandbox themselves.
Hooks are defined in settings files ( ~/.claude/settings.json,.claude/settings.json,.claude/settings.local.json or managed policy). The hooks reference lists events such as SessionStart, UserPromptSubmit, PreToolUse, PostToolUse, PostToolUseFailure and Stop. PreToolUse runs "before a tool call executes" and can block it. You block either by exiting with code 2 or by returning permissionDecision: "deny" with a reason.
That makes hooks the right tool for the gaps in the table above. The sandbox can't stop the Edit tool from touching migrations/, but a PreToolUse hook matched to Edit|Write can. It can also add dynamic logic that static config can't express, such as "deny pushes after 6 p.m." or "deny writes when the test suite is red."
The tradeoff: command hooks "run with your full access" ( sandboxing docs ). A hook that downloads something or calls an API isn't held back by your allowedDomains. Keep hook scripts short, review them like production code, and store them where the sandbox denies writes..claude/ is a protected path, so Claude can't rewrite hooks you keep there. For ready-made scripts, see /claude-code-hooks-examples-7-copy-paste-scripts/.
You check Claude Code usage with the /usage command in a session. Authoritative billing lives in the Claude Console for API users and on claude.ai for subscribers.
Sandboxing makes Claude do more without stopping, which can also mean more tokens. So check usage after you turn on auto-allow. Your options, per the Claude Code costs docs:
For scale, Anthropic reports that across enterprise deployments, the average cost is "around $13 per developer per active day" and $150–250 per developer per month (as of October 2026; costs docs ). Background features use a small amount even when idle, typically under $0.04 per session. More detail is in /claude-code-how-to-see-token-usage-and-reduce-it/.
Start with the three DIY steps below. All of them work on any plan.
If you'd rather not build this yourself: Claude Code is included with Anthropic's Pro plan at $20/month and Max from $100/month (as of October 2026; check the official pricing page ). Paying doesn't configure the sandbox for you; it buys more usage. Team plans ($25/seat monthly for Standard, per the official pricing page ) add central administration, so an admin can enforce the sandbox for everyone through managed settings with failIfUnavailable: true ( sandboxing docs ).
That suits a small team where one person owns security. It's overkill for a solo builder, who gets the same sandbox for free in user settings. If you need isolation that also covers the Read and Edit tools, a dev container or VM is the official recommendation for bypassPermissions.
The cost of that is extra setup and upkeep.
Community threads mostly cover practical friction, such as Docker, SSH git remotes and database clients failing inside the sandbox. All of these are documented with fixes on the official sandboxing page. The usual fix is a narrow excludedCommands entry or switching git to HTTPS. Check any forum advice against the docs, because settings like allowNestedUserNamespaces quietly weaken the boundary.
Yes. They work independently and combine. The sandbox limits what Bash can reach, and auto mode's classifier reviews other actions, including unsandboxed retries ( permission modes docs ). Auto mode requires a supported model, such as Opus 4.6+ or Sonnet 4.6+ on the Anthropic API.
Only partly. --dangerously-skip-permissions still lets the Edit, Write and Read tools act outside the sandbox. It also auto-approves unsandboxed retries unless you set allowUnsandboxedCommands: false. Anthropic says to use bypass mode only in containers or VMs, ideally without internet access ( docs ).
The official sandboxing page lists no dedicated flag. For one run, pass claude --settings '{"sandbox": {"enabled": true}}'. For every run, put the sandbox block in ~/.claude/settings.json ( docs ).
Run /usage in the session for an estimated cost and token breakdown. Use the Console usage page for authoritative API billing. Subscribers see plan usage bars on the same /usage screen ( costs docs ).
This article was created with the help of AI. Sources are linked inline; check the official documentation for the latest details.