A12: 安全与对齐
相关章节:第 10 章 权限管理与安全
Claude Code 是一个自主 Agent,可以读取你的文件、编写代码、执行 Shell 命令并与外部服务交互。让这种强大功能保持安全不是可选的——它是核心工程挑战。本附录解释使 Claude Code 值得信赖的多层安全架构、Claude 为什么有时会拒绝请求,以及如何设计默认安全的 Agent 工作流。
为什么 Claude 会拒绝某些请求
如果你使用过 Claude Code 一段时间,你一定遇到过拒绝——Claude 拒绝执行你要求的操作。这不是 Bug。它是系统最重要的特性之一。
对齐训练流程
Claude 的安全行为来自多阶段训练过程:
Pre-training (raw capability)
│
▼
RLHF (Reinforcement Learning from Human Feedback)
│ Humans rate outputs for helpfulness AND harmlessness
▼
Constitutional AI (self-critique)
│ Claude evaluates its own outputs against principles
▼
Tool-use specific training
│ Additional training for safe tool calling behavior
▼
Deployed Claude (in Claude Code)
│
▼
Runtime safety layers (permissions, sandboxing)每一层添加不同类型的安全保障:
- RLHF 教会 Claude 一般性边界:不帮助创建恶意软件、不产生有害内容、不欺骗用户
- Constitutional AI(宪法 AI) 给 Claude 内化的原则,通过自我批评来应用(参见 A08 Constitutional AI 与 CLAUDE.md)
- 工具使用训练 教会 Claude 对破坏性操作保持特别谨慎:
rm -rf、git push --force、修改系统文件 - 运行时层(权限、沙箱化)即使模型判断失败也能提供纵深防御
Claude Code 中常见的拒绝类别
| 情况 | 为什么 Claude 拒绝 | 应该怎么做 |
|---|---|---|
| 编写恶意软件或漏洞利用代码 | 安全训练阻止有害代码生成 | 描述防御需求:"Write a test that verifies our input sanitization blocks SQL injection" |
| 删除系统文件 | 工具使用训练标记破坏性系统操作 | 具体说明你想删除什么以及原因 |
使用 sudo 运行命令 | 提权操作需要额外谨慎 | 在设置中授予特定权限或交互式确认 |
| 以明文访问凭据 | 围绕密钥处理的安全训练 | 使用环境变量、Vault 引用或带有正确 .gitignore 的 .env 文件 |
| 生成欺骗性内容 | Constitutional AI 反对欺骗的原则 | 诚实地重新表述请求 |
拒绝是校准过的,而非二元的
Claude 没有简单的黑名单。它的拒绝是上下文相关的:
- 在安全库中编写名为
encrypt_payload的函数是可以的 - 编写一个将数据窃取到外部服务器的
encrypt_payload函数会被拒绝 - 在教育上下文中解释 SQL 注入的工作原理是可以的
- 生成针对特定生产数据库的 SQL 注入 Payload 会被拒绝
如果 Claude 拒绝了你认为合理的内容,提供更多关于你为什么需要它的上下文。拒绝通常来自对意图的模糊性。
权限系统作为安全层
Claude Code 实现了三级权限系统,作为运行时纵深防御:
┌─────────────────────────────────────────────────┐
│ Permission Resolution │
│ │
│ 1. Check DENY rules ──► Blocked? → Refuse │
│ │ │
│ ▼ │
│ 2. Check ALLOW rules ──► Allowed? → Execute │
│ │ │
│ ▼ │
│ 3. Default: ASK USER ──► Prompt for approval │
│ │
└─────────────────────────────────────────────────┘纵深防御
权限系统在模型对齐之外提供额外的安全保障,而不是替代它。这是纵深防御的原则:
Layer 1: Model alignment (Claude's training)
│ Claude's judgment about what is safe
▼
Layer 2: Permission rules (.claude/settings.json)
│ Project-level rules about what is allowed
▼
Layer 3: Interactive approval (ask-user prompts)
│ Human in the loop for unrecognized operations
▼
Layer 4: OS-level sandboxing
│ Process isolation, filesystem restrictions
▼
Layer 5: Git safety net
Checkpoints, undo capability, version control如果任何单一层失败,其他层仍然提供保护。模型对齐失败(Claude 错误判断一个命令是安全的)被权限系统捕获。权限配置错误(ALLOW 规则过于宽泛)由模型自身的判断来缓解。这种冗余是刻意设计的。
负责任地配置权限
// .claude/settings.json -- recommended starting point
{
"permissions": {
"allow": [
"Read",
"Glob",
"Grep",
"Bash(npm test*)",
"Bash(npm run lint*)",
"Bash(git status)",
"Bash(git diff*)",
"Bash(git log*)"
],
"deny": [
"Bash(rm -rf /)*",
"Bash(sudo *)",
"Bash(curl * | bash)",
"Bash(git push --force*)",
"Bash(chmod 777*)"
]
}
}原则:广泛允许读取,窄范围允许写入,显式拒绝破坏性操作。
读取操作(Read、Glob、Grep)可以全局允许——它们不会修改你的系统。写入操作和 Shell 命令应该仅允许特定的、已知安全的模式。破坏性操作应该被显式拒绝。
过度授权的危险
将 "Bash(*)" 添加到允许列表以消除所有权限提示是很诱人的。这是危险的:
// DO NOT DO THIS in production workflows
{
"permissions": {
"allow": ["Bash(*)"] // Allows ANY shell command without asking
}
}使用这种配置,如果 Claude 误解了任务或幻觉出一个命令,就没有人工检查点来捕获它。模型的对齐是你唯一的安全层,而对齐是概率性的,不是绝对的。
减少提示的更安全方法:
{
"permissions": {
"allow": [
"Bash(npm *)",
"Bash(node *)",
"Bash(git add *)",
"Bash(git commit *)",
"Bash(npx jest*)",
"Bash(npx tsc*)",
"Write"
]
}
}这允许常见的开发命令,同时仍然要求对任何意外操作进行审批。
大脑与双手原则
第 14 章介绍了 Agent 系统的大脑与双手原则(Brain-vs-Hands),这是安全的核心:
┌──────────────────────────────────┐
│ BRAIN (Claude) │
│ │
│ Decides WHAT to do │
│ Reasons about approach │
│ Plans multi-step actions │
│ Evaluates results │
│ │
│ ───────── boundary ────────── │
│ │
│ HANDS (Tools) │
│ │
│ Executes specific actions │
│ Reads/writes files │
│ Runs commands │
│ Reports results │
│ │
└──────────────────────────────────┘安全含义:大脑(模型)永远不应该直接执行操作。它应该始终通过双手(工具)进行,而这些工具有安全约束:
- Read:无副作用,始终安全
- Write/Edit:可通过 git 修改,通过检查点可逆
- Bash:沙箱化、权限门控、超时限制
- WebFetch:网络访问受限且可审计
设计 Agent 工作流时,保持这种分离。模型推理;工具执行。工具受约束;模型不受约束。这种不对称性是安全 Agent 设计的基础。
设计默认安全的 Agent 系统
使用 Claude Code 构建自动化(CI/CD 流水线、定时 Agent、批处理)时,安全变得更加关键,因为没有人在实时观察。
原则 1:最小权限
只给 Agent 其特定任务所需的权限:
# CI/CD code review agent -- read-only, no write access needed
claude --model claude-sonnet-4-6-20250514 \
--permission-mode deny-all \
--allowedTools "Read,Glob,Grep,Bash(git diff*),Bash(git log*)" \
-p "Review the diff on this branch for security issues."原则 2:不可变输入
Agent 系统不应该修改自己的配置:
// The agent should NOT be able to edit these files
// Add them to deny rules
{
"permissions": {
"deny": [
"Edit(.claude/*)",
"Write(.claude/*)",
"Edit(CLAUDE.md)",
"Write(CLAUDE.md)"
]
}
}如果 Agent 可以修改自己的 CLAUDE.md 或设置,它就可以有效地重新编程自己——移除那些有意放置的安全约束。
原则 3:有界执行
为自主 Agent 设置时间和成本限制:
# Set a maximum session cost
export CLAUDE_MAX_COST=5.00 # Stop after $5 of API usage
# Set a maximum number of tool calls
export CLAUDE_MAX_TURNS=50 # Stop after 50 turns没有边界的 Agent 可能进入无限循环,无限消耗 Token。有界执行是成本和行为的安全网。
原则 4:审计追踪
Claude Code 执行的每个操作都被记录。在团队环境中,确保保留这些日志:
# Enable verbose logging for CI/CD agents
claude --verbose --output-format json \
-p "Run the deployment checklist" \
2>&1 | tee /var/log/claude-agent/$(date +%Y%m%d-%H%M%S).json审计追踪服务于两个目的:调试(出了什么问题?)和问责(谁授权了这个操作?)。
负责任的 Agent 部署清单
在生产或 CI/CD 中部署任何 Claude Code Agent 之前,请验证:
权限
- [ ] 读取操作被显式允许(避免过多提示)
- [ ] 写入操作限定在特定目录
- [ ] Shell 命令限制在已知安全的模式
- [ ] 破坏性操作(
rm -rf、git push --force)被显式拒绝 - [ ] 网络访问限制在必要的端点
边界
- [ ] 配置了每会话最大成本
- [ ] 配置了每会话最大回合数
- [ ] 为单个工具调用设置了超时
- [ ] 为整体运行设置了会话超时
密钥
- [ ] API 密钥在环境变量中,不在文件中
- [ ]
.env文件在.gitignore中 - [ ] Agent 无法读取凭据存储或密钥链
- [ ] 输出日志已清除敏感数据
恢复
- [ ] Git 检查点已启用(可以撤销 Agent 的更改)
- [ ] Agent 在分支上操作,而不是在 main 上
- [ ] 在合并 Agent 输出之前有人工审查步骤
- [ ] 回滚程序已记录并测试
监控
- [ ] Agent 运行记录了时间戳和成本
- [ ] 异常行为触发警报(意外的文件修改、高 Token 使用量)
- [ ] 定期审计权限配置
常见安全陷阱
陷阱 1:不经审查就信任 Agent 输出
# DANGEROUS: Agent generates and deploys without human review
claude -p "Fix the production bug and deploy" --allow-all即使修复是正确的也可能有意外的副作用。始终在"修复"和"部署"之间包含人工审查步骤。
陷阱 2:允许 Agent 安装包
# An agent that can run `npm install` can introduce supply-chain vulnerabilities
claude -p "Add the library we need for PDF generation"如果 Agent 安装了恶意或被入侵的包,它会以你的权限在你的环境中运行。将包安装限制为人工批准的依赖项,或使用 lockfile 验证步骤。
陷阱 3:通过 CLAUDE.md 共享凭据
<!-- DO NOT DO THIS in CLAUDE.md -->
## Database Access
Use the following connection string:
postgres://admin:s3cret_passw0rd@prod-db.example.com:5432/myappCLAUDE.md 被纳入版本控制。永远不要在其中放置凭据。使用环境变量引用代替:
## Database Access
The database connection string is in the $DATABASE_URL environment variable.陷阱 4:在 CI/CD 中忽略沙箱
在 CI/CD 模式下,Claude Code 以降低的交互安全运行(没有人来审批提示)。如果你跳过沙箱配置,每个 Shell 命令都以完整的 CI Runner 权限运行:
# GitHub Actions -- configure sandboxing explicitly
- name: Run Claude Code Review
run: |
claude --permission-mode deny-all \
--allowedTools "Read,Glob,Grep" \
-p "Review the changes in this PR"陷阱 5:递归自我改进
一个可以修改自身提示、指令或工具定义的 Agent 可以逃脱其安全约束:
Agent reads CLAUDE.md → modifies CLAUDE.md to remove restrictions →
reads new CLAUDE.md → operates without restrictions通过拒绝对配置文件的写入权限来防止这种情况(参见上面的原则 2)。
Anthropic 的负责任扩展政策(Responsible Scaling Policy)
Anthropic 发布了一项负责任扩展政策,指导 Claude 模型的开发和部署。与 Claude Code 用户相关的要点:
ASL(AI 安全级别)框架:模型在部署前会被评估危险能力。Claude Code 仅搭载通过 Anthropic 安全评估的模型。
红队测试:在每次模型发布前,专门的团队尝试引发有害行为。Claude 的拒绝基于这些测试的经验。
部署保障措施:Claude Code 中的权限系统、沙箱化和审计日志是部署级别的保障措施,补充模型级别的训练。
渐进式部署:Anthropic 增量发布能力,监控滥用情况并调整安全措施。新的工具类型或权限被逐步添加。
作为 Claude Code 用户,你自动从这个流程中受益。你的责任是为你的环境适当配置运行时安全层(权限、沙箱化、访问控制)。
安全与生产力的平衡
安全和生产力不是对立的——设计得当时它们是互补的:
| 安全措施 | 对生产力的影响 | 净效果 |
|---|---|---|
| 全局允许读取权限 | 消除安全操作的提示 | 正面 |
| 拒绝破坏性命令 | 防止灾难性错误 | 正面 |
| 对未知操作逐一审批 | 轻微摩擦,高保护 | 正面 |
| 拒绝所有命令 | 不可用——不断提示 | 负面 |
| 允许所有命令 | 快但危险 | 负面 |
目标是找到最大化两条曲线下面积的配置。对于大多数团队,这意味着:允许读取,允许已知安全的写入和命令,拒绝已知危险的操作,其余的都询问。
核心要点
- Claude 的拒绝是特性,不是 Bug。 它们来自多个旨在防止有害行为的训练阶段。如果拒绝看起来不正确,请提供更多上下文。
- 纵深防御有效是因为每一层覆盖不同的失败模式。 模型对齐、权限、沙箱化和 git 检查点各自捕获不同类别的错误。
- 最小权限是安全 Agent 设计的基础。 只给 Agent 其特定任务所需的权限。
- 永远不要让 Agent 修改自己的配置。 能自我修改的 Agent 可以逃脱安全约束。
- 部署前的人工审查是不可妥协的。即使正确的代码也可能有意外的副作用。
- 审计一切。 在团队和 CI/CD 环境中,日志是调试和问责的安全网。
参见:A08 Constitutional AI 与 CLAUDE.md 了解 CLAUDE.md 如何实现项目级 AI 治理,以及 A04 Agent 架构模式 了解安全如何与 Agent 设计集成。