浅度学习一下 Claude Code 的 Sandbox

AI工程2026-05-189 分钟aiclaude-codemacossandboxsecurity

许多编码 Agent 都能读文件、改代码、搜索项目、运行测试,甚至执行 shell 命令。

这也是很多人第一次使用它时会有不安的地方:

它能操作 shell,能修改我的本地文件,那它是不是可以在我电脑上为所欲为?

这个问题不能简单回答“是”或“不是”,这里以 Claude Code 为例稍微研究一下。

结论:Claude Code 确实具备操作本地环境的能力,但它也有一套安全边界来约束这些能力。这个边界主要由 权限系统、用户确认、内置工具、Bash sandbox、diff 审查 组成。

这篇文章讨论的范围:macOS 下 Claude Code 原生 sandbox 和权限机制的大致工作方式


一、为什么 Claude Code 需要 sandbox

Claude Code 不是一个普通聊天窗口,它是一个可以执行工程任务的 Agent。

当你让它“帮我修复登录按钮不生效的问题,并跑一下测试”时,它可能会搜索代码、读取文件、修改组件、执行 npm test,再根据结果继续修复。

这套能力非常有用,但也带来一个问题:只要一个工具能代表你在本机执行操作,它就必须有边界。

对 Agent 来说,风险不只是“删文件”。更常见也更隐蔽的风险包括:读取 .env、SSH key、云厂商 credentials;执行联网命令;修改 package.json scripts、CI、部署脚本;批量修改或删除文件;执行你没有仔细看过的脚本。

所以 Claude Code 需要 sandbox,不是因为它“不可信”,而是因为它真的有行动能力。


二、claude 命令和 bash 的区别

理解 Claude Code sandbox 之前,先要纠正一个常见误解:

claude 不是 bash
Claude Code 是一个 CLI Agent 程序
bash 只是 Claude Code 可以调用的工具之一

你在终端里输入:

claude

进入的不是一个增强版 bash,而是 Claude Code 的交互界面。它背后大概可以这样理解:

用户
 ↓
Claude Code CLI
 ├─ 模型交互
 ├─ 权限判断
 ├─ Read / Edit / Grep / Glob 等内置工具
 └─ Bash 工具
      ↓
    受限或需审批的 shell 命令

Claude Code 本身是一个 Agent Runtime。模型负责理解目标,Claude Code Runtime 负责把下一步翻译成具体工具调用,比如读文件、改文件、搜索代码、执行 Bash 命令。

这里的 Read、Edit、Grep、Glob 可以理解成“参数明确的内置工具”:读哪个文件、改哪个文件、搜什么内容,都能被 Claude Code 用明确参数表达出来。Bash 则是通用 shell 工具,能力更大,风险也更高。

Claude Code 不是“一个会聊天的 bash”,而是“一个能调用 bash 的 Agent Runtime”。


三、普通 bash 的风险来自哪里

普通 bash 的风险不在于 bash 自己有多神秘,而在于它继承了当前用户的系统权限。

例如:

cat ~/.ssh/id_rsa
rm -rf src
curl https://example.com

这些命令看起来是 bash 在执行,但真正读文件、删文件、联网的是操作系统。普通终端里的 bash 通常拥有当前用户的大量权限,所以它能读项目目录,也可能能读 home 目录、配置文件、凭证文件。

如果 Agent 不加限制地调用普通 bash,风险就会被放大。因为 Agent 可能在多轮任务中自动生成命令、自动运行命令;一旦命令里混入高风险操作,或者项目脚本本身被污染,就可能出问题。

所以安全边界不能只依赖“模型应该不会这么做”。


四、macOS 原生 sandbox 如何限制 Bash

Claude Code 的 macOS sandbox,核心作用是限制 Bash 工具及其子进程的文件和网络访问。

在 macOS 上,这类限制基于系统级的 Seatbelt sandbox 机制。可以简单理解为:Claude Code 在执行某些 Bash 命令时,不是直接启动一个拥有完整用户权限的普通 shell,而是把这个 shell 放进一个受限环境。

结构可以简化成:

Claude Code
  ↓
权限判断 / sandbox 策略判断
  ↓
macOS Seatbelt sandbox
  ↓
bash -lc "npm test"
  ↓
npm / node / 子进程

这和“让模型自觉不要乱来”不是一回事。模型可以提出动作,但真正约束 Bash 的,是操作系统层面的 sandbox。即使 npm test 里启动了 node 脚本、测试框架、子进程,这些子进程也会受到同一套边界影响。

所以关键不是“bash 看起来是不是 bash”,而是“这个 bash 被放在了什么边界里”。


五、sandbox 和权限系统分别管什么

Claude Code 的安全边界不是只靠 sandbox。

更准确地说,它至少有几层:

权限系统:判断工具、路径、命令、域名该不该访问
sandbox:限制 Bash 及其子进程的文件和网络访问
用户确认:决定高风险操作是否继续
diff 审查:确认最终改动是否可接受

这里最容易误解的是:sandbox 主要约束 Bash

Read、Edit、Write 这类内置文件工具,不是通过 Bash sandbox 运行的,它们主要依赖 Claude Code 的权限系统来约束。Bash 工具则会同时受到权限系统和 sandbox 的影响。

可以用一个公式记住:

允许执行 ≠ 一定执行成功
执行成功 = 应用层允许 + OS 层允许 + 用户没有拒绝

sandbox 本身也不是一个“打开之后所有事情都安全”的万能开关。它还涉及:

  • sandbox 内的命令是否自动允许;
  • sandbox 内的命令是否仍需确认;
  • 命令无法在 sandbox 中运行时,是否允许回退到普通权限流程。

