主题
05.5 权限模型与安全边界
Claude Code 敢跑你的命令,是因为有一套权限系统兜底。理解它,你才能安全地放开自动化。
读完你能做什么:为不同信任级别的场景配置合适的权限,既不被每步打断,也不担心它闯祸。
一、权限模式:一个连续谱
Claude Code 有多个权限模式,从最谨慎到最放开:
| 模式 | 行为 | 适用 |
|---|---|---|
plan | 只读探索,不能改任何东西 | 陌生代码库、方案设计 |
default(别名 manual) | 标准权限检查,逐个提示 | 日常,需要审阅每步 |
acceptEdits | 自动接受文件编辑和常见文件系统命令 | 你信任它改文件,但危险命令仍问 |
auto | 后台分类器审查命令和受保护目录写入 | 平衡自动化与安全 |
dontAsk | 自动拒绝权限提示(已明确允许的仍可用) | 严格限制在允许清单内 |
bypassPermissions | 跳过所有权限提示 | ⚠️ 仅隔离环境 |
1.1 切换方式
bash
# 启动时指定
claude --permission-mode plan
claude --permission-mode acceptEditstext
# 会话中按 Shift+Tab 循环切换
# 或者用命令
> /plan1.2 一个实用的渐进策略
text
新项目/陌生代码 → plan(先看清楚)
↓ 理解了
日常开发 → default 或 acceptEdits
↓ 配好了 allow 规则
成熟的自动化流程 → auto + 精确的 allow/deny
↓ 完全隔离的环境(容器/worktree)
批量无人值守 → bypassPermissions(谨慎!)二、权限规则语法
在 .claude/settings.json 中用 allow / ask / deny 三类规则精确控制。
2.1 基本结构
json
{
"permissions": {
"allow": [
"Bash(npm test)",
"Bash(npm run *)",
"Bash(git status)",
"Bash(git diff *)",
"Read",
"Edit"
],
"ask": [
"Bash(git push *)"
],
"deny": [
"Bash(rm -rf *)",
"Read(./.env)",
"Read(./secrets/**)"
]
}
}2.2 规则匹配
| 写法 | 含义 |
|---|---|
Read | 允许/拒绝整个工具 |
Bash(npm test) | 只匹配精确命令 |
Bash(git diff *) | * 是通配,匹配 git diff 开头 |
Read(./secrets/**) | 路径通配,匹配 secrets 目录下所有 |
mcp__* | 匹配所有 MCP 工具 |
mcp__github__* | 匹配 github server 的所有工具 |
2.3 三类规则的优先级
text
deny > ask > allowdeny 永远赢。即使某命令在 allow 里,只要 deny 也匹配,就被拒绝。用这个特性设护栏:
json
{
"permissions": {
"allow": ["Bash(git *)"],
"deny": ["Bash(git push --force *)", "Bash(git reset --hard *)"]
}
}"允许所有 git 命令,但 force push 和 hard reset 除外。"
三、必配的安全护栏
无论你多信任它,这几条 deny 规则建议长期开着:
json
{
"permissions": {
"deny": [
"Bash(rm -rf /*)",
"Bash(rm -rf ~)",
"Read(./.env)",
"Read(./.env.*)",
"Read(./**/*secret*)",
"Read(./**/id_rsa)",
"Read(./**/credentials*)",
"Bash(git push --force*)",
"Bash(curl * | bash)",
"Bash(curl * | sh)"
]
}
}理由:
- 防误删 ——
rm -rf类 - 防密钥泄露到上下文 —— 读到
.env就进上下文了,可能被后续输出带出去 - 防危险的远程执行 ——
curl | bash是供应链攻击的经典入口 - 防历史破坏 —— force push
四、Additional Directories
默认情况下,Claude Code 只能读写你启动它的目录(及其子目录)。
bash
# 临时增加可访问目录
claude --add-dir ../shared-lib ../configjson
// 持久化
{
"permissions": {
"additionalDirectories": ["../shared-lib"]
}
}注意:--add-dir 授予的是文件访问权,但这些目录里的 .claude/ 配置默认不会被加载(除非设 CLAUDE_CODE_ADDITIONAL_DIRECTORIES_CLAUDE_MD=1)。
五、沙箱模式
在支持的平台上,可以让 Claude Code 在沙箱里运行,进一步隔离:
text
> /sandboxjson
{
"sandbox": {
"enabled": true
}
}沙箱提供 OS 级的隔离,即使权限规则有疏漏,破坏范围也被限制。这是无人值守自动化的推荐配置。
六、--dangerously-skip-permissions 的正确用法
这个 flag 跳过所有权限提示。它有合法用途,但必须配合隔离。
6.1 什么时候可以用
text
✅ 在 Docker 容器里,代码是一次性的
✅ 在 CI 的隔离 runner 里
✅ 在 git worktree + 沙箱里做实验6.2 什么时候绝对不要用
text
❌ 在你的主开发机上,对着重要仓库
❌ 有生产凭据的环境
❌ 能访问你个人文件的目录6.3 更安全的替代
与其完全跳过,不如用精确的 allow 清单达到"该自动的自动,该拦的拦":
bash
claude \
--allowedTools "Bash(npm *)" "Bash(git add *)" "Bash(git commit *)" "Read" "Edit" "Write" \
--disallowedTools "Bash(rm *)" "Bash(git push *)" "mcp__*"这比 bypassPermissions 安全得多,又能免去大部分打断。
6.4 与 daemon 子命令的交互(v2.1.199+)
bash
# 从 v2.1.199 起,前导的 --dangerously-skip-permissions 会正确路由到 daemon 子命令
claude --dangerously-skip-permissions daemon status七、提示词 vs 权限:一条重要界线
权限系统是确定性的,提示词是概率性的。
text
你想禁止某个操作
├─ 用提示词说"不要 rm -rf" → 概率性,可能失效
└─ 用 deny 规则 Bash(rm -rf *) → 确定性,永远生效任何"必须保证"的边界,都应该用权限规则或 hook 实现,而不是写在 CLAUDE.md 里祈祷它遵守。这条界线在本手册反复出现,因为它是安全使用 Agent 的核心。详见 04.2 元技巧 2 和 06.5 Hooks。
八、Auto Mode 的分类器
auto 模式用一个后台分类器判断命令的风险。你可以查看它的规则:
bash
claude auto-mode defaults # 打印内置分类规则(JSON)
claude auto-mode config # 查看应用了你的设置后的有效配置
claude auto-mode defaults --label 'Git Destructive' # 只看某类规则重置为默认:
bash
claude auto-mode reset --yes # v2.1.212+这让你能理解"为什么某个命令被自动允许/拦截",而不是黑盒。
九、企业管控
组织可以下发不可被个人覆盖的策略。相关内容见 10.3 企业级管控:
permissions.deny在 managed settings 里,个人无法解除allowManagedHooksOnly只允许管理员批准的 hookforceLoginMethod/forceLoginOrgUUID锁定认证
十、配置模板:三种信任级别
10.1 谨慎级(陌生代码/重要仓库)
json
{
"permissions": {
"defaultMode": "plan",
"deny": [
"Bash(rm -rf *)", "Read(./.env*)", "Read(./**/*secret*)",
"Bash(git push*)", "Bash(curl * | *sh)"
]
}
}10.2 平衡级(日常开发)
json
{
"permissions": {
"defaultMode": "acceptEdits",
"allow": [
"Bash(npm *)", "Bash(git status)", "Bash(git diff *)",
"Bash(git add *)", "Bash(git commit *)", "Read", "Edit", "Write"
],
"ask": ["Bash(git push *)"],
"deny": [
"Bash(rm -rf *)", "Read(./.env*)", "Bash(git push --force*)"
]
}
}10.3 自动化级(隔离环境 + 精确清单)
json
{
"sandbox": { "enabled": true },
"permissions": {
"defaultMode": "auto",
"allow": [
"Bash(npm *)", "Bash(git *)", "Read", "Edit", "Write", "Glob", "Grep"
],
"deny": [
"Bash(rm -rf /*)", "Bash(git push --force*)",
"Read(./.env*)", "mcp__*(*delete*)"
]
}
}延伸阅读
- 06.5 Hooks 生命周期钩子 —— 比权限规则更灵活的强制机制
- 06.8 Settings 配置全解
- 10.3 企业级管控
- 04.4 拒绝与边界的真实逻辑