The Claude Code sandbox is an operating-system boundary around the shell commands Claude runs: you turn it on with /sandbox, and from then on Bash commands can only write inside your project and a temp folder, and can only reach network hosts you allow. Because the OS enforces those limits, Claude Code can run sandboxed commands without asking you to approve each one.
This guide covers what the sandbox restricts, which platforms support it, how to turn it on, the two sandbox modes, the settings that matter and the limits to keep in mind. It is based on the official sandboxing documentation and the settings reference.
What does the Claude Code sandbox restrict?
When the sandbox is on, every shell command Claude runs starts inside it, and so do the processes those commands start. The defaults:
| Access | Default inside the sandbox | Change it with |
|---|---|---|
| Writes | Working directory, a per-user temp directory and directories you added; protected paths stay blocked | filesystem.allowWrite, filesystem.denyWrite |
| Reads | Most of the machine, including files like ~/.ssh and ~/.aws/credentials |
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 |
Note the read default. The sandbox does not hide your credentials unless you tell it to, so the credentials settings below are worth adding.
What runs outside the sandbox matters just as much:
- Built-in tools such as Read, Edit, Write, WebFetch and WebSearch. They follow permission rules instead, so a
denyReadentry doesn't stop the Read tool. - Other processes Claude Code starts: hooks, local MCP servers, LSP servers, your status line command and
apiKeyHelper. - Commands you type yourself at the
!prompt, in most sessions. - Excluded commands and unsandboxed retries, covered below.
Claude Code builds the sandbox on Anthropic's open source sandbox-runtime package.
Which platforms does the sandbox support?
| Platform | How it is enforced | What you install |
|---|---|---|
| macOS | Apple's built-in Seatbelt framework | Nothing |
| Linux | bubblewrap, with socat relaying network traffic | bubblewrap and socat |
| WSL2 | bubblewrap, same as Linux | bubblewrap and socat |
| Native Windows | Not supported; commands run unsandboxed | Use WSL2 instead |
On Linux and WSL2, install the two packages:
# Ubuntu or Debian
sudo apt-get install bubblewrap socat
# Fedora
sudo dnf install bubblewrap socat
A few platform notes from the docs:
- Ubuntu 24.04 and later may block bubblewrap from creating user namespaces through AppArmor. Run
sysctl kernel.apparmor_restrict_unprivileged_userns; if it returns1, add the AppArmor profile forbwrapshown in the docs. - WSL1 is not supported. If you see
Sandboxing requires WSL2, upgrade the distribution. - The seccomp filter is optional and adds Unix domain socket blocking. Install it with
npm install -g @anthropic-ai/sandbox-runtimeif/sandboxreports it missing. - Restart after installing. The dependency check runs at startup.
How do you turn on the sandbox with /sandbox?
- Start a session and run
/sandbox. The panel has Mode, Overrides and Config tabs, plus a Dependencies tab on Linux when something is missing. - On the Mode tab, choose auto-allow or regular permissions.
- Ask Claude to run a build or test command. The first time a command needs a new domain, Claude Code asks you to approve it.
The panel saves your choice to .claude/settings.local.json, so it applies to the current project. To sandbox every project, set sandbox.enabled in your user settings:
{
"sandbox": {
"enabled": true
}
}
To try it for one session without touching any file:
claude --settings '{"sandbox": {"enabled": true, "allowUnsandboxedCommands": false}}'
One default to be aware of: if the sandbox can't start because a dependency is missing or the platform is unsupported, Claude Code runs commands without it. Set sandbox.failIfUnavailable to true to make Claude Code exit at startup instead.
Check that it works. Ask Claude (not the ! prompt) to run touch ~/sandbox-probe. Inside the sandbox it fails with Operation not permitted on macOS or Read-only file system on Linux. curl --noproxy '*' https://example.com should fail with Could not resolve host. If Claude offers to retry outside the sandbox, decline.
What are the sandbox modes?
Both modes enforce the same file and network limits. They differ only in approvals.
Auto-allow mode runs sandboxed commands with no prompt. Some checks still apply:
- A command a
Bashdeny rule matches is still blocked. - Content-scoped ask rules such as
Bash(git push *)still prompt. - Recognized
rmcommands aimed at critical paths still go through the normal permission flow. - Commands that set a variable in front, like
FOO=bar npm test, or forms likemake CC=clang, go through the normal flow too, though they still run sandboxed.
Regular permissions mode sends every Bash command through the normal permission prompts even though it is sandboxed. You get more control and more prompts. In settings, this is "autoAllowBashIfSandboxed": false.
The unsandboxed retry. When a command fails because of the sandbox, Claude may ask to rerun it outside. In Manual mode you see a prompt titled "Bash command (unsandboxed)"; in auto mode the classifier reviews it; in dontAsk it is denied. To remove this escape hatch, set "allowUnsandboxedCommands": false, which the Overrides tab calls Strict sandbox mode.
How do filesystem and network isolation work?
Filesystem. Writes are allowed in the working directory, the temp directory Claude Code points $TMPDIR to, and directories added with --add-dir, /add-dir or permissions.additionalDirectories. Inside those, the sandbox still blocks writes to files Claude Code loads configuration or code from: .claude settings, skills, agents and hooks, .mcp.json, shell startup files like .bashrc and .zshrc, .gitconfig, and hooks and config inside .git. An allowWrite entry does not lift that protection. In a linked git worktree, writes to the shared .git directory are allowed so commits work.
Network. On Linux and WSL2 a sandboxed command runs in a separate network namespace; on macOS, Seatbelt blocks connections other than the one to the proxy. Claude Code runs the proxy outside the sandbox and points commands at it with HTTP_PROXY, HTTPS_PROXY and related variables. As a result:
- Tools that honor proxy variables, such as
curl,npmandgitover HTTPS, work once their host is allowed. - Tools that ignore them, such as plain
sshand most database drivers, can't connect even to an allowed host. - UDP, HTTP/3 and
pingcan't leave the sandbox.
Approving a host at a prompt allows it for the session. "Yes, and don't ask again" saves a WebFetch(domain:...) allow rule, which also feeds the sandbox allowlist.
Which sandbox settings matter most?
| Setting | What it does |
|---|---|
sandbox.enabled |
Turns the sandbox on |
sandbox.failIfUnavailable |
Exit at startup if the sandbox can't run |
sandbox.autoAllowBashIfSandboxed |
true (default) for auto-allow, false for regular permissions |
sandbox.allowUnsandboxedCommands |
false turns off the unsandboxed retry |
sandbox.excludedCommands |
Command patterns that run outside the sandbox |
sandbox.filesystem.allowWrite / denyWrite |
Extra writable paths, or paths to block |
sandbox.filesystem.denyRead / allowRead |
Block reads, then reopen narrower paths |
sandbox.network.allowedDomains / deniedDomains |
Hosts commands may or may not reach |
sandbox.credentials |
Deny reads of credential files and unset secret variables |
A project configuration that combines them, following the official examples:
{
"sandbox": {
"enabled": true,
"filesystem": {
"allowWrite": ["/tmp/build"]
},
"network": {
"allowedDomains": ["registry.npmjs.org", "*.example.com"]
},
"credentials": {
"files": [
{ "path": "~/.aws/credentials", "mode": "deny" },
{ "path": "~/.ssh", "mode": "deny" }
],
"envVars": [
{ "name": "GITHUB_TOKEN", "mode": "deny" }
]
}
}
}
Sandbox paths use normal conventions: /tmp/build is absolute and ~/.kube is under your home folder. That differs from permission rules, where // means absolute. When a tool needs one more folder or host, prefer allowWrite or allowedDomains over excludedCommands, because an excluded command runs with your full access. For where these keys live and which file wins, see the Claude Code settings guide.
For organizations, deliver the sandbox block through managed settings with enabled, failIfUnavailable and allowUnsandboxedCommands: false, and add network.allowManagedDomainsOnly so only the managed allowlist applies.
How does the sandbox relate to permissions and modes?
They are separate layers. Permission rules decide whether a tool call runs, based on the command text, before it starts. The sandbox limits what a running shell command can touch, whatever the command turns out to do.
| What it controls | What replaces the prompt | |
|---|---|---|
/sandbox |
What a Bash command can reach once it runs | The sandbox boundary, in auto-allow mode |
| Auto mode | Whether each tool call runs | A classifier that reviews actions |
--dangerously-skip-permissions |
Whether each tool call runs | Nothing |
The docs recommend using both: a Bash deny rule can be sidestepped by writing a command differently, while the sandbox still holds. Paths and domains from Read, Edit and WebFetch rules are merged into the sandbox configuration.
What are the limits of the sandbox?
The docs are direct that the sandbox reduces risk but is not complete isolation:
- Network filtering is by hostname. The proxy doesn't inspect TLS by default, so allowing a broad domain such as
github.comcan open paths for data exfiltration, including domain fronting. - Unix sockets can bypass it. Allowing
/var/run/docker.sock, for example, effectively grants host access. - Broad write access can escalate. Allowing writes to folders on your
$PATHor to shell config files can lead to code execution in other security contexts. enableWeakerNestedSandboxlets the Linux sandbox run inside Docker without privileged namespaces, but considerably weakens it.- Scope is shell commands. For a boundary around the whole Claude Code process, run it in a container, a VM or the sandbox runtime.
Keep your skills next to a safe setup
A sandbox makes it safer to let Claude run commands on its own; reusable instructions make those runs consistent. Kipt keeps your prompts and Agent Skills as Markdown in a private GitHub repo you own and installs every skill into Claude Code or Codex with one npx skills add command.