Back to Blog

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

Alex Kim
14 min read
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 allowedDomains and paths to allowWrite.
  • ๐Ÿ”‘ Hide your secrets. By default, sandboxed commands can read ~/.ssh and ~/.aws/credentials. A credentials block blocks them.
  • ๐Ÿšช Close the escape hatch. Set allowUnsandboxedCommands to false, 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:

  1. 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.
  2. Two packages on Linux and WSL2. The sandbox needs bubblewrap and socat. On Ubuntu or Debian, run sudo apt-get install bubblewrap socat. macOS uses its built-in Seatbelt framework and needs nothing extra.
  3. A restart after installing. Claude Code checks for the packages at startup, so restart it before you run /sandbox.
  4. A settings file you can edit. The steps below write to .claude/settings.json in 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:

ModeWhat happens to a sandboxed command
Auto-allowRuns with no prompt, because the sandbox contains it
Regular permissionsGoes 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 modeThe unsandboxed retry
Manual or acceptEditsYou get a prompt titled "Bash command (unsandboxed)"
Auto modeA classifier model reviews it
bypassPermissionsRuns with no prompt
dontAskDenied

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:

  1. Every command in the call has to match. npm ci && docker compose build stays sandboxed unless another entry covers npm ci.
  2. Claude Code matches the text. A script or make target that calls docker inside it doesn't match, and neither does /usr/local/bin/docker.
  3. 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 denyRead entry doesn't stop the Read tool, and allowedDomains doesn't limit WebFetch.
  • Other processes Claude Code starts. Command hooks, local MCP servers, plugin monitors, LSP servers, your status line command and apiKeyHelper run 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:

ApproachWhat it isolatesNeeds DockerBest for
Sandboxed Bash toolShell commands and their child processesNoFewer prompts in everyday work on your own machine
Sandbox runtime (srt claude)The whole Claude Code processNoMCP servers and hooks inside the boundary, without Docker. Still a beta research preview
Dev containerThe full development environmentYesA standard setup a team commits to the repository
Virtual machineA full operating systemNoUntrusted repositories and kernel-level separation
Cloud sessionA VM that Anthropic hostsNoFull 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

AccessDefaultChange it with
WritesThe working directory, a per-user temp directory and directories you've added. Protected paths stay write-deniedfilesystem.allowWrite, filesystem.denyWrite
ReadsMost of the machine, including credential filesfilesystem.denyRead, credentials
NetworkNo direct route out. A local proxy checks each host against allowed domains, which start emptynetwork.allowedDomains, network.deniedDomains
Environment variablesInherited from Claude Code, secrets includedcredentials, 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

KeyWhat it does
sandbox.enabledTurns the sandbox on
sandbox.failIfUnavailableRefuses to start when the sandbox can't run, instead of running unsandboxed
sandbox.allowUnsandboxedCommandsfalse ignores the unsandboxed retry
sandbox.autoAllowBashIfSandboxedWhether sandboxed commands run without a prompt
sandbox.network.strictAllowlistRefuses hosts outside the allowlist instead of prompting. Ignored in a repository's files
sandbox.network.allowManagedDomainsOnlyIn 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

SymptomFix
A host-not-allowed errorApprove the host, or add it to allowedDomains
docker failsAdd a narrow excludedCommands pattern such as docker compose *
jest hangs or failsWatchman doesn't work in the sandbox. Turn off Jest's watchman option
gh, gcloud or terraform fails TLS checks on macOSAdd 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 hostThese tools ignore the proxy variables, so they can't connect from inside
ping or a UDP tool failsOnly TCP leaves the sandbox
open or a browser sign-in fails with error -600 on macOSThe 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.

#claude-code#Sandbox#ai-agents#security#Docker
Free assessment

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.