指南将代理风险拆解为不可信输入、可访问的敏感数据和可执行操作三个要素,说明提示注入与误操作如何造成损失。通过权限规则和操作检查点缩小影响范围,并解释各层防护的边界。
Claude Code 能读取你的代码仓库、编辑文件、运行 shell 命令,还能调用 MCP server。这些能力正是它有用的原因,也意味着你应该像对待持有生产环境凭据的 CI runner 一样,认真做好它的安全防护。本指南汇总了适合日常工作的 Claude Code 安全最佳实践:该配置什么、每项设置为什么重要,以及每一层防护的边界在哪里。
简而言之:假设 Agent 迟早会读到恶意内容,可能是 README、issue、网页,也可能是工具返回的结果。你要确保,即便这种情况发生,它能造成的损害也很有限。
大多数实际风险,来自同一个会话中三种因素的碰头:模型读取的不可信内容、它能够接触到的敏感材料(.env、~/.aws、SSH 密钥、MCP 配置中的 token),以及它采取行动的通道(shell、网络、git push,或能向某处写入内容的 MCP 工具)。Prompt injection 是常见的触发因素,但无心之失也会造成同样的损害,例如变量为空时执行清理命令,或者信心满满地运行 git reset --hard。下面的每项实践,都是为了移除这三个因素中的一个,或在它们之间设置一道检查关卡。
Claude Code 从 JSON 设置文件中读取权限规则。规则分为三类:allow、ask 和 deny,每条规则都指定一个工具,以及它可以执行的操作。你可以在 ~/.claude/settings.json 或项目的 .claude/settings.json 中,先采用下面这组配置:
{
"permissions": {
"allow": [
"Bash(npm run lint)",
"Bash(npm run test *)"
],
"ask": [
"Bash(git push *)"
],
"deny": [
"Read(./.env)",
"Read(./.env.*)",
"Bash(git push --force *)",
"Bash(rm -rf *)"
]
}
}
设置文档中有几个细节值得了解:
把命令模式规则当作警戒线,而不是围墙。Bash(rm -rf *) 无法匹配 rm -fr、rm -r -f 或 find . -delete。模式规则擅长拦截常见写法,却无法完整描述所有“破坏性操作”。
Read(./.env) 拦截的是 Read 工具。单靠这条规则,并不能阻止通过 Bash 执行 cat .env、用 Grep 搜索整个仓库,或通过以你的主目录为根目录的 MCP filesystem server 读取文件。添加 deny 规则后,要亲自测试其他访问路径:让 Agent 对同一个文件执行 cat、grep 和 less,并确认每种操作都被拒绝。
更好的做法是,完全不在开发者的机器上存放生产环境机密。对于需要这些机密的命令,在运行时通过 secret manager 注入,这样工作目录里就没有可供 Agent 读取的机密。
当你使用“Yes, and don't ask again”批准一条 Bash 命令时,Claude Code 会将一条 allow 规则保存到 .claude/settings.local.json 中。这些批准记录会悄悄积累。每隔几周打开这个文件,删除所有超出你原本愿意授予范围的规则:Bash(python *) 或 Bash(curl *) 授予的权限,远远超过你当时想批准的那一条命令。
将 .claude/settings.json 提交到仓库,让每次克隆都获得同一份 deny 列表。对于组织而言,受管设置的优先级高于其他所有设置,用户或项目文件都无法覆盖它。把不可妥协的规则放在那里,例如机密路径、强制推送、生产环境部署命令;个人则可以在本地添加方便日常工作的 allow 规则。
MCP server 的定义保存在 Claude Code 自身的配置中。每个 server 都是一个以你的用户权限运行的进程,而且通常持有 token。实用规则如下:
Hook 允许你在工具执行前运行自己的程序。对于 PreToolUse,Claude Code 会将 JSON 数据(工具名称和输入)写入 hook 的 stdin,再读取它返回的 JSON 决策。返回 permissionDecision: "deny" 并附上原因,就能阻止这次调用,同时向模型展示原因。这通常能让模型重新规划,而不是反复重试。
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash|Write|Edit|WebFetch",
"hooks": [{ "type": "command", "command": "node /path/to/your-hook.mjs" }]
}
]
}
}
相比静态模式,hook 的优势在于:它可以规范化命令、解析路径后再检查、查看会话历史,还能像其他代码一样,在 CI 中进行单元测试。
对于不是你编写的仓库,在容器或 VM 中运行 Claude Code,不挂载宿主机凭据,并限制出站网络访问。Claude Code 的文档也介绍了 Bash sandbox 选项,应该启用它。即便前面的每条规则都写得有些偏差,隔离这一层仍然能守住边界。
出问题时,“Agent 运行了什么,又是什么允许它这样做?”应该在一分钟内就能回答,而不是花上一下午翻查 shell 历史。记录决策时,也要记录产生该决策的规则,并把日志保存在 Agent 无法编辑的位置。
Cirvix AgentControl 是一个开源(Apache-2.0)的策略层,通过一份策略文件覆盖前面提到的两层防护。它在受管控的工具调用执行前进行评估,返回 permit、hold(等待指定审批人)或 deny,默认结果为 deny。
对于 Claude Code,有两种接入方式,而且它们可以互相补充:
不到一分钟就能试一次策略决策,而且不会实际执行任何操作:
npx --yes @cirvix_ai/agent-control check --action fs.read --resource .env.production
# DENY fs.read …/.env.production rule deny-dotenv-read (exit 1)
要明确它的边界:Cirvix 管控的是经由 gateway、hook 或其 SDK wrapper 路由的调用。它不检查 prompt,不阻止 prompt injection,也看不到你亲自在终端里输入的操作。它限制的是遭到注入或犯了错误的 Agent 能做什么,而这正是你实际能够控制的部分。
Cirvix AgentControl 已开源;更多指南和文档可在 Cirvix 官网查看。
如需采取进一步措施,可以考虑屏蔽此人和/或举报滥用行为。