Permission System - 权限管道与行动控制

3075 字
15 分钟
Permission System - 权限管道与行动控制

L07 要回答一个问题:如何在 L06 的基础上让 Agent 行动可靠可控,而不让恶意操作或误判穿透?

L06 给了我们骨架:三层压缩 + 连续性保护 + 控制权归属。但真实 Agent 执行时可能访问敏感文件、执行危险命令、误判操作后果。全部放行会失控,全部拦截会瘫痪。怎么做?

本章讲三个机制:

机制解决什么问题核心设计
权限管道任何调用先过安全检查Deny → Mode → Allow → Ask
三种模式不同场景不同策略default/plan/auto
Bash特殊处理bash不是普通文本独立前置检查 + 危险pattern过滤

这三个机制叠加在 L06 的 Context Compact 上,循环本身不变。理解 L07,就理解了 Agent 如何”行动可靠可控不穿透”。

一、权限管道:四层顺序检查#

“权限系统不是为了让 Agent 更笨,而是让行动先经过可靠的安全判断。”

这句话概括了 Permission System 的本质。任何工具调用都不直接执行,必须先过权限管道。

管道顺序原则#

flowchart LR TC[tool_call] --> DENY[Deny Rules] DENY -->|通过| MODE[Mode Check] MODE -->|通过| ALLOW[Allow Rules] ALLOW -->|通过| ASK[Ask User] ASK -->|yes| EXEC[执行 Handler]

四层顺序有深刻理由:

层级检查内容为什么优先级最高
Deny禁止规则(危险pattern)安全优先——直接拦截,不问用户
Mode模式约束(plan只读)策略层——会话风格控制
Allow允许规则(白名单)效率层——命中直接放行
Ask用户确认兜底——未命中规则问用户

顺序为什么是 Deny → Mode → Allow → Ask?

  • Deny 优先:安全高于效率。危险操作必须先拦截,不问用户意愿。
  • Mode 第二:会话风格控制。Plan 模式下写操作必须拦截,不管 Allow 规则。
  • Allow 第三:效率优化。白名单命中直接放行,不需要问用户。
  • Ask 兜底:未知操作问用户。用户决策优于系统猜测。

管道执行流程#

def permission_pipeline(tool_call):
# Layer 1: Bash特殊检查(独立前置)
if tool_call.tool == "bash":
result = bash_validator(tool_call.input["command"])
if result == "deny":
return PermissionDecision(behavior="deny", reason="Bash validator")
# Layer 2: Deny Rules
if matches_deny_rules(tool_call):
return PermissionDecision(behavior="deny", reason="matched deny rule")
# Layer 3: Mode Check
if mode == "plan" and is_write_operation(tool_call):
return PermissionDecision(behavior="deny", reason="plan mode blocks writes")
if mode == "auto" and is_safe_read(tool_call):
return PermissionDecision(behavior="allow", reason="auto mode allows reads")
# Layer 4: Allow Rules
if matches_allow_rules(tool_call):
return PermissionDecision(behavior="allow", reason="matched allow rule")
# Layer 5: Ask User(兜底)
return PermissionDecision(behavior="ask", reason="no rules matched")

关键点:管道在 dispatch map 和 handler 之间——找到 handler 后不直接执行,先过管道。

验证你的理解#

Q1:Allow 规则命中后,还会 Ask 用户吗?

:::details 答案 不会。Allow 规则命中直接 allow,不问用户。

管道顺序:Deny → Mode → Allow → Ask。

Allow 是效率层——白名单命中表示”系统已判断安全”,不需要问用户。

如果 Allow 后还要 Ask,白名单就失去效率意义。每次都要问用户,流畅度下降。 :::

二、三种模式:不同场景不同策略#

权限管道是通用机制,三种模式是场景策略。

模式未命中规则时行为适用场景
defaultAsk User日常交互,用户参与决策
plan读操作 Allow,写操作 Deny分析/审查,只看不改
auto安全操作 Allow,危险操作 Ask高流畅度探索,减少中断

default 模式:用户参与决策#

