| title | Configure the sandboxed Bash tool |
|---|---|
| source | https://code.claude.com/docs/en/sandboxing |
| category | code |
| generated | true |
Fetch the complete documentation index at: https://code.claude.com/docs/llms.txt Use this file to discover all available pages before exploring further.
Learn how Claude Code's sandboxed Bash tool provides filesystem and network isolation for safer, more autonomous agent execution.
The Bash sandbox lets Claude run most shell commands without stopping to ask permission. Instead of approving each command, you define which files and network domains commands can touch, and the operating system enforces that boundary for every Bash command and its child processes.
This page covers how to:
- Enable the sandbox and choose how sandboxed commands are approved
- Configure which paths and network domains commands can reach
- Combine sandboxing with permission rules and permission modes
- Enforce sandboxing across an organization with managed settings
The sandbox is built into Claude Code and runs on macOS, Linux, and WSL2. Native Windows is not supported. On Windows, run Claude Code inside a WSL2 distribution.
On macOS, there is nothing to install: sandboxing uses the built-in Seatbelt framework. On Linux and WSL2, the sandbox relies on two packages, covered in Set up Linux and WSL2. Even if you haven't installed them yet, you can start with /sandbox, because its panel shows whether anything is missing.
```text theme={null}
/sandbox
```
This opens the sandbox panel with three tabs:
* **Mode**: choose how sandboxed commands are approved, covered in the next step
* **Overrides**: choose whether commands that fail under the sandbox can fall back to running unsandboxed. This is the [`allowUnsandboxedCommands`](./code-settings.md#sandbox-settings) setting
* **Config**: view the resolved sandbox settings
If the panel shows only a Dependencies tab, a required package is missing. Install it as described in [Set up Linux and WSL2](#set-up-linux-and-wsl2), restart Claude Code, and run `/sandbox` again.
Commands that cannot run sandboxed fall back to the regular permission flow. To widen or narrow these boundaries, see [Configure sandboxing](#configure-sandboxing).
Selecting a mode in the panel writes to your project's local settings at .claude/settings.local.json, which apply to the current project and are not checked into git. To enable the sandbox across all of your projects, set sandbox.enabled to true in your user settings at ~/.claude/settings.json. To enforce sandboxing for every developer in an organization, use managed settings.
On Linux and WSL2, the sandbox relies on two packages:
bubblewrap: the unprivileged sandboxing tool that enforces filesystem isolationsocat: the relay used to route network traffic through the sandbox proxy
Install them with your distribution's package manager:
```bash theme={null} sudo apt-get install bubblewrap socat ``` ```bash theme={null} sudo dnf install bubblewrap socat ```After installing, the Dependencies tab in /sandbox shows whether ripgrep, bubblewrap, socat, and the seccomp filter are available on your platform. Ripgrep is bundled with the native Claude Code binary. The seccomp filter is optional and adds Unix domain socket blocking. Install it with npm install -g @anthropic-ai/sandbox-runtime if it is missing.
When a required dependency is missing, the Dependencies tab is the only tab shown until you install it. The dependency check runs at startup, so restart Claude Code after installing packages for /sandbox to detect them.
To check whether your environment enforces this restriction, including inside WSL2, run `sysctl kernel.apparmor_restrict_unprivileged_userns`. If the key does not exist or returns `0`, skip this step. If it returns `1`, add an AppArmor profile that grants `bwrap` this capability:
```bash theme={null}
sudo tee /etc/apparmor.d/bwrap > /dev/null <<'EOF'
abi <abi/4.0>,
include <tunables/global>
profile bwrap /usr/bin/bwrap flags=(unconfined) {
userns,
include if exists <local/bwrap>
}
EOF
```
The profile applies only to `bwrap` itself, not to the commands it runs inside the sandbox. Reload AppArmor to apply it:
```bash theme={null}
sudo systemctl reload apparmor
```
On WSL2, sandboxed commands cannot launch Windows binaries such as `cmd.exe`, `powershell.exe`, or anything under `/mnt/c/`. WSL hands these off to the Windows host over a Unix socket, which the sandbox blocks. If a command needs to invoke a Windows binary, add it to [`excludedCommands`](./code-settings.md#sandbox-settings) so it runs outside the sandbox.
Claude Code offers two sandbox modes:
Auto-allow mode: Bash commands will attempt to run inside the sandbox and are automatically allowed without requiring permission. Commands that cannot be sandboxed, such as those needing network access to non-allowed hosts, fall back to the regular permission flow, where Claude Code checks your permission rules and prompts you for any command those rules do not already allow.
Even in auto-allow mode, the following still apply:
- Explicit deny rules are always respected
rmorrmdircommands that target/, your home directory, or other critical system paths still trigger a permission prompt- Ask rules apply to commands that fall back to the regular permission flow
Regular permissions mode: All Bash commands go through the regular permission flow, even when sandboxed. This provides more control but requires more approvals.
In both modes, the sandbox enforces the same filesystem and network restrictions. The difference is only in whether sandboxed commands are auto-approved or require explicit permission.
Some commands cannot run inside the sandbox at all, such as tools that are incompatible with it or that need a host you have not allowed. Rather than failing the task or requiring you to turn sandboxing off, Claude Code includes an escape hatch: when a command fails because of sandbox restrictions, Claude analyzes the failure and may retry the command with the dangerouslyDisableSandbox parameter. The retried command runs outside the sandbox, so it goes through the regular permission flow and requires your approval.
You can disable this escape hatch by setting "allowUnsandboxedCommands": false in your sandbox settings. When disabled, which the /sandbox Overrides tab shows as Strict sandbox mode, the dangerouslyDisableSandbox parameter is completely ignored and all commands must run sandboxed or be explicitly listed in excludedCommands.
Customize sandbox behavior through your settings.json file. See Settings for the complete configuration reference.
By default, sandboxed commands can only write to the current working directory. If subprocess commands like kubectl, terraform, or npm need to write outside the project directory, use sandbox.filesystem.allowWrite to grant access to specific paths:
{
"sandbox": {
"enabled": true,
"filesystem": {
"allowWrite": ["~/.kube", "/tmp/build"]
}
}
}These paths are enforced at the OS level, so all commands running inside the sandbox, including their child processes, respect them. This is the recommended approach when a tool needs write access to a specific location, rather than excluding the tool from the sandbox entirely with excludedCommands.
When the same filesystem array is defined in multiple settings scopes, the arrays are merged: paths from every scope are combined, not replaced.
Path prefixes control how paths are resolved:
| Prefix | Meaning | Example |
|---|---|---|
/ |
Absolute path from filesystem root | /tmp/build stays /tmp/build |
~/ |
Relative to home directory | ~/.kube becomes $HOME/.kube |
./ or no prefix |
Relative to the project root for project settings, or to ~/.claude for user settings |
./output in .claude/settings.json resolves to <project-root>/output |
This syntax differs from Read and Edit permission rules, which use //path for absolute and /path for project-relative. Sandbox filesystem paths use standard conventions: /tmp/build is absolute.
You can also deny write or read access using sandbox.filesystem.denyWrite and sandbox.filesystem.denyRead, and re-allow specific paths within a denied region using sandbox.filesystem.allowRead.
The example below blocks reading from the entire home directory while still allowing reads from the current project. Place it in your project's .claude/settings.json, because the relative path . resolves to the project root only when the configuration lives in project settings:
{
"sandbox": {
"enabled": true,
"filesystem": {
"denyRead": ["~/"],
"allowRead": ["."]
}
}
}The . in allowRead resolves to the project root because this configuration lives in project settings. If you placed the same configuration in ~/.claude/settings.json, . would resolve to ~/.claude instead, and project files would remain blocked by the denyRead rule.
The sandboxed Bash tool restricts file system access to specific directories:
- Default write behavior: read and write access to the current working directory and its subdirectories
- Default read behavior: read access to the entire computer, except certain denied directories. Note that this default still allows reading credential files such as
~/.aws/credentialsand~/.ssh/. Add them todenyReadto block them. - Blocked access: cannot modify files outside the current working directory without explicit permission, including shell configuration files such as
~/.bashrcand system binaries in/bin/ - Configurable: define custom allowed and denied paths through settings
You can grant write access to additional paths using sandbox.filesystem.allowWrite in your settings. These restrictions are enforced at the OS level, so they apply to all subprocess commands, including tools like kubectl, terraform, and npm, not just Claude's file tools.
Network access is controlled through a proxy server running outside the sandbox:
- Domain restrictions: no domains are pre-allowed. The first time a command needs a new domain, Claude Code prompts for approval. Pre-allow domains with
allowedDomainsto avoid the prompt. - Managed lockdown: if
allowManagedDomainsOnlyis set in managed settings, non-allowed domains are blocked automatically instead of prompting, and onlyallowedDomainsfrom managed settings are honored. - Custom proxy support: advanced users can implement custom rules on outgoing traffic
- Comprehensive coverage: restrictions apply to all scripts, programs, and subprocesses spawned by commands
The sandboxed Bash tool leverages operating system security primitives:
- macOS: uses Seatbelt for sandbox enforcement
- Linux: uses bubblewrap for isolation
- WSL2: uses bubblewrap, same as Linux
WSL1 is not supported because bubblewrap requires kernel features only available in WSL2. These OS-level restrictions ensure that all child processes spawned by Claude Code's commands inherit the same security boundaries.
These same primitives are available as the standalone @anthropic-ai/sandbox-runtime package, which the Sandbox environments page covers as a separate approach for wrapping the entire Claude Code process.
Sandboxing, permission rules, and permission modes are complementary layers. The sections below cover how the sandbox interacts with each.
Permission rules and sandboxing control different things:
- Permission rules control which tools Claude Code can use and are evaluated before any tool runs. They apply to all tools: Bash, Read, Edit, WebFetch, MCP, and others.
- Sandboxing provides OS-level enforcement that restricts what Bash commands can access at the filesystem and network level. It applies only to Bash commands and their child processes.
The two layers also differ in how they are enforced. Claude Code evaluates permission decisions before a command runs, based on the command string and, in auto mode, a separate classifier's judgment about whether the command is safe. The operating system enforces the sandbox boundary on the running process, so it holds regardless of what the model chose to run and even if an allowed command does more than its name suggests.
Filesystem and network restrictions are configured through both sandbox settings and permission rules:
| Setting or rule | What it does |
|---|---|
sandbox.filesystem.allowWrite |
Grants subprocess write access to paths outside the working directory |
sandbox.filesystem.denyWrite and sandbox.filesystem.denyRead |
Block subprocess access to specific paths |
sandbox.filesystem.allowRead |
Re-allows reading specific paths within a denyRead region |
Edit allow rules |
Grant write access to specific paths, the same way sandbox.filesystem.allowWrite does |
Read and Edit deny rules |
Block access to specific files or directories |
WebFetch allow and deny rules |
Control domain access |
Sandbox allowedDomains |
Controls which domains Bash commands can reach |
Sandbox deniedDomains |
Blocks specific domains even when a broader allowedDomains wildcard would otherwise permit them |
Paths from both sandbox.filesystem settings and permission rules are merged together into the final sandbox configuration.
The claude-code repository's examples directory includes starter settings configurations for common deployment scenarios, including sandbox-specific examples. Use these as starting points and adjust them to fit your needs.
/sandbox is not a permission mode. Permission modes decide whether a tool call runs and whether you are prompted first, while the sandbox restricts what a Bash command can access once it runs. They differ in what they control and what replaces the per-action prompt:
| What it controls | What replaces the prompt | |
|---|---|---|
/sandbox |
What a Bash command can access once it runs | The sandbox boundary itself, 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. Protected path checks are also skipped; only removing / or your home directory still prompts |
The sandbox's auto-allow mode is separate from auto mode: auto-allow approves Bash commands because the sandbox boundary contains them, while auto mode uses a classifier to review actions. The two work independently and can be combined. To choose an isolation boundary for unattended runs, see Sandbox environments.
Administrators can require sandboxing for every user, keep developers from widening the policy, and route sandbox traffic through a corporate proxy.
To require the sandbox for every developer, deliver the sandbox keys through managed settings, either as a file managed by your MDM or through server-managed settings on Claude.ai.
The following managed settings configuration enables the sandbox, refuses to start Claude Code if the sandbox cannot initialize, and prevents the model from retrying commands outside the sandbox:
{
"sandbox": {
"enabled": true,
"failIfUnavailable": true,
"allowUnsandboxedCommands": false
}
}The two keys beyond enabled control what happens when the sandbox cannot run a command:
failIfUnavailable: a missing dependency such as bubblewrap on Linux blocks Claude Code from starting rather than showing a warning and falling back to unsandboxed executionallowUnsandboxedCommands: false: thedangerouslyDisableSandboxescape hatch is ignored, so commands that fail under the sandbox cannot be retried outside it
Two additions are worth considering alongside them. Add excludedCommands for any organization-approved tools that must run without isolation. Add denyRead entries for credential directories such as ~/.aws and ~/.ssh, which the default read policy still allows.
The sandbox does not run on native Windows, so if your fleet includes Windows hosts, scope this configuration to macOS and Linux or have those users run Claude Code inside WSL2 or a container.
For boolean keys such as enabled and failIfUnavailable, Claude Code uses the managed value and ignores anything a developer sets locally. For array keys such as excludedCommands and allowRead, Claude Code merges entries from every scope, so a developer can append entries that widen the policy.
Set allowManagedReadPathsOnly to true in managed settings so that only allowRead entries from managed settings are honored. User, project, and local allowRead entries are ignored. This prevents developers from widening read access beyond the organization-approved paths. To lock network domains to the managed values the same way, set allowManagedDomainsOnly.
excludedCommands has no equivalent managed-only lockdown, so a developer can always append entries that run additional commands outside the sandbox. Keep the managed list narrow.
For organizations requiring advanced network security, you can implement a custom proxy to:
- Decrypt and inspect HTTPS traffic
- Apply custom filtering rules
- Log all network requests
- Integrate with existing security infrastructure
To point Claude Code at your proxy, set the proxy ports in sandbox settings:
{
"sandbox": {
"network": {
"httpProxyPort": 8080,
"socksProxyPort": 8081
}
}
}Some commands fail inside the sandbox even though they work outside it. The fixes below cover the most common cases.
- Commands fail with a host-not-allowed error: many CLI tools need to reach specific hosts. Granting permission when prompted adds the host to your allowed list so the tool runs inside the sandbox in future.
jesthangs or fails:watchmanis incompatible with the sandbox. Runjest --no-watchmaninstead.- Go-based CLIs fail TLS verification on macOS: tools such as
gh,gcloud, andterraformmay fail TLS verification under Seatbelt. List these tools inexcludedCommandsto run them outside the sandbox. If you are usinghttpProxyPortwith a MITM proxy and custom CA, setenableWeakerNetworkIsolationtotrueinstead. dockercommands fail:dockeris incompatible with the sandbox. Adddocker *toexcludedCommandsto run it outside the sandbox.- Bubblewrap fails to start inside a container: in an unprivileged container, bubblewrap cannot mount a fresh
/procfilesystem. SetenableWeakerNestedSandboxtotrueso the inner sandbox bind-mounts the container's existing/procinstead. Only use this setting when the outer container already provides the isolation boundary you need, since it exposes process information to sandboxed commands that a fresh/procmount would hide. - Seccomp filter on Linux: the seccomp filter is required to block Unix domain sockets. The Dependencies tab in
/sandboxshows whether it is available. If it is missing, runnpm install -g @anthropic-ai/sandbox-runtimeto install the helper. --dangerously-skip-permissionsfails as root: this flag is blocked when running as root or via sudo on Linux and macOS, because root access combined with no permission prompts can modify any file or service on the system. The check is skipped automatically inside a recognized sandbox. To run autonomously in a container, use the dev container configuration, which runs Claude Code as a non-root user.
Sandboxing reduces risk but is not a complete isolation boundary. Review the limitations below before relying on it as a hard security control.
- Network filtering: the network filtering system operates by restricting the domains that processes are allowed to connect to. The built-in proxy does not terminate or perform TLS inspection on outbound traffic, so the contents of encrypted connections are not examined. You are responsible for ensuring that only trusted domains are allowed in your policy.
- Privilege escalation via Unix sockets: the
allowUnixSocketsconfiguration can inadvertently grant access to powerful system services that could lead to sandbox bypasses. For example, allowing access to/var/run/docker.sockeffectively grants access to the host system through the Docker socket. Consider carefully any Unix sockets that you allow through the sandbox. - Filesystem permission escalation: overly broad filesystem write permissions can enable privilege escalation attacks. Allowing writes to directories containing executables in
$PATH, system configuration directories, or user shell configuration files such as.bashrcor.zshrccan lead to code execution in different security contexts when other users or system processes access these files. - Linux sandbox strength: the Linux implementation provides strong filesystem and network isolation but includes an
enableWeakerNestedSandboxmode that enables it to work inside Docker environments without privileged namespaces, or on Linux hosts where unprivileged user namespaces are disabled by sysctl. This option considerably weakens security and should only be used when additional isolation is otherwise enforced. - Settings files protected: the sandbox automatically denies write access to Claude Code's
settings.jsonfiles at every scope and to the managed settings directory, so a sandboxed command cannot modify its own policy.
- Platform support: supports macOS, Linux, and WSL2. WSL1 and native Windows are not supported.
- Performance overhead: minimal, but some filesystem operations may be slightly slower.
- Tool compatibility: some tools that require specific system access patterns may need configuration adjustments, or may need to be run outside the sandbox.
The sandbox isolates Bash subprocesses. Other tools operate under different boundaries:
- Built-in file tools: Read, Edit, and Write use the permission system directly rather than running through the sandbox. See permissions.
- Computer use: when Claude opens apps and controls your screen, it runs on your actual desktop rather than in an isolated environment. Per-app permission prompts gate each application. See computer use in the CLI or computer use in Desktop.
- Environment variables: sandboxed Bash commands inherit the parent process environment by default, including any credentials set there. To strip Anthropic and cloud provider credentials from subprocesses, set
CLAUDE_CODE_SUBPROCESS_ENV_SCRUB. - Subagents: subagents run in the same process as the parent session and use the same sandbox configuration. Bash commands inside a subagent are sandboxed when sandboxing is enabled in the parent session.
- Sandbox environments: compare the built-in sandbox with dev containers, containers, and VMs
- Security: comprehensive security features and best practices
- Permissions: permission configuration and access control
- Settings: complete configuration reference
- CLI reference: command-line options