Claude Code sandbox: what it stops, what it doesn't, and when to use a container

Last updated: November 12, 2026
TL;DR
The Claude Code sandbox is an operating-system boundary around the shell commands Claude runs. It limits which files those commands can write and which network hosts they can reach, so Claude Code can run them without asking you each time. It's off by default, and it covers shell commands only: Claude's file tools, MCP servers and hooks run outside it.
- ๐งฑ Turn it on. Run
/sandbox, pick auto-allow or regular permissions, and Claude Code saves the choice for that project. - ๐งช Prove it. Ask Claude to run
touch ~/sandbox-probe. Inside the sandbox it fails. - ๐ Open only what the build needs. Allowed domains start empty. Add hosts to
allowedDomainsand paths toallowWrite. - ๐ Hide your secrets. By default, sandboxed commands can read
~/.sshand~/.aws/credentials. Acredentialsblock blocks them. - ๐ช Close the escape hatch. Set
allowUnsandboxedCommandstofalse, so Claude can't retry a blocked command outside the sandbox. - ๐ฆ Use a container for unattended runs. Anthropic's docs say the Bash sandbox alone isn't enough for a session that runs without prompts.
Facts here come from Anthropic's sandboxing guide and sandbox environments page, read on November 10, 2026, when Claude Code was at 2.1.322.
Before you start
Four things decide how these steps go:
- Your platform. The sandbox runs on macOS, Linux and WSL2. On native Windows, Claude Code runs commands unsandboxed, so run it inside WSL2 if you want the sandbox there.
- Two packages on Linux and WSL2. The sandbox needs
bubblewrapandsocat. On Ubuntu or Debian, runsudo apt-get install bubblewrap socat. macOS uses its built-in Seatbelt framework and needs nothing extra. - A restart after installing. Claude Code checks for the packages at startup, so restart it before you run
/sandbox. - A settings file you can edit. The steps below write to
.claude/settings.jsonin your project. Shared keys there apply to everyone who opens the repository.
Step 1: Turn the sandbox on
Start a session and run:
/sandbox
The panel has three tabs. Mode sets how sandboxed commands are approved, Overrides sets whether a failed command can fall back to running unsandboxed, and Config shows the settings Claude Code resolved. On Linux, a Dependencies tab also appears when something is missing. If it's the only tab, the sandbox can't start yet.
On the Mode tab, choose one:
| Mode | What happens to a sandboxed command |
|---|---|
| Auto-allow | Runs with no prompt, because the sandbox contains it |
| Regular permissions | Goes through your normal permission prompts, sandbox or not |
Claude Code saves the choice to .claude/settings.local.json, which applies to that project only. To turn the sandbox on for every project, set "sandbox": {"enabled": true} in ~/.claude/settings.json.
Auto-allow doesn't wave everything through. A command that a Bash deny rule matches is still blocked, a content-scoped ask rule such as Bash(git push *) still prompts, and an rm aimed at a critical path still goes through the permission flow.
Step 2: Prove commands run inside it
Ask Claude to run this command. Don't type it yourself at the ! prompt, because commands you type there usually run outside the sandbox:
touch ~/sandbox-probe
Inside the sandbox, it fails with Operation not permitted on macOS or Read-only file system on Linux and WSL2. Your home directory isn't writable by default. If Claude offers to retry it outside the sandbox, decline.
Then ask Claude to run curl https://example.com. In Manual mode, you get a prompt to allow the host, because allowed domains start empty and every connection goes through Claude Code's proxy.
One default to know before you rely on this: if the platform can't run the sandbox, or the dependency check fails at startup, Claude Code runs commands unsandboxed. Set "failIfUnavailable": true under sandbox to make it refuse to start instead.
Step 3: Allow the hosts and paths your build needs
When a command needs a new host, answering Yes allows it for the session. Yes, and don't ask again saves a WebFetch(domain:...) allow rule to your local settings. To skip the prompts for hosts you already know, list them:
{
"sandbox": {
"enabled": true,
"network": {
"allowedDomains": ["registry.npmjs.org", "files.pythonhosted.org"]
},
"filesystem": {
"allowWrite": ["~/.kube", "/tmp/build"]
}
}
}
allowWrite is the right fix when a tool such as kubectl or terraform writes outside the project. The command stays sandboxed, and only that path opens. Sandbox paths use normal conventions: ~/.kube is under your home directory and /tmp/build is absolute. That's different from Read and Edit permission rules, which use // for an absolute path.
Keep the domain list short. Anthropic's docs warn that a broad entry such as github.com can become a route for data to leave, because by default the proxy decides from the hostname and doesn't inspect encrypted traffic.
Step 4: Keep credentials away from sandboxed commands
The sandbox restricts writes, not reads. A sandboxed command can read most of your machine, including ~/.ssh and ~/.aws/credentials, and it inherits Claude Code's environment variables. There is no built-in credential deny list, so add one:
{
"sandbox": {
"enabled": true,
"credentials": {
"files": [
{ "path": "~/.aws/credentials", "mode": "deny" },
{ "path": "~/.ssh", "mode": "deny" }
],
"envVars": [
{ "name": "GITHUB_TOKEN", "mode": "deny" },
{ "name": "NPM_TOKEN", "mode": "deny" }
]
}
}
}
A deny file entry blocks reads inside the sandbox, and a deny variable is unset before each sandboxed command runs. Deny entries merge across every settings file, so a project can add one but can't remove one you set.
To block reads of your whole home directory while keeping the project readable, put this in the project's .claude/settings.json, where . means the project root:
{
"sandbox": {
"filesystem": {
"denyRead": ["~/"],
"allowRead": ["."]
}
}
}
In ~/.claude/settings.json, the same . would mean ~/.claude, and your project files would stay blocked.
Step 5: Close the unsandboxed retry
When a command fails inside the sandbox, Claude can retry it outside with a dangerouslyDisableSandbox parameter. Who approves that retry depends on your permission mode:
| Permission mode | The unsandboxed retry |
|---|---|
Manual or acceptEdits | You get a prompt titled "Bash command (unsandboxed)" |
| Auto mode | A classifier model reviews it |
bypassPermissions | Runs with no prompt |
dontAsk | Denied |
A matching allow rule such as Bash(curl *) also approves the retry with no prompt. To turn the retry off, which the Overrides tab calls Strict sandbox mode, set:
{
"sandbox": {
"enabled": true,
"allowUnsandboxedCommands": false,
"failIfUnavailable": true
}
}
Since Claude Code 2.1.285, a false in your user settings holds even when a project's settings say true. If you'd rather keep the retry and see every one, add an ask rule for Bash(dangerouslyDisableSandbox:true). It prompts in auto mode and bypass mode too.
Step 6: Take out the tools that can't run inside
Some tools break in the sandbox. docker is incompatible with it, so take only the commands you need out of the sandbox:
{
"sandbox": {
"enabled": true,
"excludedCommands": ["docker compose *"]
}
}
Three matching rules catch people out:
- Every command in the call has to match.
npm ci && docker compose buildstays sandboxed unless another entry coversnpm ci. - Claude Code matches the text. A script or
maketarget that callsdockerinside it doesn't match, and neither does/usr/local/bin/docker. - An excluded command runs with your full access. If the pattern covers a tool that acts on a file Claude can write, such as a compose file, Claude can edit that file and then run it outside the sandbox. Write the narrowest pattern that works.
Prefer allowWrite or allowedDomains when a tool only needs one more path or host. Those keep the command inside.
What the Claude Code sandbox doesn't cover
The sandbox wraps shell commands: Bash, PowerShell and Monitor commands, plus every process they start. Everything else in a session sits outside it:
- Claude's own file and web tools. Read, Edit, Write, WebFetch and WebSearch follow permission rules instead. A
denyReadentry doesn't stop the Read tool, andallowedDomainsdoesn't limit WebFetch. - Other processes Claude Code starts. Command hooks, local MCP servers, plugin monitors, LSP servers, your status line command and
apiKeyHelperrun with your full access. - Commands you type. A command at the
!prompt runs unsandboxed in most sessions. - Excluded commands and approved retries. Both run outside by design.
Subagents use the parent session's sandbox settings, so their Bash commands are sandboxed when yours are. The sandbox also changes nothing about what reaches the model: your prompts and the files Claude reads go to Anthropic or your provider either way.
When to use a container instead
The sandbox is the light option. Anthropic's sandbox environments page compares it with approaches that put the whole Claude Code process inside a boundary, which covers file tools, MCP servers and hooks too:
| Approach | What it isolates | Needs Docker | Best for |
|---|---|---|---|
| Sandboxed Bash tool | Shell commands and their child processes | No | Fewer prompts in everyday work on your own machine |
Sandbox runtime (srt claude) | The whole Claude Code process | No | MCP servers and hooks inside the boundary, without Docker. Still a beta research preview |
| Dev container | The full development environment | Yes | A standard setup a team commits to the repository |
| Virtual machine | A full operating system | No | Untrusted repositories and kernel-level separation |
| Cloud session | A VM that Anthropic hosts | No | Full isolation with nothing to provision |
Anthropic's guidance draws one firm line. The Bash sandbox on its own constrains only shell commands, so it isn't enough for fully unattended runs. Run any session in bypass mode inside a container, a VM or the sandbox runtime, as a non-root user, because Claude Code refuses to start in that mode as root on Linux and macOS. Anthropic's reference dev container pairs that with a default-deny firewall script that limits outbound traffic.
You can also stack the two: the Bash sandbox inside a container adds per-command limits on top of the container's boundary. If you're weighing whether to let Claude run that far unattended, our guide to Claude Code's permission modes covers what each mode approves.
Reference: what a sandboxed command can reach by default
| Access | Default | Change it with |
|---|---|---|
| Writes | The working directory, a per-user temp directory and directories you've added. Protected paths stay write-denied | filesystem.allowWrite, filesystem.denyWrite |
| Reads | Most of the machine, including credential files | filesystem.denyRead, credentials |
| Network | No direct route out. A local proxy checks each host against allowed domains, which start empty | network.allowedDomains, network.deniedDomains |
| Environment variables | Inherited from Claude Code, secrets included | credentials, CLAUDE_CODE_SUBPROCESS_ENV_SCRUB |
Protected paths include the .claude settings files, .claude/hooks and .mcp.json, plus, in the working directory, shell startup files such as .zshrc and the hooks and config files inside .git. A command that could edit them could grant itself permissions or add a hook that runs outside the sandbox, so an allowWrite entry doesn't reopen them.
Reference: settings for a team
| Key | What it does |
|---|---|
sandbox.enabled | Turns the sandbox on |
sandbox.failIfUnavailable | Refuses to start when the sandbox can't run, instead of running unsandboxed |
sandbox.allowUnsandboxedCommands | false ignores the unsandboxed retry |
sandbox.autoAllowBashIfSandboxed | Whether sandboxed commands run without a prompt |
sandbox.network.strictAllowlist | Refuses hosts outside the allowlist instead of prompting. Ignored in a repository's files |
sandbox.network.allowManagedDomainsOnly | In managed settings, honors only the organization's domain list |
To require the sandbox for every developer, deliver enabled, failIfUnavailable and allowUnsandboxedCommands: false through managed settings. That makes the sandbox admin-required, and from Claude Code 2.1.285 it ignores a repository's settings that loosen it, excludedCommands included. Put the exclusions your approved tools need in managed settings, because a repository can't supply them.
Troubleshooting
| Symptom | Fix |
|---|---|
| A host-not-allowed error | Approve the host, or add it to allowedDomains |
docker fails | Add a narrow excludedCommands pattern such as docker compose * |
jest hangs or fails | Watchman doesn't work in the sandbox. Turn off Jest's watchman option |
gh, gcloud or terraform fails TLS checks on macOS | Add a pattern such as gh * to excludedCommands. The tool then runs with your full access |
ssh or a database client can't reach an allowed host | These tools ignore the proxy variables, so they can't connect from inside |
ping or a UDP tool fails | Only TCP leaves the sandbox |
open or a browser sign-in fails with error -600 on macOS | The sandbox blocks Apple Events. Set allowAppleEvents in your user settings or exclude open *. Either way, commands can then launch apps outside the sandbox |
Anthropic's sandboxing guide has the full troubleshooting list, including the Linux user-namespace and AppArmor cases.
Frequently asked questions
What is the Claude Code sandbox?
It's an operating-system boundary around the shell commands Claude runs. It controls which files those commands can write and which network hosts they can reach. Because the operating system enforces it, Claude Code can run sandboxed commands without asking you to approve each one.
Is the Claude Code sandbox on by default?
No. It's off until you run /sandbox and pick a mode, or set sandbox.enabled to true in a settings file. Even then, Claude Code runs commands unsandboxed if the platform can't support it, unless you also set failIfUnavailable to true.
Does the sandbox stop Claude from reading my secrets?
Not by default. Sandboxed commands can read most of your machine, including ~/.ssh and ~/.aws/credentials, and they inherit Claude Code's environment variables. List the files and variables to block in a sandbox.credentials block. There's no built-in deny list.
Does the sandbox cover MCP servers and hooks?
No. Hooks, local MCP servers, plugin monitors and LSP servers run outside it with your full access, and Claude's Read, Edit and WebFetch tools follow permission rules instead. To put all of them inside a boundary, run Claude Code in the sandbox runtime, a dev container or a VM.
Does the Claude Code sandbox work on Windows?
Not on native Windows, where Claude Code runs commands unsandboxed. It works on macOS, Linux and WSL2, so Windows users can run Claude Code inside a WSL2 distribution. A container or VM also works.
Why does docker fail inside the sandbox?
Docker is incompatible with the sandbox. Take the commands you need out with a narrow excludedCommands pattern such as docker compose *. Those commands then run with your full access, so avoid a broad pattern like docker *.
Is the sandbox the same as auto mode?
No. Auto mode uses a classifier model to decide whether each tool call runs. The sandbox limits what a shell command can reach once it runs. They work independently, and you can use both together.
Can I skip permissions if the sandbox is on?
Anthropic's docs say no for fully unattended work. The Bash sandbox constrains only shell commands, so run bypass-mode sessions inside a container, a VM or the sandbox runtime, which also wrap file tools, MCP servers and hooks.
Write down why each exception exists
A sandbox policy grows one exception at a time: a host for a registry, a path for kubectl, a pattern for docker compose. Each one is a decision someone will need to remember later, and Claude will keep asking for the same exceptions unless the reasoning lives somewhere it reads. Our guide to compound engineering for Claude Code shows how to build those rules up one fix at a time. For the bigger picture, our guide to whether Claude Code is safe for a business covers the account, approver and managed settings around it, and our hooks guide covers the checks that run outside the sandbox.
Stop guessing. Score your first workflow.
Score one workflow in about five minutes. Nine questions, a grade, and the specific gap holding it back - no call required.
Related Posts

Is Claude Code safe for a business? What it can reach and what you control
Claude Code is safe enough for business use when three things are set on purpose: the plan developers sign in with, the permission mode sessions start in, and the limits locked in managed settings. What it can reach, where your code goes, who approves each action, and the version a team should run.

Claude Sheets, Whiteboards and Data: the admin defaults to check
Anthropic launched Claude Sheets and Whiteboards in beta on November 10, 2026, and renamed Claude Dashboards to Claude Data. What's already on for Team plans, what Enterprise turns on November 19, why live sharing is the setting to read first, and where to change it.

Claude Code best practices for a team: what to write down and what to enforce
Claude Code best practices for a team: what belongs in CLAUDE.md, which rules to enforce with hooks, deny rules and managed settings, how to scope them, and how to measure a pilot.