flowchart TB D1[未命中规则] --> D2[Ask User] D2 -->|yes| D3[执行] D2 -->|no| D4[拒绝]

适用场景:日常交互,用户希望参与关键决策。

特点:未知操作问用户,用户决策优于系统猜测。

plan 模式:只读约束#

flowchart TB P1[读操作] --> P2[Allow] P3[写操作] --> P4[Deny] P2 --> P5[执行] P4 --> P6[拒绝]

适用场景:分析代码、审查日志、查看配置——只看不改。

特点:写操作强制拦截,不问用户。这是会话风格控制,不是安全判断。

auto 模式:安全自动过#

flowchart TB A1[安全操作<br/>read/search] --> A2[Allow] A3[危险操作<br/>write/bash危险] --> A4[Ask] A2 --> A5[执行] A4 -->|yes| A5 A4 -->|no| A6[拒绝]

适用场景:高流畅度探索,减少确认中断。

特点:安全操作(read_file、search)自动放行,危险操作(write_file、bash危险命令)问用户。

验证你的理解#

Q2:plan 模式下,Allow 规则命中的写操作会被放行吗?

:::details 答案 不会。plan 模式下写操作强制拦截,不管 Allow 规则。

管道顺序:Deny → Mode → Allow → Ask。

Mode 检查在 Allow 之前——plan 模式写操作在 Mode 层就被 Deny,不会到达 Allow。

设计理由:plan 模式是”只读约束”,是会话风格控制,高于白名单效率。用户说”只看不改”,系统必须遵守,不能因为白名单而放行写操作。 :::

三、Bash特殊处理:独立前置检查#

bash 不是普通文本,是可执行动作描述。

为什么 bash 需要特殊处理?

工具输入内容检查方式
read_file文件路径路径检查(safe_path)
write_file文件路径 + 内容路径检查 + 内容检查
bash命令字符串内容分析——危险pattern识别

bash 的输入是命令字符串,需要在内容层面检查,不只是路径层面。

Bash 危险 pattern#

Pattern拒绝理由示例
sudo权限提升风险sudo rm -rf /
rm -rf批量删除风险rm -rf src/
命令替换嵌套执行风险$(cat file)
可疑重定向文件覆盖风险> /etc/passwd

检查时机:bash 命令进入权限管道前,先过 Bash Validator。

def bash_validator(command: str) -> str:
# 危险pattern检查
dangerous_patterns = ["sudo", "rm -rf", "$(", "> /etc/", "> ~/.ssh/"]
for pattern in dangerous_patterns:
if pattern in command:
return "deny"
# 可疑重定向检查
if ">" in command and not is_safe_redirect(command):
return "deny"
return "allow" # 通过,继续走后续管道

Bash 读写分类#

bash 命令需要判断读还是写操作:

命令类型读操作写操作
文件操作ls, cat, find, greprm, mv, cp, echo > file
git 操作git status, git log, git diffgit add, git commit, git push

判断方法:内容分析——识别命令关键词。

def classify_bash_operation(command: str) -> str:
read_keywords = ["ls", "cat", "find", "grep", "git status", "git log", "git diff"]
write_keywords = ["rm", "mv", "cp", "git add", "git commit", "git push", ">"]
for kw in read_keywords:
if kw in command:
return "read"
for kw in write_keywords:
if kw in command:
return "write"
return "unknown" # 需进一步判断或问用户

验证你的理解#

Q3:git status 是读操作还是写操作?为什么?

:::details 答案 git status 是读操作。

git status 只查看状态,不修改 Git 工作区、暂存区、仓库。

常见误判:看到 “git” 就认为是写操作。正确分类需要理解命令语义:

命令类型原因
git status只查看状态
git log只查看历史
git diff只查看差异
git add修改暂存区
git commit创建 commit
git push写入远程

plan 模式下,git status 可以执行,git add 被拦截。 :::

四、回顾:L07 在循环上叠加了什么#

回到开头的问题:如何在 L06 的基础上让 Agent 行动可靠可控,而不让恶意操作或误判穿透?

答案:

