介绍如何通过代理机制保护在 Claude Code 中的 API 密钥和敏感数据。直接可用的安全最佳实践,对所有用户 AI 工具的程序员有即时参考价值。
Agentic 编码工具的沙箱,本质上是一个网络问题。
在可信主机上为 Agentic 编码工具设置命令允许列表,可能会带来不小的风险。借用 Simon Willison 的思路:
沙箱有助于我们从「致命三要素」的角度分析它们:
Anthropic 提供了几种专用于 Claude Code 的沙箱工具:
sandbox-exec。这与 Chromium 使用的技术相同。sandbox-exec。Cursor 也为 Mac 用户提供了类似的沙箱功能,Cursor IDE 底层同样使用 sandbox-exec。OpenAI 的 Codex CLI 也支持使用 sandbox-exec 的 sandbox 参数。看到这么多新工具开始限制 Agentic 编码工具对宿主机的访问权限,我们感到非常兴奋!
你也可以使用 gVisor 或 Firecracker VM 编写自己的沙箱!围绕网络隔离和代理展开的思路同样适用。
尽管具体采用的沙箱技术会影响隔离级别,但一个隔离充分的 Claude Code 沙箱,可以让其中的 Claude Code 看起来就像运行在一台独立主机上一样。
例如,几乎所有 Claude Code 实例都能访问 Anthropic API key,以便与 Anthropic API 交互。
Claude Code 可以访问当前终端会话中的所有环境变量,这些变量会继续传递给 Claude Code 沙箱;Claude Code 也可以读取你运行 claude 时所在目录中的文件。
遗憾的是,许多软件都需要 secret。例如,开发第三方集成功能时就需要使用 secret。
因此,为开发、预发布和生产环境分别设置集成凭据尤其重要。不过,即使是开发环境的集成凭据,也不是为了公开访问而设计的——否则它们就不能算凭据了!
请考虑本地代码仓库中用于管理 secret 的 dotenv 文件及其优先级。确保这些 .env 文件已正确加入 .gitignore 和 .dockerignore 已经不够了:只要把这些 .env 文件留在运行 claude 的目录里,Claude Code 就能够访问其中的 secret。
你也可以使用 gVisor 或 Firecracker VM 编写自己的沙箱!围绕网络隔离和代理展开的思路同样适用。
官方提供的 devcontainer 模板中包含一个 init-firewall.sh 脚本,它会为运行 Claude Code 的 devcontainer 配置防火墙。默认情况下,该防火墙允许连接以下主机:
registry.npmjs.org:允许安装 npm packageapi.anthropic.com:与 Anthropic API 交互sentry.io:Anthropic 使用的日志与错误可观测性产品statsig.anthropic.com/statsig.com:Anthropic 使用的 feature flag 产品marketplace.visualstudio.com:允许安装 VSCode extensionvscode.blob.core.windows.net/update.code.visualstudio.com:VSCode 使用的 blob store这个防火墙在 IP 层执行限制:初始化脚本通过 dig 解析这些主机的 IP 地址,然后使用 iptables 允许连接这些 IP。这意味着,对这些主机的具体连接并不一定会在 TLS/HTTP 层得到约束。例如,如果允许列表中的某个 IP 对应一台 AWS ALB,并且它会根据 SNI 或 Host header 路由流量,那么它仍然可能收到指定了其他主机的请求。
此外,为支持 SSH 连接,该防火墙允许通过 22 端口与任意 IP 地址进行入站和出站通信。
假设我们执行以下操作:
claude –dangerouslyUnsafePermissions 运行 devcontainer。devcontainer 可以通过多种方式泄露敏感数据,包括凭据:
即使我们只允许向少数几个主机发送 HTTP 流量,这个问题依然很棘手,因为存在 Domain Fronting:在同一个域名上,往往可以执行种类繁多的操作。在 IP、域名甚至 host 层面对这类域名应用受限权限,通常都不够细粒度,无法做到既允许你希望放行的操作,又阻止你希望拦截的操作。事实上,prompt injection 攻击尤其擅长利用过于宽泛的域名允许列表来泄露敏感信息!
要确定允许和禁止哪些网络流量,通常需要深入到应用层进行判断。
好在 Claude Code 支持通过代理路由流量!可以通过两种方式配置 Claude Code 使用代理:
HTTP_PROXY 环境变量,让它应用于 Claude Code 的所有 HTTP 流量。这个代理环境变量会拦截 Claude Code 父进程发出的 HTTP 流量。httpProxyPort。它会拦截沙箱内执行的 Bash 命令所产生的 HTTP 代理流量。需要注意的是,这两项代理配置彼此独立:HTTP_PROXY 环境变量不会拦截沙箱内 Bash 命令发出的 HTTP 流量,而 sandbox 的 httpProxyPort 也不会拦截沙箱外 Claude Code CLI 工具发出的 HTTP 流量。
你可以在 settings.json 中通过以下配置,让 Claude Code 使用 HTTP 代理:
mitmproxy 是运行这些 HTTP 代理的优秀工具。注意:要拦截 Node 进程发往 Claude 的 TLS 流量,需要通过 export NODE_EXTRA_CA_CERTS=~/mitmproxy/mitmproxy-ca-cert.pem 向 Node 提供由 mitmproxy 生成的 TLS certificate。
mitmproxy 工具还支持 addon,可用于转换 Claude Code 与第三方 Web 服务器之间的 HTTP 请求。例如,你可以编写一个 addon,拦截 https://api.anthropic.com,并使用真实的 Anthropic API Key 更新 X-API-Key header。
接着,你可以向 Claude Code 传入一个无效的 Anthropic API Key。这样一来,无论 Claude Code 进程还是沙箱,都无法接触到我们真实的 Anthropic API Key!
然后,你可以使用正确的 API key 运行 mitmweb:
之后,将 ANTHROPIC_API_KEY 环境变量设置为无效的 API key,再运行 claude:
从 Claude Code 的视角来看,api.anthropic.com 返回的所有 API 响应,都会让 Claude Code 认为 sk-ant-dummy 是一个有效的 API key!
遗憾的是,Claude Code 仍然要求先通过 OAuth 登录,之后才会检查是否设置了 ANTHROPIC_API_KEY。因此,你可能需要先通过 OAuth 登录,获取 API key,关闭该会话,然后再启动一个新的 claude 进程,并为它设置无效的 ANTHROPIC_API_KEY 环境变量。
这项技术并不只能用来隐藏 Anthropic API Key:你可以填入假的 API key 和 secret,再使用 mitmproxy addon 拦截相应的 HTTP 请求,等请求离开 Claude Code 进程和沙箱后,再注入真实的 API key。
我们的客户使用 Formal 对人类身份和机器身份实施最小权限原则。你也可以利用 Formal,将人类身份和机器身份与 Native Users 解耦,并在应用层实施细粒度的最小权限控制。组织实施最小权限原则时使用的许多技术,同样适用于 Claude Code 沙箱:如果组织权限受到足够严格的约束,那么即使 Claude Code 失控并持有开发者凭据,其爆炸半径也应该很小。
截至目前,Admin Anthropic API Key 会继承创建者的全部权限,而且无法进一步细化 API key 的权限。相比之下,通过 Claude API 为 Claude Code 生成的 API key,似乎会受到可访问 API endpoint 范围的限制,但我们尚未找到准确说明哪些权限已启用、哪些权限已禁用的文档。
开发者可能希望使用 Claude Code 编写和运行使用 Admin Anthropic API Key 的代码。如果通过环境变量传入 API Key,沙箱就可以访问这个 Admin Anthropic API Key。不过,组织可能希望阻止 Anthropic API Key 执行某些 API 操作,同时记录是谁执行了哪些 API 操作。开发者自己甚至可能察觉不到其中的差别!
防止 Claude Code 泄露 API Key 的最佳方式,是从一开始就确保它永远无法直接访问凭据!你可以使用 Formal Connectors、Formal Resources 和 Native Users,确保 Claude Code 无法泄露 API Key。这样,Claude Code 可以使用 Formal 专用凭据向 Connector 发出请求,再由 Connector 在与上游 API 通信时注入真实的 secret。
对于难以调整的 hostname 和 header,可以使用 mitmproxy addon,将这些域名的 HTTP 请求路由到对应的 listener。
随后,你可以通过 mitmproxy -s reroute_hosts.py 加载这个 addon。
这种方式的优势之一,是不必为 Claude Code 配置 hostname 和端口:从 Claude Code 的视角来看,这些 API 的默认 hostname 和端口完全没有变化。
我们可以采用与本地 GitHub MCP server 用例中类似的方式创建 policy。
如果把 path param 改为 “/v1/messages,”,就能确认这项 policy 即使在 Claude Code 沙箱之外,也可以拦截对 Anthropic API 的请求:
同时,我们还能看到整个组织向 Anthropic API 发出的每一个请求!
当然,这项技术并不只适用于保护 Anthropic API Key:即使你希望允许 Claude Code 使用其中一部分 API,也可以结合 HTTP 代理和 Claude Code 沙箱,对 API Key 实施最小权限控制!
因此,代理可以从两个方面缓解「致命三要素」带来的风险: