沙箱
用沙箱化的 Bash 工具获得文件系统和网络隔离:启用、两种模式、配置文件系统路径、工作原理与限制。
Bash 沙箱让 Claude 无需停下来请求权限就能运行大多数 shell 命令。你不再逐个批准命令,而是定义命令能触碰哪些文件和网络域名,然后由操作系统对每个 Bash、PowerShell 或 Monitor 命令及其子进程强制执行这个边界。
想比较其他隔离方式(dev container、自定义容器、虚拟机),见官方的 Sandbox environments;想减少 Bash 之外其他工具的权限提示,见权限模式。
开始使用
沙箱内置于 Claude Code,运行在 macOS、Linux 和 WSL2 上,不支持原生 Windows(在 Windows 上,请在 WSL2 发行版里运行 Claude Code)。macOS 上无需安装任何东西:沙箱使用内置的 Seatbelt 框架。Linux 和 WSL2 上,沙箱依赖两个包:
bubblewrap:强制文件系统隔离的无特权沙箱工具socat:用于把网络流量路由经过沙箱代理的中继
用发行版的包管理器安装:
sudo apt-get install bubblewrap socat
# 或
sudo dnf install bubblewrap socat步骤:
- 启动 Claude Code 会话并运行
/sandbox。它会打开沙箱面板,有三个标签页:Mode(选择沙箱化命令如何被批准)、Overrides(选择在沙箱下失败的命令能否回退到非沙箱运行,即allowUnsandboxedCommands设置)、Config(查看解析后的沙箱设置)。如果面板只显示 Dependencies 标签页,说明缺少必需的包,安装后重启 Claude Code 再运行/sandbox - 在 Mode 标签页选 auto-allow 或 regular permissions
- 让 Claude 运行一条命令,比如构建或测试套件。默认情况下,沙箱内的命令可以写入工作目录、每用户临时目录和你添加的目录;命令第一次需要新的网络域名时,Claude Code 会提示批准
- 无法在沙箱里运行的命令回退到常规权限流程,其权限提示的标题是「Bash command (unsandboxed)」而不是「Bash command」,这样你能分辨哪些命令在沙箱之外运行
你在面板里选定模式后,Claude Code 会把它保存到项目的本地设置 .claude/settings.local.json。想不写设置文件、只为一个会话改变沙箱,用 --settings 启动,例如启动一个 Claude 无法在沙箱之外重试被阻止命令的会话:
claude --settings '{"sandbox": {"enabled": true, "allowUnsandboxedCommands": false}}'默认情况下,如果沙箱因缺少依赖或平台不受支持而无法启动,Claude Code 显示警告并在没有沙箱的情况下运行命令;想让它变成硬性失败,设置
sandbox.failIfUnavailable。
沙箱模式
两种模式下沙箱强制执行相同的文件系统和网络限制,区别只是沙箱化的命令是被自动批准,还是需要显式许可。
Auto-allow 模式:命令可以被沙箱化时,Claude Code 在沙箱内运行并自动批准,无需询问你。无法沙箱化的命令(如需要访问非允许主机的网络)回退到常规权限流程。即使在这个模式下,以下仍然适用:显式 deny 规则始终被遵守;针对关键路径的 rm 或 rmdir 仍走常规权限流程;内容限定的 ask 规则(如 Bash(git push *))即使对沙箱化命令仍强制提示。
Regular permissions 模式:所有 Bash 命令都走常规权限流程,即使被沙箱化。这提供更多控制,但需要更多批准。
未沙箱重试的逃生口:有些命令根本无法在沙箱里运行,比如与沙箱不兼容的工具,或需要你没允许的主机。Claude Code 在被阻止命令的结果里报告沙箱违规,指出沙箱拒绝的路径或主机,Claude 会看到沙箱挡住了什么,并可以用 dangerouslyDisableSandbox 参数在沙箱之外重试。重试的命令走常规权限流程:Manual 模式下你会得到确认提示。你可以在沙箱设置里设置 "allowUnsandboxedCommands": false 禁用这个逃生口,这样每个命令都必须沙箱运行。注意严格沙箱模式只适用于 Claude 运行的命令;你在 ! shell 模式提示里自己输入的命令在沙箱之外运行(后台会话除外)。
临时目录:每用户临时目录默认和工作目录一起可在沙箱内写入。除非禁用文件系统隔离,Claude Code 会为沙箱化命令把 $TMPDIR 设为该目录。
配置沙箱
通过 settings.json 定制沙箱行为。默认情况下,沙箱化命令可以写入当前工作目录、每用户临时目录,以及用 --add-dir、/add-dir 或 permissions.additionalDirectories 添加的目录。如果子进程需要写这些位置之外的路径,用 sandbox.filesystem.allowWrite 添加:
{
"sandbox": {
"enabled": true,
"filesystem": {
"allowWrite": ["~/.kube", "/tmp/build"]
}
}
}这些路径在 OS 级别强制执行,所以沙箱内运行的所有命令(包括子进程)都遵守它们。当某个工具需要对特定位置的写权限时,推荐这种做法,而不是用 excludedCommands 把工具完全排除在沙箱之外。同一个文件系统数组在多个设置范围里定义时,Claude Code 会合并它们,而不是用一个范围的数组替换另一个。会话期间编辑这些列表,Claude Code 会把改动应用到运行中的会话。
路径前缀如何解析:
| 前缀 | 含义 | 示例 |
|---|---|---|
/ | 从文件系统根开始的绝对路径 | /tmp/build 保持为 /tmp/build |
~/ | 相对于家目录 | ~/.kube 变成 $HOME/.kube |
./ 或无前缀 | 项目设置里相对于项目根,用户设置里相对于 ~/.claude | .claude/settings.json 里的 ./output 解析为 <project-root>/output |
这个语法不同于 Read 和 Edit 权限规则(后者用 //path 表示绝对路径、/path 表示项目相对路径),沙箱文件系统路径采用标准约定。你也可以用 sandbox.filesystem.denyWrite 和 sandbox.filesystem.denyRead 拒绝写或读访问,用 sandbox.filesystem.allowRead 在被拒绝区域内重新允许特定路径;读规则重叠时,路径更窄的规则生效。下面的例子阻止读取整个家目录,同时仍允许读取当前项目(放在项目的 .claude/settings.json 里,因为相对路径 . 只有当配置在项目设置里时才解析为项目根):
{
"sandbox": {
"enabled": true,
"filesystem": {
"denyRead": ["~/"],
"allowRead": ["."]
}
}
}想在保留工作目录可读的同时拒绝沙箱化命令读取家目录和挂载卷,设置 permissions.blockReadsOutsideWorkingDirectories,而不是自己写路径规则。把 sandbox.filesystem.disabled 设为 true 可以跳过文件系统隔离但保留网络隔离。
沙箱如何工作
文件系统隔离
沙箱化的 Bash 工具把文件系统访问限制在特定目录:
- 默认写行为:对当前工作目录及其子目录、你添加的目录、再加上每用户临时目录有读写权限
- 默认读行为:对整台电脑有读权限,除了某些被拒绝的目录。注意这个默认仍然允许读取
~/.aws/credentials和~/.ssh/这样的凭据文件;用sandbox.credentials阻止读取这些文件 - 被阻止的访问:没有显式权限,不能修改工作目录、添加的目录和每用户临时目录之外的文件,包括
~/.bashrc这样的 shell 配置文件和/bin/里的系统二进制文件 - Git worktree:当工作目录是链接的 git worktree 时,沙箱还允许写入主仓库共享的
.git目录,让git commit这类命令能更新引用和索引(其中的hooks/和config仍受保护)
受保护路径
在沙箱化命令可写的目录内,沙箱仍然拒绝写入 Claude Code 从中加载配置和代码的文件。能编辑这些文件的命令可以授予自己权限,或添加 Claude Code 在沙箱之外运行的 Hook 或 MCP 服务器。受保护的有:工作目录及其上级目录里的 .claude 设置文件、.claude/skills、.claude/agents、.claude/commands、.claude/hooks 目录和 .mcp.json;仅工作目录里的 shell 启动文件(.bashrc、.zshrc)、.gitconfig、.vscode 和 .idea 目录,以及 .git 里的 hooks 和 config;~/.claude(或 CLAUDE_CONFIG_DIR 指向的目录)里的大部分内容,加上 ~/.claude.json 和 .credentials.json 凭据存储。没有办法豁免这些路径之一:allowWrite 条目或覆盖该路径的 Edit allow 规则不会解除保护。
网络隔离
网络访问通过运行在沙箱之外的代理服务器控制:
- 域名限制:Claude Code 默认不预先允许任何域名。命令第一次需要新域名时,Claude Code 会提示批准
- 批准选择:选 Yes,Claude Code 在当前会话的剩余时间里允许该主机,不再为之后对同一主机的连接提示;选「Yes, and don't ask again」会把
WebFetch(domain:...)allow 规则保存到你的本地设置 - 预先允许域名:用
allowedDomains预先允许域名以完全避免提示 - 严格白名单:在用户、托管或 CLI
--settings设置里把strictAllowlist设为true,Claude Code 会拒绝沙箱化命令访问白名单之外的任何主机,而不是提示 - 托管锁定:托管设置里设置
allowManagedDomainsOnly,未允许的域名被自动阻止而不是提示 - 企业代理:当网络要求出站流量经过企业代理时,在设置的
env块里设置HTTPS_PROXY、HTTP_PROXY和NO_PROXY - 全面覆盖:限制适用于命令派生的所有脚本、程序和子进程
内置代理根据请求的主机名强制执行白名单,默认不终止或检查 TLS 流量。
限制
沙箱降低风险,但不是完整的隔离边界。依赖它作为硬性安全控制之前,请审阅这些限制:
- 网络过滤:沙箱限制进程能连接哪些域名,但默认不检查加密连接的内容。允许
github.com这类宽泛的域名可能产生数据外泄路径(代理基于客户端提供的主机名做决定,沙箱内运行的代码可能利用域前置绕过过滤) - 通过 Unix socket 提权:
allowUnixSockets配置可能无意中授予对系统服务的访问,导致沙箱绕过。例如允许访问/var/run/docker.sock实际上授予了通过 Docker socket 访问主机系统的权限 - 文件系统权限升级:过于宽泛的文件系统写权限可能导致提权攻击。允许写入包含
$PATH里可执行文件的目录、系统配置目录或用户 shell 配置文件(如.bashrc、.zshrc)都可能带来风险 - Linux 沙箱强度:Linux 实现提供强的文件系统和网络隔离,但包含一个
enableWeakerNestedSandbox模式,让它能在没有特权命名空间的 Docker 环境里工作,会大大削弱安全性 - macOS 的 Apple Events:macOS 沙箱默认阻止 Apple Events;
allowAppleEvents设置解除限制,让open、osascript这类工具能工作,但会移除代码执行隔离
平台:支持 macOS、Linux 和 WSL2;不支持 WSL1 和原生 Windows。范围:沙箱隔离 Bash 子进程,其他工具在不同边界下运行:内置文件工具(Read、Edit、Write)直接使用权限系统而不经过沙箱;computer use 在你真实的桌面上运行;沙箱化的 Bash 命令默认继承父进程环境(包括其中设置的任何凭据),可以用 sandbox.credentials 取消设置或遮蔽特定变量;子智能体与父会话在同一进程里运行并使用相同的沙箱配置。
有效的沙箱需要同时有文件系统隔离和网络隔离。没有网络隔离,被攻陷的智能体可能外泄 SSH 密钥等敏感文件;没有文件系统隔离,则可能逃出沙箱并获得网络访问。
与权限的关系
沙箱和权限互补:权限控制 Claude Code 能使用哪些工具、访问哪些文件或域名,沙箱提供 OS 级强制。两者一起用提供纵深防御,两处来源的路径和域名会合并进最终的沙箱配置。