13Permission System
L3P1五步章 · 技术章
Why · 为什么要学
不是所有 tool 都能 auto 执行——读文件可以,删数据库要确认,发邮件要审批。permission system 是 harness 在"自动化效率"和"用户控制"之间画线的地方。设计差了用户被询问到崩溃,设计松了 agent 误删 prod 数据。这一节是 #14 Sandbox 和 #29 Prompt Injection 防御的协同前提。
1 ·核心要点
Permission system 决定每个 tool 调用走三条路径之一:
| 决策 | 行为 | 典型规则 |
|---|---|---|
allow | 直接执行 | 所有 read、安全的 git 命令、特定目录 edit |
ask | 弹 UI 让用户确认 | rm、未限定范围的 edit、外发请求 |
deny | 直接拒绝 | curl 到外部域、sudo、改 system 文件 |
# Claude Code permissions 配置示例
permissions:
allow:
- "Bash(git:*)" # 所有 git 命令
- "Read(*)" # 读任意文件
- "Edit(./src/**)" # 只能改 src 下文件
ask:
- "Bash(rm:*)" # rm 都要问
- "Edit(/**)" # src 之外的 edit 要问
deny:
- "Bash(curl:*)" # curl 直接禁
- "Bash(sudo:*)" # sudo 直接禁
两阶段决策:(1) 快速分类——这个操作进 allow / ask / deny 哪个桶?(规则匹配,不调模型,延迟低);(2) 完整执行——deny 直接拒并返回 is_error,ask 弹 UI 阻塞等用户,allow 直接跑。
auto-approve list:用户在某次 ask 时勾"always allow this pattern"。这个列表要明确告诉用户"你刚授权了什么 pattern",并显示生效范围。
设计原则:默认最小权限;destructive(delete/send/publish/pay)永远 ask;高风险 pattern 即使被 auto-approve 也要 hard-coded 排除。
2 ·最小代码示例
# permission 决策伪代码
def check_permission(tool_name, tool_input, permissions, auto_approve):
pattern = make_pattern(tool_name, tool_input) # 如 "Bash(rm -rf /)"
# Phase 1: 快速分类(规则匹配)
if matches_any(pattern, permissions.deny):
return Decision.DENY
if matches_any(pattern, HARD_BLOCK_PATTERNS): # 永不放行的硬底线
return Decision.DENY
if matches_any(pattern, permissions.allow) or pattern in auto_approve:
return Decision.ALLOW
if matches_any(pattern, permissions.ask):
return Decision.ASK
return Decision.ASK # 默认 ask(最小权限原则)
# 关键:HARD_BLOCK_PATTERNS 不能被任何 auto-approve 覆盖
HARD_BLOCK_PATTERNS = [
"Bash(rm -rf /)",
"Bash(rm:* -rf:* ~)",
"Bash(sudo:*)",
"Edit(/etc/**)",
"Edit(/usr/**)",
]
3 ·工程权衡
什么操作必须 ask 或 deny
- 不可逆 destructive(delete、drop、truncate、rm -rf)——永远 ask
- 外发数据(send email、post API、curl 到外网)——永远 ask,可能 deny
- 支付/金钱(charge、transfer、purchase)——永远 ask
- 权限变更(chmod、添加 user、改 share 设置)——永远 ask