Sandboxing and auto mode

Claude Code · Expert · 16 min

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.

Check yourself

  1. Why is the sandbox stronger than a deny rule like Bash(curl *)?
  2. Which statement about bypassPermissions is true?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: code.claude.com/docs/en/sandboxing

Builds on

Unlocks

Nothing builds on this yet.