官方文档中的 Auto-allow / Regular permissions,以及 autoAllowBashIfSandboxedallowUnsandboxedCommands,都可以放在这个框架里理解。

其中最需要谨慎的是非 sandbox 回退:一旦你允许命令脱离 sandbox,它就不再受同一套 OS 级边界限制,而是回到更接近普通终端的执行方式。

权限系统是事前审批,sandbox 是底层兜底。两者应该一起用,但都不能替代人的判断和审查。


六、如何配置 Claude Code 权限

Claude Code 的权限配置,主要解决一个问题:

哪些工具、命令、路径、域名,可以被 Claude Code 使用?

配置通常会有不同层级,比如用户级、项目级、本地级,以及组织统一管控的托管配置。

权限规则大概可以这样理解:

{
  "permissions": {
    "allow": [
      "Bash(npm test*)",
      "Bash(npm run lint)",
      "Read(src/**)",
      "Edit(src/**)"
    ],
    "deny": [
      "Read(.env)",
      "Read(**/secrets/**)",
      "Bash(curl*)",
      "Bash(rm -rf*)"
    ]
  }
}

这段不是为了让你直接复制,而是表达一个思路:

  • 低风险、高频命令可以 allow;
  • 敏感路径和危险命令应该 deny;
  • 范围过宽的 Bash 规则要谨慎。

尤其是 Bash 规则,不能只看命令开头。例如:

Bash(npm *)

看起来只是允许 npm,但它可能覆盖很多行为:安装依赖、运行任意 script、执行带生命周期脚本的操作。对团队项目或不熟悉的仓库,这个范围通常太宽。

更好的做法是把高频低风险命令单独列出来:

Bash(npm test*)
Bash(npm run lint)
Bash(npm run build)

七、内置工具和 Bash 工具有什么区别

内置工具和 Bash 的区别可以简单理解为:

Read / Edit / Grep / Glob:内置工具,参数明确,便于权限判断
Bash:通用 shell 工具

常见操作可以这样分:

操作优先方式
读一个明确文件Read
修改一个明确文件Edit / Patch
搜索代码Grep / Glob
跑测试 / 构建 / npm scriptBash
查看 git diffBash

内置工具的行为更明确,权限判断也更直接;Bash 更通用,但一条 shell 命令可能读文件、写文件、联网、启动子进程,所以需要更严格的边界。


八、一次真实操作的安全链路

把前面串起来看,一个真实任务大概是这样。用户说:

帮我修复登录按钮不生效的问题,并跑一下测试。

Claude Code 可能会这样做:

1. Grep 搜索 LoginButton
2. Read 读取相关文件
3. Edit 修改代码
4. Bash 执行 npm test
5. 根据测试结果继续修复
6. 展示最终 diff 和总结

对应的安全链路是:

用户请求
 ↓
模型决定下一步动作
 ↓
Claude Code 判断工具和权限
 ↓
必要时询问用户
 ↓
Read / Edit / Grep 等内置工具按权限执行
 ↓
Bash 命令进入 sandbox 或普通权限流程
 ↓
OS 限制文件和网络访问
 ↓
结果返回给模型
 ↓
用户审查 diff / 测试结果

这里面任何一层都不是万能的,但多层机制叠在一起,就比“让模型直接跑普通 bash”安全得多。


九、哪些操作需要特别小心

使用 Claude Code 时,有几类操作要格外注意。

1. 读取敏感文件

.env
.ssh
.npmrc
~/.aws/credentials
secrets
credentials

这些文件里可能有 API key、数据库密码、部署 token、云厂商凭证,建议放进 deny 规则里。

2. 执行联网命令

curl
wget
git clone
npm install
pnpm install

联网本身不是坏事,但它意味着本地环境和外部世界发生了交互。尤其是 npm installpnpm install,除了下载依赖,还可能触发安装脚本。

3. 修改执行链路

package.json scripts
.github/workflows
Dockerfile
Makefile
husky hooks
部署脚本

这些文件会影响“未来执行什么”。比如 npm test 看起来只是跑测试,但真实执行内容取决于 package.json scripts

4. 删除或批量修改文件

rm -rf
find ... -delete
sed -i
批量替换脚本

这类操作不是不能做,而是要明确范围。“删掉 dist 目录”和“删掉当前目录下所有匹配文件”,风险完全不同。


十、如何更安全地使用 Claude Code

更安全使用 Claude Code,可以记住这几条:

  1. 新项目先让它解释计划,不要一上来大范围修改。
  2. .env.ssh.npmrc、credentials、secrets 默认 deny。
  3. curlwget、未知安装命令只允许一次,不要永久 allow。
  4. 执行 npm testnpm run build 前先看 package.json scripts
  5. 修改 package.json、CI、部署脚本、hooks 时认真看 diff。
  6. 保持 Git 工作区干净,方便比较和回滚。
  7. 团队项目维护项目级权限配置,避免每个人随手点 allow。

十一、总结

Claude Code 不是普通 bash,它是一个 Agent Runtime。

可以这样总结它的安全链路:

模型负责提出动作;
Claude Code 权限系统负责判断动作能不能做;
内置工具负责结构化读写代码;
Bash 工具负责执行项目命令;
macOS Seatbelt sandbox 负责限制 Bash 和子进程不能越界;
用户通过配置、确认和 diff 审查控制最终边界。

Claude Code 的安全性不是建立在“大模型足够听话”上,而是建立在一套受控工具、权限配置和 macOS sandbox 约束之中。

Agent 越有行动能力,就越需要清晰边界。边界不是为了限制效率,而是为了让自动化可以被放心使用。