叠加机制代码位置循环的变化
权限管道dispatch → handler 之间不变——只是执行前检查
三种模式会话启动时设置不变——只是管道策略差异
Bash特殊处理管道第一层前置不变——只是bash单独检查

循环本身仍是 L01 的 while True + stop_reason + messages[]。L07 只是在”执行控制层”叠加了权限管道。

与后续课程的关系#

理解 L07 后,你会发现后续课程都在 Permission System 上叠加——循环本身始终不变:

课程关系
L02 Tool Use管道在 dispatch map 和 handler 之间
L04 Subagent权限继承问题——子 Agent 是否继承父 Agent 权限?
L06 Context Compact权限判断占上下文?压缩后权限决策是否保留?
L08 Hook System权限 = 能不能执行;Hook = 执行前后插入什么
L09 Memory System权限规则跨会话保留?

核心洞察:Permission System 是”行动可靠可控”的机制。理解 L07,就理解了 Agent 如何”行动先过安全判断”。后续课程都在扩展权限机制——权限继承、跨会话保留、执行前后插入逻辑。

五、心智模型升级:从 L0 到 L2#

读完这篇文章,你的理解经历了怎样的升级?

L07 核心概念的理解升级路径#

概念L0(表面)L1(关联)L2(深层)
权限管道”调用先过检查""四层顺序:Deny→Mode→Allow→Ask""管道顺序原则——安全高于效率(Deny优先),策略高于白名单(Mode第二),效率优于猜测(Allow第三),用户决策兜底(Ask)。每层有深刻理由”
三种模式”default问用户,plan只读,auto自动过""不同场景不同策略""模式分离本质——default=用户参与(信任用户),plan=只读约束(信任策略),auto=流畅优先(信任系统判断)。决策主体不同”
Bash特殊处理”bash危险要检查""独立前置检查 + 危险pattern""Bash特殊原则——bash不是普通文本,是可执行动作描述。内容层面检查,不只是路径层面。类比 SQL 注入防御——输入不是数据,是执行意图”
读写分类”判断是读还是写""plan模式下写操作拦截""读写分类本质——判断操作是否修改世界状态。git status 不修改状态(读),git add 修改暂存区(写)。需要语义理解,不只是关键词匹配”

如何检验你达到了 L2?#

用这个问题自测:

如果迁移到数据库 Agent,权限系统怎么设计?

:::details L2 层级回答 迁移设计:

Claude原则数据库迁移
Bash特殊检查SQL危险命令前置deny(DELETE TABLE、TRUNCATE)
Deny→Mode→Allow→Ask同样顺序架构
内容分析Query内容分析
Plan=只读Plan=SELECT only

困难点

  1. 存储过程边界:存储过程读写性质判断困难,需要元数据标注。
  2. 数量级别预判:UPDATE 1 行 vs UPDATE 100万行,风险不同。

设计决策

  • 高敏感操作(DROP TABLE)硬编码 Deny
  • 普通规则配置文件
  • 存储过程需要元数据标注读写性质 :::

本章目标:让每个核心概念都从 L0 升级到 L2。理解 L07,不只是记住管道顺序,而是掌握”如何在循环上行动可靠可控”的设计原则。

六、复习可视化#

权限管道流程#

flowchart TB subgraph 输入 TC[tool_call] end subgraph 权限管道 TC --> BASH[Bash Validator<br/>独立前置检查] BASH -->|危险pattern| DENY1[deny<br/>reason: Bash validator] BASH -->|通过| DENY[Deny Rules] DENY -->|命中| DENY2[deny<br/>reason: matched deny rule] DENY -->|通过| MODE[Mode Check] MODE -->|plan模式+写操作| DENY3[deny<br/>reason: plan mode blocks writes] MODE -->|auto模式+读操作| ALLOW1[allow<br/>reason: auto mode allows reads] MODE -->|default模式| ALLOW[Allow Rules] ALLOW -->|命中| ALLOW2[allow<br/>reason: matched allow rule] ALLOW -->|通过| ASK[Ask User] end subgraph 输出 ASK -->|用户yes| EXEC[执行 Handler] ASK -->|用户no| DENY4[deny<br/>reason: denied by user] ALLOW2 --> EXEC ALLOW1 --> EXEC DENY1 --> REJECT[返回拒绝] DENY2 --> REJECT DENY3 --> REJECT DENY4 --> REJECT end style BASH fill:#ff6b6b,color:#fff style DENY fill:#ff6b6b,color:#fff style MODE fill:#4ecdc4,color:#fff style ALLOW fill:#45b7d1,color:#fff style ASK fill:#f9ca24,color:#fff style EXEC fill:#6c5ce7,color:#fff

三种模式对比#

flowchart LR subgraph default模式 D1[未命中规则] --> D2[Ask User] D2 -->|yes| D3[执行] D2 -->|no| D4[拒绝] end subgraph plan模式 P1[读操作] --> P2[Allow] P3[写操作] --> P4[Deny] P2 --> P5[执行] P4 --> P6[拒绝] end subgraph auto模式 A1[安全操作<br/>read/search] --> A2[Allow] A3[危险操作<br/>write/bash危险] --> A4[Ask] A2 --> A5[执行] A4 -->|yes| A5 A4 -->|no| A6[拒绝] end style D2 fill:#f9ca24,color:#fff style P2 fill:#45b7d1,color:#fff style P4 fill:#ff6b6b,color:#fff style A2 fill:#45b7d1,color:#fff style A4 fill:#f9ca24,color:#fff

Bash读写分类#

flowchart TB BASH[bash command] --> ANALYZE[内容分析] ANALYZE --> READ{读操作?} READ -->|是| READ_LIST[ls/cat/find/grep<br/>git status/log/diff] READ -->|否| WRITE{写操作?} WRITE -->|是| WRITE_LIST[rm/mv/cp<br/>git add/commit/push<br/>echo > file] WRITE -->|复杂| COMPLEX[需要进一步判断] READ_LIST --> PLAN_ALLOW[Plan模式: Allow] WRITE_LIST --> PLAN_DENY[Plan模式: Deny] COMPLEX --> PLAN_ASK[Plan模式: Ask User] style READ_LIST fill:#45b7d1,color:#fff style WRITE_LIST fill:#ff6b6b,color:#fff style COMPLEX fill:#f9ca24,color:#fff

数据库Agent迁移#

flowchart TB subgraph Claude Code Harness CC1[tool_call] --> CC2[Bash Validator] CC2 --> CC3[Deny Rules] CC3 --> CC4[Mode Check] CC4 --> CC5[Allow Rules] CC5 --> CC6[Ask User] end subgraph 数据库 Agent DB1[query_call] --> DB2[SQL Validator<br/>DELETE TABLE/TRUNCATE] DB2 --> DB3[Deny Rules<br/>敏感表] DB3 --> DB4[Mode Check<br/>Plan=SELECT only] DB4 --> DB5[Allow Rules] DB5 --> DB6[Ask User<br/>未知存储过程] end CC1 -.->|迁移| DB1 CC2 -.->|迁移| DB2 CC3 -.->|迁移| DB3 CC4 -.->|迁移| DB4 CC5 -.->|迁移| DB5 CC6 -.->|迁移| DB6 style CC2 fill:#ff6b6b,color:#fff style DB2 fill:#ff6b6b,color:#fff

支持与分享

如果这篇文章对你有帮助,欢迎分享给更多人或赞助支持!

赞助
Permission System - 权限管道与行动控制
https://firefly.cuteleaf.cn/posts/learn-claude-code/07-permission-system/
作者
AltumSisy
发布于
2026-04-14
许可协议
CC BY-NC-SA 4.0
Profile Image of the Author
AltumSisy
Hello, I'm AltumSisy.
公告
欢迎来到我的博客!这是一则示例公告。
音乐
封面

音乐

暂未播放

0:00 0:00
暂无歌词
分类
标签
站点统计
文章
32
分类
3
标签
25
总字数
68,347
运行时长
0
最后活动
0 天前

文章目录