For long unattended runs, a boundary enforced by the operating system is stronger than any rule matched on command text.
Permission rules match text, so Bash(curl *) does not catch python -c "import urllib...". A sandbox solves this differently: the operating system itself restricts what a shell command can touch, whatever the command is.
Claude Code's built-in Bash sandbox (macOS via Seatbelt; Linux and WSL2 via bubblewrap and socat; not native Windows) is off by default. Turn it on with /sandbox or "sandbox": {"enabled": true} in settings. Inside it, shell commands:
- can write only to the working directory, temp folders and directories you add (
sandbox.filesystem.allowWrite), - reach the network only through a local proxy that checks hosts against
sandbox.network.allowedDomains, which starts empty.
Because the boundary is enforced, sandboxed commands can run without prompts (auto-allow), which removes most approval fatigue safely. Limits: the sandbox covers shell commands only. Claude's file tools, WebFetch, MCP servers and hooks run outside it and follow permission rules. A command that fails in the sandbox may be retried unsandboxed with approval; "allowUnsandboxedCommands": false disables that escape hatch, and failIfUnavailable refuses to start without the sandbox.
Auto mode is different: a classifier model reviews actions and blocks risky ones. It reduces prompts and catches many bad actions but is a judgment, not a boundary; combine it with the sandbox for defense in depth.
bypassPermissions (--dangerously-skip-permissions) removes checks entirely and offers no protection against prompt injection. Use it only inside a disposable container or VM, as a non-root user, with network limits. For whole-process isolation, run Claude Code in a dev container or the open-source sandbox runtime.
Example
{
"sandbox": {
"enabled": true,
"allowUnsandboxedCommands": false,
"failIfUnavailable": true,
"filesystem": {
"allowWrite": ["~/.cache/pip"]
},
"network": {
"allowedDomains": ["github.com", "*.npmjs.org", "pypi.org"]
}
},
"permissions": {
"deny": ["Read(./.env)", "Read(~/.ssh/**)"]
}
}Remember
- The sandbox is OS-enforced filesystem and network isolation for shell commands
- It does not cover file tools, WebFetch, MCP or hooks; keep permission rules too
- Auto mode is a classifier, not a boundary; bypassPermissions belongs only in disposable containers
Watch out for
- Enabling the sandbox and assuming secrets are safe, while the Read tool (outside the sandbox) can still open them without a deny rule.