OFFICIAL SOURCE ANALYSIS

权限系统

6 种权限模式详细对比、权限决策的多源竞争机制、Plan Mode 工作流、Allow/Deny 规则、Hooks 系统。

Part 2: 权限系统

上下文决定 Claude 「知道什么」,权限决定 Claude 「能做什么」。权限系统的核心职责是在模型的自主性和用户的安全感之间找到平衡点。

1. 六种权限模式的详细对比

Claude Code 提供 6 种预设的权限模式,覆盖从「极度保守」到「完全放行」的全部频谱。你可以通过 --permission-mode 启动参数或 /config 中设置。

模式 自动批准 需要确认 适用场景
default 只有读文件 所有写操作、所有命令执行 初次使用、高安全要求项目
acceptEdits 读文件 + 文件编辑 命令执行、文件删除 信任 Claude 改代码,但不信任它跑命令
plan 读 + 探索命令 + 写计划文档 修改业务代码、执行副作用命令 让 Claude 先研究再提方案,你审批后才执行
auto 全部动作 + classifier 安全检查 仅 classifier 认为危险的操作 日常开发、信任度高的场景
dontAsk 仅预定义的动作列表 超出预定义范围的一切 CI/CD、自动化流程中的精确控制
bypassPermissions 一切操作全部放行 隔离容器、一次性环境(慎用

各模式详解

default — 最保守 推荐新手

只有纯读操作(FileRead、GrepTool、GlobTool 等)被自动批准。所有写操作(编辑文件、创建文件、删除文件)和所有命令执行(Bash)都需要用户逐一确认。

体验:非常安全,但频繁弹出确认框会打断工作流。适合刚开始使用 Claude Code 时建立信任。

典型交互:

Claude 想要编辑 src/index.ts
  [y] 允许  [n] 拒绝  [a] 允许同类操作  [d] 拒绝同类操作
acceptEdits — 信任编辑 常用

在 default 的基础上,额外自动批准文件编辑操作(Edit、Write、NotebookEdit 等)。

适合:你信任 Claude 修改代码的能力,但仍然希望在它执行 shell 命令前确认。这是很多开发者的甜蜜点。

不自动批准的:Bash 命令执行、文件删除等可能有不可逆副作用的操作。

plan — 研究-规划-执行模式 协作流

这不仅仅是一个权限模式——它改变了 Claude 的工作方式。详见下方 Plan Mode 的工作方式

自动批准的:

  • 文件读取
  • 探索性命令(grep、find、ls 等不产生副作用的命令)
  • 写计划文档

不自动批准的:

  • 修改业务代码
  • 执行有副作用的命令(npm install、git commit 等)
auto — 全自动 + 安全网 高效

几乎所有操作都自动批准,但有一层 Bash classifier 安全检查:

  • 系统内置一个轻量级分类器,实时判断每个 Bash 命令的风险等级
  • 低风险命令(编译、测试、格式化)直接放行
  • 高风险命令(rm -rfgit push --force、涉及网络的命令)会被拦截并要求确认

适合:日常开发中追求效率,同时保留最后一道安全防线。大多数资深用户使用此模式。

dontAsk — 精确白名单

只允许预定义的动作集合,超出范围的操作不会询问用户而是直接拒绝或排队等待。

适合:CI/CD 集成、自动化脚本中需要精确控制 Claude 能做什么的场景。配合 --allowedTools 参数使用效果最佳。

bypassPermissions — 全部放行 危险

所有操作无条件通过,不经过任何安全检查。

警告:只应在以下场景使用:
  • 隔离的 Docker 容器中
  • 一次性的临时环境
  • 不包含任何敏感数据的沙盒
在生产代码库中使用 bypassPermissions 是在拿你的代码安全赌博。Claude 不会故意做坏事,但模型幻觉可能导致意外的破坏性命令被执行。

2. 权限决策流程

每次 Claude 想要调用一个工具时,权限系统会执行一个精密的决策流程。理解这个流程有助于你预测和控制 Claude 的行为。

决策流程总览

Claude 请求调用工具 (e.g. Bash: "npm test") │ ├─① 创建 Permission Context │ 包含: 工具名、参数、当前权限模式、历史决策 │ ├─② 多源竞争决策 (createResolveOnce 模式) │ ┌──────────────────────────────────────────┐ │ │ 以下决策源并行启动,第一个返回结果的赢 │ │ │ │ │ │ Source 1: Hooks (PreToolUse) │ │ │ → 用户配置的脚本可以抢先决策 │ │ │ → 可返回: allow / deny / 追加上下文 │ │ │ │ │ │ Source 2: Bash Classifier (仅 auto 模式) │ │ │ → 轻量级命令风险分类器 │ │ │ → 200ms grace period 等待其完成 │ │ │ │ │ │ Source 3: Allow/Deny 规则 │ │ │ → /permissions 中配置的静态规则 │ │ │ → 优先级高于 classifier │ │ │ │ │ │ Source 4: Channel Permissions │ │ │ → 权限模式定义的默认行为 │ │ │ │ │ │ Source 5: User Interaction │ │ │ → 弹出确认框让用户手动决策 │ │ └──────────────────────────────────────────┘ │ ├─③ 第一个决策源返回结果 │ → allow: 执行工具 │ → deny: 拒绝并告知 Claude │ → escalate: 转交用户确认 │ → context: 追加上下文后重新评估 │ └─④ 决策持久化 如果用户选择了 "allow all similar" → 同类操作后续自动批准,不再询问

关键机制详解

createResolveOnce 模式 — 第一个决策源赢 核心

权限系统不是按顺序检查每个决策源的。它使用 createResolveOnce 模式:所有决策源被同时激活,谁先返回有效结果谁赢。

为什么这样设计?

  • 性能:不需要等所有源都返回才做决定
  • 用户体验:如果 Hooks 或规则能快速决策,用户就不需要看到确认框
  • 灵活性:不同源可以互相「抢答」

实际优先顺序:

  1. Hooks 通常最先返回(本地脚本执行快)
  2. Allow/Deny 静态规则(简单的模式匹配)
  3. Bash classifier(需要约 200ms)
  4. 用户交互(等待人类操作,最慢)
200ms grace period — 等待 classifier 完成 细节

auto 模式下,当 Bash classifier 正在分析命令风险时,系统会等待最多 200ms。这个短暂的延迟是为了让 classifier 有机会拦截危险命令,而不是直接放行。

如果 200ms 内 classifier 没有返回:系统会回退到权限模式的默认行为(auto 模式下通常是放行)。

如果 Hooks 在 200ms 内先返回了:classifier 的结果会被忽略,因为 createResolveOnce 已经被 resolve 了。

决策持久化 — allow 后同类操作自动批准 UX

当用户在确认框中选择了 [a] allow all similar 时,系统会记住这个决策,后续同类操作自动批准。

  • 持久化范围:当前会话内有效。新会话需要重新确认(除非配置了 Allow 规则)
  • 「同类」的定义:工具名相同 + 关键参数匹配模式相同(如同一类 Bash 命令)
  • 撤销方式:/permissions 面板可以查看和管理所有已保存的决策

3. Plan Mode 的工作方式

Plan Mode 不仅仅是一个权限开关——它从根本上改变了 Claude 的工作流程,从「直接执行」变成「研究 → 规划 → 审批 → 执行」的四阶段协作模型。

研究
规划
审批
执行

四个阶段

阶段 1:研究(自动)

Claude 自由地读取文件、搜索代码、运行只读命令来理解问题。这些操作在 plan 模式下被自动批准,无需用户介入。

  • 读取相关文件
  • Grep/Glob 搜索代码模式
  • 运行探索性命令(lscatgit log 等)
  • 分析架构和依赖关系
阶段 2:规划(自动)

基于研究结果,Claude 输出一份详细的执行计划,描述将要做什么修改、为什么这样做、可能的风险点。

  • 列出需要修改的文件
  • 描述每个修改的目的和预期效果
  • 标注可能的副作用或需要注意的地方
  • 计划可以写成文档(如果配置了的话)
阶段 3:审批(用户)

用户审阅计划后决定是否批准执行。

  • 可以批准整个计划
  • 可以修改计划后再执行
  • 可以拒绝并要求重新规划
  • 可以只批准部分步骤
阶段 4:执行(需确认)

获得批准后,Claude 按计划执行修改。每个写操作仍然可能需要单独确认(取决于具体配置)。

何时使用 Plan Mode:
  • 大型重构任务——先看全貌再动手
  • 不熟悉的代码库——让 Claude 先研究再提方案
  • 需要团队审阅的变更——用计划文档替代口头描述
  • 关键系统——任何修改都需要人类确认

4. Allow/Deny 规则

Allow/Deny 规则是用户手动配置的静态权限规则。它们的优先级高于 classifier,是你精确控制 Claude 行为的主要工具。

管理方式

使用 /permissions 命令打开交互式权限管理面板,可以查看、添加、编辑和删除规则。

规则类型

类型效果示例
Allow 匹配的操作自动批准,不询问用户 Allow Bash(npm test) — 允许运行 npm test
Deny 匹配的操作自动拒绝,不询问用户 Deny Bash(rm -rf *) — 永远禁止 rm -rf

规则匹配机制

工具名 + 参数模式匹配

规则的格式是 工具名(参数模式)。参数模式支持通配符匹配:

  • Bash(npm *) — 匹配所有以 npm 开头的命令
  • Edit(src/**) — 匹配对 src 目录下所有文件的编辑
  • Bash(git push *) — 匹配所有 git push 命令
优先级

Allow/Deny 规则的优先级高于 Bash classifier。这意味着:

  • 如果你 Allow 了一个 classifier 认为危险的命令,它会被放行
  • 如果你 Deny 了一个 classifier 认为安全的命令,它会被拒绝
  • 规则让你拥有最终控制权,不受自动分类器的影响
实用规则配置示例 推荐
# 允许常见的开发命令
Allow Bash(npm test)
Allow Bash(npm run lint)
Allow Bash(npm run build)
Allow Bash(npx prisma generate)
Allow Bash(git status)
Allow Bash(git diff *)
Allow Bash(git log *)

# 禁止危险命令
Deny Bash(rm -rf *)
Deny Bash(git push --force *)
Deny Bash(git reset --hard *)
Deny Bash(curl * | sh)
Deny Bash(wget * | sh)

# 允许编辑特定目录
Allow Edit(src/**)
Allow Edit(tests/**)

# 禁止编辑配置文件
Deny Edit(.env*)
Deny Edit(*.pem)
Deny Edit(*credentials*)

5. Hooks 系统

Hooks 是 Claude Code 权限系统中最强大也最灵活的扩展点。它允许你在工具调用的前后插入自定义脚本,实现自动化的权限决策、上下文注入和行为审计。

两种 Hook 类型

类型触发时机能做什么
PreToolUse 工具执行之前
  • 放行操作(跳过用户确认)
  • 拒绝操作(阻止执行)
  • 升级为用户确认(即使当前模式本来会自动放行)
  • 追加上下文(在工具输入中添加额外信息)
PostToolUse 工具执行之后
  • 审计日志记录
  • 触发后续操作(如自动格式化、自动测试)
  • 修改工具输出
  • 发送通知

Hook 的返回值

PreToolUse Hook 可返回的决策
返回值效果
allow 直接放行,跳过所有后续权限检查
deny 直接拒绝,工具不会被执行
escalate 强制转交用户确认,即使当前权限模式本来会自动放行
context 不做权限决策,但向工具调用追加额外的上下文信息
(无返回 / 空) 跳过此 Hook,继续正常的权限决策流程

配置方式

Hooks 在 settings.json 中配置。可以通过 /config 命令打开设置面板来编辑。

settings.json 中的 Hooks 配置示例 配置
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "command": "python3 ~/.claude/hooks/check_bash_safety.py"
      },
      {
        "matcher": "Edit",
        "command": "node ~/.claude/hooks/validate_edit.js"
      }
    ],
    "PostToolUse": [
      {
        "matcher": "Edit",
        "command": "npx prettier --write $FILE_PATH"
      },
      {
        "matcher": "Bash",
        "command": "python3 ~/.claude/hooks/audit_log.py"
      }
    ]
  }
}

matcher 字段:指定此 Hook 监听的工具名称。可以是具体工具名(如 BashEdit),也可以用通配符匹配多个工具。

command 字段:要执行的脚本或命令。脚本通过标准输入(stdin)接收工具调用的详细信息(JSON 格式),通过标准输出(stdout)返回决策。

PreToolUse Hook 脚本示例 代码
#!/usr/bin/env python3
# ~/.claude/hooks/check_bash_safety.py
# 检查 Bash 命令是否安全

import sys, json

# 从 stdin 读取工具调用信息
input_data = json.loads(sys.stdin.read())
command = input_data.get("tool_input", {}).get("command", "")

# 定义危险模式
dangerous_patterns = [
    "rm -rf /",
    "curl.*| sh",
    "wget.*| bash",
    "> /dev/sda",
    "mkfs",
    "dd if=",
]

for pattern in dangerous_patterns:
    if pattern in command:
        # 返回 deny 决策
        json.dump({
            "decision": "deny",
            "reason": f"命令包含危险模式: {pattern}"
        }, sys.stdout)
        sys.exit(0)

# 没有匹配到危险模式,不做决策(继续正常流程)
json.dump({}, sys.stdout)
sys.exit(0)

Hooks 的执行时序

工具调用请求 │ ├── PreToolUse Hooks(可能有多个,按配置顺序执行) │ ├── Hook 1 返回 allow → 直接放行,跳过后续 Hooks │ ├── Hook 1 返回 deny → 直接拒绝,跳过后续 Hooks │ ├── Hook 1 返回 context → 追加上下文,继续执行后续 Hooks │ └── Hook 1 无返回 → 继续执行后续 Hooks │ ├── 正常权限决策流程(如果 Hooks 没有做出最终决策) │ ├── Allow/Deny 规则 │ ├── Bash Classifier │ └── 用户交互 │ ├── 工具执行 │ └── PostToolUse Hooks(按配置顺序执行) ├── 审计日志 ├── 后处理(格式化等) └── 通知
Hooks 的实际应用场景:
  • 安全审计:记录所有 Bash 命令执行到审计日志
  • 自动格式化:每次编辑文件后自动运行 Prettier/ESLint
  • 自定义安全策略:根据公司安全规范拦截特定操作
  • 上下文增强:在特定工具调用时注入额外的项目信息
  • 团队通知:当 Claude 执行关键操作时发送 Slack 通知

权限体系全景总结

决策优先级(从高到低)
  1. Hooks (PreToolUse) — 用户自定义脚本的决策优先级最高。返回 allow/deny 后其他源全部跳过。
  2. Allow/Deny 静态规则 — 通过 /permissions 配置的规则,比 classifier 优先。
  3. Bash Classifier — 仅在 auto 模式下生效的轻量级风险分类器。
  4. 权限模式默认行为 — 6 种模式各自定义的默认行为。
  5. 用户交互 — 弹出确认框等待人类决策,兜底方案。
最终建议:
  • 新手期:default 模式,逐步建立对 Claude 行为的认知
  • 日常开发:auto 模式 + Allow/Deny 规则做精细控制
  • 重要变更:切换到 plan 模式,让 Claude 先出方案再执行
  • 自动化流水线:dontAsk + Hooks 做精确的白名单控制
  • 安全敏感项目:配置 PreToolUse Hooks 实现自定义安全策略