权限管线五步 本节摘要:上一节讲了 Hooks——鉴权管线第一道闸门。这一节详细拆解完整的权限管线五步,这是 Grok Build 安全设计的核心。每一次工具调用,在真正执行前,都要穿过这五道闸门:PreToolUse hooks、权限规则匹配、记住的授权、内建自动放行、提示策略。任意一步拒绝或需询问,都会改变流程。本节还会重点讲一个容易被忽视但至关重要的细节——命令分段鉴权:为什么 不会因为 cat 是只读就整体放行。理解权限管线,你就理解了 Grok Build 如何在「能干」与「不失控」之间取得平衡。 一、为什么需要五步闸门 先理解为什么权限检查不是一个简单的「允许/拒绝」二元判断,而是五步管线。
本节摘要:上一节讲了 Hooks——鉴权管线第一道闸门。这一节详细拆解完整的权限管线五步,这是 Grok Build 安全设计的核心。每一次工具调用,在真正执行前,都要穿过这五道闸门:PreToolUse hooks、权限规则匹配、记住的授权、内建自动放行、提示策略。任意一步拒绝或需询问,都会改变流程。本节还会重点讲一个容易被忽视但至关重要的细节——命令分段鉴权:为什么
cat foo && rm bar不会因为 cat 是只读就整体放行。理解权限管线,你就理解了 Grok Build 如何在「能干」与「不失控」之间取得平衡。
先理解为什么权限检查不是一个简单的「允许/拒绝」二元判断,而是五步管线。
多样的来源
权限决策的信息来源很多:
这些来源各有侧重,需要协同:hooks 做用户自定义、规则做框架策略、remembered 避免烦扰、白名单免问、模式定基调。
决策的层次
权限决策不仅是「允许/拒绝」,还有「需询问」:
「需询问」是关键——很多操作不能简单二分,要看用户意图。比如写文件,有时是 Agent 该做的,有时是误操作,框架无法预判,要问用户。
性能与体验
如果每次工具调用都问用户,体验极差。所以要有「自动放行」机制(白名单、remembered),让「显然安全」的操作免问,只在「需要判断」时打扰用户。
五步闸门就是为了协调这些需求——让决策既有原则(规则),又有便利(白名单),又有控制(模式),又有自定义(hooks)。
工具调用请求 ↓ [闸门 1] PreToolUse Hooks 用户自定义 hooks,可拒绝(fail-open) ↓ 通过 [闸门 2] 权限规则匹配 deny 命中 → 拒绝 allow 命中 → 直接放行(跳过 3、4、5) ask 命中 → 标记需询问 无命中 → 继续(按未匹配处理) ↓ [闸门 3] 记住的授权(会话内 remembered) 本次会话用户曾允许 → 复用 ↓ [闸门 4] 内建自动放行 只读工具 / 只读命令白名单 → 放行 ↓ [闸门 5] 提示策略(由 mode 决定) default → 弹询问 acceptEdits → 编辑类直接放行 dontAsk → 不问(但仍受规则约束) bypassPermissions → YOLO 全放行 plan → 计划模式,不实际执行
任意一步「拒绝」立即终止;「允许」放行;走到最后还没决定,按模式处理。下面逐步详谈。
上一节详谈过,这里简要回顾:
这一闸门的特点:用户级、灵活、fail-open。让用户能实现任意自定义策略,但不是可靠防线(hook 故障会失效)。
这是框架级权限的核心。用户通过配置定义一组规则,每条规则形如:
Bash(git *) # 匹配 bash 命令(git 开头) Read(src/**) # 匹配读文件(src 目录下) Edit(**/*.rs) # 匹配编辑(Rust 文件) MCPTool(my-server__*) # 匹配某 MCP server 的所有工具
规则有三种决定:allow、deny、ask。
匹配优先级:deny > ask > allow
如果多条规则都匹配,按优先级决定:
为什么 deny 最高:安全优先——只要有一条规则说「禁止」,就禁止,哪怕其他规则允许。这避免了「意外放行危险操作」。
规则的来源
规则从几个来源累积:
~/.grok/config.toml 的权限段).claude/settings.json 兼容(为复用 Claude 生态的配置)--allow / --deny 命令行临时规则规则例子
# 永远允许 git 只读命令 [[permissions.allow]] rule = "Bash(git status)" [[permissions.allow]] rule = "Bash(git log *)" # 永远禁止 rm -rf [[permissions.deny]] rule = "Bash(rm -rf *)" # 编辑 src 下的文件要询问 [[permissions.ask]] rule = "Edit(src/**)"
这一闸门的特点:框架级、可靠、按规则。比 hooks 可靠(不 fail-open),比白名单精细(可定制)。是权限管线的「中坚」。
即使用户没写规则,他可能在会话中临时授权过某些操作。比如 Agent 第一次想编辑 src/main.rs,弹询问,用户选「允许本次会话」。这条授权被记住,后续 Agent 再编辑这个文件,直接放行,不再问。
remembered 的特点:
为什么不持久化
如果跨会话记住,会有风险:用户某次「临时允许」了一次性操作,结果被永久记住,后续误用。会话级让用户每次会话重新评估,更安全。持久化授权要走规则(闸门 2),用户明确写进配置。
这一闸门的特点:会话级、便利导向。避免「同一操作问一百遍」的烦扰。
有些操作「显然安全」,框架默认放行,无需问用户:
只读白名单的维护
这个白名单是框架维护的,只含「普遍认为是只读」的命令。需要注意:
cat 只读,但 cat > file 重定向就改文件了——下一节讲为何这要小心)这一闸门的特点:框架级、便利导向。让「显然安全」的操作免问,大幅减少询问频率。
走到这一步,说明前四闸门都没决定(没 hooks 拒绝、没规则匹配、没 remembered、不在白名单)。这时按权限模式决定:
default(默认): 弹询问,让用户决定 用户可选:允许本次/允许本次会话/拒绝 acceptEdits: 编辑类(Edit/Write)直接放行 其他类型仍走 default 询问 (适合「我信任 Agent 改代码,但跑命令要问我」) dontAsk: 不弹询问,按规则处理 没规则匹配的,默认拒绝(避免误放行) (适合「我设了规则,没允许的就拒」) bypassPermissions(--yolo): 全部放行,不问 (危险!适合 CI/完全信任场景) plan: 计划模式,不实际执行任何修改类工具 (第 8 章详谈)
模式的选择
模式反映用户对 Agent 的信任程度与场景:
模式的来源
模式从几个地方设:
.claude/settings.json 的 defaultMode--permission-mode 标志模式是会话级的,可运行时切换。
这是权限管线里一个容易被忽视但至关重要的细节。考虑这条 bash 命令:
cat foo.txt && rm -rf /important
如果框架只看「整个命令的第一个词」,会发现 cat 是只读白名单里的,于是整体放行——结果 rm -rf /important 被执行了!这是严重的安全漏洞。
Grok Build 的解法:命令分段鉴权
框架对复合命令按分隔符切分,每段独立鉴权:
原命令:cat foo.txt && rm -rf /important 切分(按 &&、||、;、|): 段 1:cat foo.txt 段 2:rm -rf /important 逐段鉴权: 段 1:cat 是只读 → 通过 段 2:rm 不在白名单 → 询问/拒绝 整体:段 2 没通过 → 整个命令不执行
切分的分隔符:
&&(与)||(或);(顺序)|(管道)每段独立评估,任一段需询问/拒绝,整个命令不执行(或按策略处理)。
为什么这样重要
命令分段鉴权防止了一个常见的安全绕过手法:用只读命令「伪装」危险操作。没有分段,攻击者(或模型的误判)可以构造 cat foo && rm bar 这种「特洛伊木马」命令,骗过只读白名单。
有了分段,每段都逃不过鉴权,大大提升了安全性。
关键概念:命令分段鉴权是权限管线里一个「不起眼但关键」的设计。它体现了 Grok Build 对安全的细致——不只看表面(命令名),还看结构(复合命令的每段)。这种细致是 Agent 安全可信的基础。
把五闸门放在一起,它们的协作与短路关系:
[闸门 1] hooks 拒绝 → 立即拒绝(短路) 允许/失败 → 继续 ↓ [闸门 2] 规则匹配 deny → 立即拒绝(短路) allow → 立即放行(短路,跳过 3/4/5) ask → 标记,继续到 5 无命中 → 继续 ↓ [闸门 3] remembered 命中 → 放行(短路) 无 → 继续 ↓ [闸门 4] 白名单 命中 → 放行(短路) 无 → 继续 ↓ [闸门 5] 提示策略 按 mode 决定(询问/放行/拒绝)
短路的好处:决策高效——大多数操作在前几闸门就有结果,不必走完全部。比如只读命令在闸门 4 就放行,不必到闸门 5 询问。
ask 的传播:闸门 2 标记的 ask,会「穿透」闸门 3/4(即便白名单匹配,只要规则说 ask,仍要问)。这保证用户明确要求询问的操作,不会被白名单意外放行。
把权限管线放回第 5 章的工具调用生命周期,它是阶段四(鉴权):
① 模型生成 tool_call ② 框架查找工具 ③ 构造调用上下文 ④ 鉴权 ← 本节的五闸门 ⑤ 执行 ⑥ 流式回显 ⑦ 标准化 ⑧ 回填历史 ⑨ 下一轮
任意闸门拒绝/询问,都会改变 ⑤ 之后的行为:
一个典型的权限配置:
# ~/.grok/config.toml [permissions] # 默认模式 default_mode = "default" # 永久规则 [[allow]] rule = "Read(**)" # 允许读任何文件 [[allow]] rule = "Bash(git status)" [[allow]] rule = "Bash(git log *)" [[allow]] rule = "Bash(git diff *)" [[deny]] rule = "Bash(rm -rf /)" # 永远禁止 [[deny]] rule = "Edit(.env)" # 永远禁止改 .env [[ask]] rule = "Edit(src/**)" # 改 src 要问
这个配置让:
配合 remembered(会话内授权累积),日常使用既安全又不烦。
权限管线管「框架级」的允许/拒绝,但它不是终极防线。即便权限管线放行了,工具执行还受沙箱(下一节)的 OS 级约束:
权限管线放行 "Edit(/etc/passwd)" ↓ 工具尝试写 /etc/passwd 沙箱(Landlock/Seatbelt)拦截:工作区外不可写 ↓ 写失败
这种「双层防线」让安全更可靠——即便权限配置失误,沙箱仍兜底。下一节详谈沙箱。
下一节,我们讲清最后一道防线——沙箱,以及它如何用 Landlock/Seatbelt + seccomp 实现不可绕过的 OS 级隔离。