文章介绍 Claude Code 2.1.221 在 Linux 和 WSL2 上对凭据文件的 mask 模式,以及 macOS 回退为 deny 的差异。它给出版本锁定、可信配置、域名收窄、代理启用和金丝雀验证等生产上线检查项。
Claude Code 2.1.221 在 Linux 和 WSL2 上为沙箱凭证文件新增了 mode: "mask"。沙箱内的命令读取到的将是包含哨兵值的副本,而不是真实凭证。当命令向允许的目标发送请求时,沙箱代理可以在出站阶段将哨兵值替换为真实值。在 macOS 上,文件遮蔽会回退为拒绝访问,因此命令无法读取凭证文件。
不要把它当成一个打开即可透明生效的开关。请固定使用 2.1.221 或更高版本,将规则放在可信的设置作用域中,使用可随时废弃的凭证,严格限制 injectHosts,启用凭证替换所需的 TLS 终止代理,并确保凭证提取失败时立即终止 canary 测试。只有同时满足以下条件,才能视为通过上线验证:命令从未看到或记录真实值;获准的请求能够成功完成身份认证;所有未经批准的路径均告失败。
在本文发布时,Anthropic 的通用沙箱指南仍声称文件条目仅支持 deny,但带有 2.1.221 标签的版本及其软件包内置设置 schema 已经提供了文件遮蔽功能。文档存在滞后,因此在生产环境上线前,应核实实际安装的具体构建版本和当前生效的 schema。
本指南面向允许 Claude Code 在 Bash 沙箱内运行 gh、npm、云服务 CLI 或内部 API 客户端的开发者和平台团队。当命令需要经过身份认证的访问权限,但又不能让 Agent 获得底层 token 时,本指南尤其有用。
凭证遮蔽是严格网络 allowlist 检查清单的补充。allowlist 控制沙箱命令能够连接到哪里;遮蔽则控制命令是否持有真实凭证。对于文件系统和会话边界,仍应保留更全面的沙箱与 worktree 回归检查。
在 2.1.221 之前,Claude Code 的文档给出了两种实用的凭证处理路径:完全拒绝访问凭证文件,或者遮蔽环境变量并由代理注入其真实值。新版本将“哨兵值加代理”的模式扩展到了 Linux 和 WSL2 上的文件。
2.1.221 软件包内置的 schema 将 extract 描述为一个全局正则表达式,其中捕获组 1 用于识别每个凭证值。如果没有配置 extract,整个文件将被替换成一个哨兵值。它还提供了 onExtractNoMatch、maskDuplicates 和 injectHosts 控制项。
遮蔽功能不会让一个获准访问的主机自动变得安全,不会检查请求的语义,不会限制 MCP 工具,也无法保护 Claude 的内置文件工具。它只适用于沙箱内运行的命令。对于会产生重要后果的操作,仍应使用最小权限 token、仓库规则、确定性测试和人工审批。
记录准确的 Claude Code 版本、安装渠道、操作系统、WSL 版本(如适用)以及设置来源。升级后应重启长期运行的会话。不要根据 package lock 或另一个终端推断当前生效的版本。
创建一个只能访问无害 canary 端点、并且能够立即撤销的 token。使用一个明确的文件路径,不要使用目录。绝对不要使用开发者的 GitHub、npm、云服务或生产环境凭证进行测试。
只有当文件中仅包含一个凭证,而且客户端能够接受这种文件结构时,才使用整文件遮蔽。对于 .netrc、JSON、YAML 或键值格式的文件,应使用 extract,以便客户端仍然能够看到有效的语法结构。捕获组 1 中只能包含 secret。
在 canary 测试中,将 onExtractNoMatch 设置为 error。软件包内置 schema 表明,默认的 warn 行为可能导致未匹配的文件在沙箱内仍然可读。文件格式发生变化时,必须阻止沙箱启动,而不是悄无声息地暴露原始文件。只有对于较长且高熵的值,才应使用 maskDuplicates,因为替换反复出现的短文本可能会破坏无关字段。
{
"sandbox": {
"enabled": true,
"failIfUnavailable": true,
"network": {
"tlsTerminate": {},
"allowedDomains": ["api.example.test"]
},
"credentials": {
"files": [
{
"path": "~/.config/example/credentials",
"mode": "mask",
"extract": "token\\s*=\\s*([A-Za-z0-9_-]+)",
"onExtractNoMatch": "error",
"maskDuplicates": true,
"injectHosts": ["api.example.test"]
}
]
}
}
}
请将示例主机和匹配模式替换为你能够控制的 canary。凭证注入规则应保存在用户设置、托管设置或显式 CLI 设置中,不要放在由仓库控制的文件里。
injectHosts 中的每个条目都必须能够通过 network.allowedDomains 访问。优先指定准确的 API hostname,而不是宽泛的通配符。凭证替换要求代理能够看到请求内容,因此需要配置 network.tlsTerminate;如果没有配置,哨兵值应原封不动地到达服务器,并导致身份认证失败。
使用你能够控制的接收端,并且只保留经过脱敏的证据:
在沙箱内读取文件时,能够看到有效的结构和哨兵值,但绝不能看到可废弃 token。
日志、trace、进程参数和错误信息中均不包含可废弃 token。
发往指定获准主机的请求能够通过代理替换完成身份认证。
将同一个请求发送到其他主机时,目标不能收到真实 token。
修改文件,使 extract 无法匹配任何内容;沙箱初始化必须终止。
在所有受支持的执行环境中重复测试。在 macOS 上必须拒绝访问该文件,不能伪装成遮蔽功能正常工作。
先从一个非生产工作流开始。如果无法证明构建版本、平台、TLS 代理、schema 或脱敏证据符合预期,请将文件条目切换为 deny,并通过权限范围严格受限的 MCP/自定义工具,或者外部凭证注入代理来执行需要身份认证的操作。不可信仓库的沙箱检查清单仍然是最外围的安全边界。
canary 的意义在于:即使日志、正则表达式或代理规则出现错误,测试仍然是安全的。
凭证文件的格式会发生变化。必须让提取不匹配的情况阻止上线。
遮蔽限制的是谁持有 token,而不是经过身份认证的请求能够执行什么操作。主机范围和 token 权限范围都必须严格限制。
2.1.221 版本明确规定,在 macOS 上会回退为 deny。因此,在 macOS 上身份认证失败是预期行为,并不能证明凭证替换已经生效。
当配置的文件、代理和主机路径都按预期工作时,它可以防止沙箱内的 Bash 命令获得真实值。但它不覆盖内置工具、MCP server、其他未在沙箱中运行的进程,也不保护存放在未列出位置的凭证。
deny 规则?不应该。当命令不需要凭证时,应继续使用 deny。只有对于通过了哨兵值、提取、出站连接、TLS、日志和回滚检查的身份认证工作流,才使用 mask。
如需采取进一步措施,你可以考虑屏蔽此人和/或举报滥用行为。