Claude Code 沙盒模式配置指南:設定方法與防護邊界
Claude Code Sandbox Mode: Exact Config and What It Blocks
Claude Code 沙盒模式可透過 /sandbox 或 settings.json 啟用,並限制 Bash 命令的寫入路徑及可連線主機。沙盒不涵蓋 Read、Edit、Write 等內置工具、hooks 或 MCP servers,而且預設限制寫入而非讀取;原生 Windows 不支援,需在 WSL2 執行。
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 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.
Which option is right for you?
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.
| Your situation | What to pick first | First page to open |
|---|---|---|
| Beginner on macOS |
/sandbox → auto-allow mode. Seatbelt is built in, so there's nothing to install (docs) |
Sandboxing docs |
| Daily work on Linux or WSL2 | Install bubblewrap and socat, then enable the sandbox with failIfUnavailable: true
|
Sandboxing docs, Linux setup |
| Native Windows (no WSL) | Move Claude Code into a WSL2 distribution. Native Windows runs commands unsandboxed | Sandboxing docs |
| Cron jobs or headless runs on a VPS | Sandbox plus allowUnsandboxedCommands: false plus deny rules |
/claude-code-permissions-best-practices-headless-template/ |
| Zero budget | The sandbox costs nothing extra. It ships with Claude Code | Permission modes docs |
| You want to skip every prompt (YOLO) | Use bypassPermissions only inside a container or VM |
Permission modes docs |
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.
What is Claude Code sandbox mode?
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):
-
Writes: the current working directory, the per-user temp directory, and any directory added with
--add-dir,/add-dirorpermissions.additionalDirectories. -
Reads: most of the machine, credential files like
~/.sshand~/.aws/credentialsincluded. -
Network: no direct route out. Traffic goes through a local proxy that checks each host against
allowedDomains, and that list starts empty.
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).
Does Claude Code have sandbox mode?
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):
-
In a session: type
/sandboxto open the sandbox panel. -
Persistently: add
"sandbox": {"enabled": true}to~/.claude/settings.jsonor the project's.claude/settings.json. -
For one run: pass
--settings '{"sandbox": {"enabled": true}}'when you startclaude.
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 vs sandbox mode: what's the difference?
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).
| Auto mode | bypassPermissions ("YOLO") | Sandbox (auto-allow) | |
|---|---|---|---|
| What it controls | Whether to prompt | Whether to prompt | What Bash can touch |
| How it decides | Classifier model reviews each action | Approves everything | OS rules (Seatbelt / bubblewrap) |
| Covers file edit tools | Yes | Yes | No, Bash only |
| Hard guarantee? | No: "does not guarantee safety" | No | Yes, within its scope |
| Official "best for" | Long tasks, fewer prompts | Isolated containers and VMs only | Bash-heavy work on macOS/Linux/WSL2 |
| Extra requirements | Supported model (e.g. Opus 4.6+, Sonnet 4.6+) | None |
bubblewrap and socat on Linux |
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.
How do you run Claude Code in sandbox mode?
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.
Step-by-step
-
Linux/WSL2 only: install the dependencies. Run
sudo apt-get install bubblewrap socaton Ubuntu/Debian, orsudo dnf install bubblewrap socaton Fedora (docs). -
Ubuntu 24.04 and later only: run
sysctl kernel.apparmor_restrict_unprivileged_userns. If it returns1, AppArmor is blocking the user namespaces bubblewrap needs. Add thebwrapAppArmor profile shown on the docs page and runsudo systemctl reload apparmor. -
Start Claude Code and type
/sandbox. The panel has a Mode tab (auto-allow or regular permissions), an Overrides tab (strict sandbox mode) and a Config tab showing the resolved settings. On Linux, a Dependencies tab appears if the optional seccomp filter is missing. -
Choose auto-allow on the Mode tab. Claude Code saves this choice to
.claude/settings.local.json. -
For unattended use, open Overrides and turn on strict sandbox mode. This sets
allowUnsandboxedCommands: false. - Verify. Ask Claude to run the two test commands from the docs:
| Test command | Expected result inside the sandbox |
|---|---|
touch ~/sandbox-probe |
Operation not permitted (macOS) or Read-only file system (Linux/WSL2) |
curl --noproxy '*' https://example.com |
Could not resolve host |
If either command succeeds, the sandbox isn't active. Check /sandbox → Config.
Example settings.json for an unattended project
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" }
]
}
}
}
What each piece does:
-
failIfUnavailable: truestops Claude Code at startup if the sandbox can't run. Without it, a missingbubblewrapon a fresh VPS can leave you running with no sandbox. -
allowUnsandboxedCommands: falseremoves the retry escape. The docs say Claude Code then "ignores thedangerouslyDisableSandboxparameter." -
strictAllowlist: trueblocks any host outside the allowlist instead of prompting. Per the docs, this only takes effect in user, managed or CLI--settingssettings, so a project file alone won't do it. -
allowedDomainsentries without a port allow every port on that host. Wildcards like*.example.comwork.
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/.
Common mistakes and fixes
-
dockerfails inside the sandbox. The docs calldockerincompatible. Fix it with a narrow exclusion such as"excludedCommands": ["docker compose *"]. -
git pushover SSH fails on macOS even when the host is allowed. Switch the remote to HTTPS, or excludegit fetch *,git pull *andgit push *. - A database client can't connect to an allowed host. Tools that ignore proxy environment variables can't get out. Exclude that specific command.
-
A local dev server can't be reached. On macOS, set
network.allowLocalBinding: true. On Linux/WSL2 that setting has no effect, so useexcludedCommandsinstead.
Does Claude Code sandbox mode work on Windows?
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.
What does Claude Code sandbox mode actually block, and what slips through?
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."
| Scenario | Blocked by sandbox? | What actually controls it |
|---|---|---|
rm -rf ~/Documents via Bash |
Yes (write outside allowed paths) | OS sandbox |
curl to a host not in allowedDomains
|
Yes (or a prompt, depending on mode) | Sandbox proxy |
cat ~/.ssh/id_ed25519 via Bash |
No by default (reads are open) | Add credentials.files deny or denyRead
|
Claude's Read tool opening ~/.aws/credentials
|
No | Permission deny rules |
| Edit/Write tool changing files | No | Permission rules / permission mode |
| WebFetch to any domain | No |
WebFetch(domain:...) permission rules |
| A command hook script | No, full access | Your own script review |
| Local MCP server | No, full access | MCP config / permission rules |
A command in excludedCommands
|
No, full access | Keep patterns narrow |
Writes to .claude/, .bashrc, .git/hooks, .mcp.json
|
Yes (protected paths) | Built-in sandbox protection |
| Exfiltration to an allowed domain | No, hostname-only check |
tlsTerminate (experimental) or a tighter allowlist |
A few rows need more explanation.
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/.
How do Claude Code hooks fit with sandbox mode?
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."
To add one:
- Save a script, for example
~/.claude/hooks/guard.sh, that reads the JSON on stdin and exits 2 to block. - Make it executable:
chmod +x ~/.claude/hooks/guard.sh. - Add it under
hooks.PreToolUsewith amatcher(for example"Edit|Write") in settings.json. - Run
/hooksand confirm it's listed under PreToolUse (costs docs use the same check).
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/.
How do you check Claude Code usage?
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:
-
/usagein a session. The Session block shows total cost, API duration and tokens by model. Claude Code computes the dollar figure locally at list price, so it's an estimate. It resets when you run/clear(since v2.1.211). -
Plan breakdown (Pro, Max, Team, Enterprise). The same screen shows usage bars, attribution to skills, subagents and MCP servers, and recommendations. Press
dorwto switch between 24 hours and 7 days. - API billing. The Console usage page is the authoritative source. The first time you authenticate, a "Claude Code" workspace is created automatically, and you can set workspace spend limits there.
-
Headless runs. Cap a single run with
--max-budget-usd.
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/.
Next steps
Start with the three DIY steps below. All of them work on any plan.
DIY today:
- Run
/sandbox, choose auto-allow, then run the two test commands (touch ~/sandbox-probeandcurl --noproxy '*' https://example.com). Both should fail. - Add
failIfUnavailable: trueandallowUnsandboxedCommands: falseto~/.claude/settings.jsonon any machine that runs jobs unattended. - Close the read gap: deny
~/.sshand~/.aws/credentialsinsandbox.credentials, and add matching Read deny rules.
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.
Related guides on this site:
- Claude Code Permissions Best Practices: Headless Template
- Claude Code on VPS: systemd Setup That Survives Reboots
- Claude Code Hooks Examples: 7 Copy-Paste Scripts
FAQ
What does Reddit say about Claude Code sandbox mode?
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.
Can I use Claude Code sandbox and auto mode together?
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.
Is it safe to use Claude Code YOLO mode with the sandbox?
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).
Is there a Claude Code CLI flag for sandbox mode?
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).
How do I check Claude Code usage after enabling the sandbox?
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).
Sources
- Configure the sandboxed Bash tool – Claude Code Docs
- Permission modes – Claude Code Docs
- Hooks reference – Claude Code Docs
- Manage costs effectively – Claude Code Docs
- Making Claude Code more secure and autonomous with sandboxing – Anthropic Engineering
- anthropics/sandbox-runtime – GitHub
- Claude pricing
- Claude Console usage
This article was created with the help of AI. Sources are linked inline; check the official documentation for the latest details.
來源:DEV Community · dev.to