一个危险的 CVE,正在你的批准里悄悄生长。
凌晨两点,你的 AI 助手发来一条消息:
⚡ exec-approvals: 请求执行
rm -rf /tmp/test-*[ allow-once ] [ allow-always ] [ deny ]
你揉了揉眼睛,点了"允许"。
然后你开始想:刚才那个 allow-always,是只对这条命令生效,还是对所有"删除临时文件"的命令都生效?
你不知道。
大多数人也不知道。
而这,正是今天这篇文章要撕开给你们看的东西。
一、为什么这个话题值得吵
在 AI Agent 时代,我们越来越多地把命令行控制权交给 AI——让它帮你部署服务、清理磁盘、安装依赖、管理服务器。
这个过程里,有一个绕不开的问题:
谁来为这条命令负责?
AI 会执行,但它的"理解"和你的"意图"之间,永远存在一条裂缝。你说"帮我清理日志",它理解为"删掉所有带 .log 后缀的文件"。但它没告诉你,它用的是 find / -name "*.log"。
exec-approvals 就是 OpenClaw 填在这条裂缝上的一层补丁。
但这道补丁,是安全锁,还是效率杀手?这个问题,吵三天三夜也吵不完。
二、exec-approvals 的双层守卫:比你想象的更复杂
很多人以为 exec-approvals 就是一个"执行前问你要不要批准"的弹窗。错了。它有两层守卫,而且这两层是完全独立的。
第一层:Policy 层——全局策略的大门
Policy 层是全局配置,决定的是:哪些命令需要问,哪些命令直接放行。
| 模式 | 行为 |
|---|---|
always | 所有命令都问,不管你是谁 |
on-miss | 只在命令没有匹配到 allowlist 时问 |
off | 完全不问,所有命令直接放行(危险!) |
注意这个逻辑:always 模式下,哪怕一个命令已经被加入 allowlist,每次执行还是会问。off 则是彻底躺平——只要进了 policy 层,就没有任何阻拦。
第二层:Allowlist 层——精确到命令的逐条审批
Allowlist 是你真正"批条子"的地方。它管的不是"要不要问",而是"批准了之后能跑多久"。
这里有三个选项,它们的语义非常微妙:
allow-once:单次有效,精确绑定到这一次命令 ID,执行完毕立即失效。
allow-always:永久有效,下次遇到相同命令直接放行,不需要再问。
deny:永久禁止,加入黑名单,下次遇到直接拒绝。
问题来了——什么是"相同命令"?
三、allow-always 的 command ID 绑定:一个被低估的漏洞
这是整篇文章最关键的部分,请逐字阅读。
当你对一条命令点了 allow-always,系统记录的"命令 ID"是基于命令的原始文本生成的。
# 你批准了这条
time npm test
# 下次 AI 送来的是这条
time rm -rf /
系统认为这是两条完全不同的命令——因为它们的文本不同,command ID 也不同。所以 allow-always 对 time npm test 的批准,不会自动覆盖 time rm -rf /。系统会走正常的 ask 流程,看起来"没问题"。
但换一个更真实的例子:
# 你批准了
curl https://api.example.com/upload -F "file=@docs.pdf"
# 下次 AI 送来了
curl https://api.example.com/upload -F "file=@secrets.zip"
Command ID 不同,因为文件路径不同。但语义完全一致——都是往同一个 API 端点上传文件。如果第一次上传的是普通文档,第二次上传的是敏感数据,allow-always 不会阻止你。
这不是 bug,这是设计上的权衡。
但它的安全含义是:allow-always 不是"授权这类操作",而是"授权这个 exact 字符串的命令"。
一旦你理解了这个本质,你就会明白为什么很多安全工程师看到 allow-always 会血压升高。
四、safeBins vs Allowlist:两个不同职责的守卫
很多人把 safeBins 和 allowlist 搞混,觉得它们是同一套系统的两个名字。不是的。
safeBins 是一份"免审批白名单",由系统或管理员预先定义。它针对的是那些经过验证、风险可控的常见命令,比如 ls、cat、pwd——你用这些命令不需要任何审批流程,因为它们本身就是只读或无害的。
Allowlist 是你手动添加的审批记录。每一条记录都是你对某条具体命令的授权行为。
换句话说:
- safeBins 是"默认信任",不需要你来审批
- Allowlist 是"我批准了",代表你主动做了授权决策
这两个机制协同工作,构成了 exec-approvals 的完整权限体系。
五、两种立场的核心矛盾
立场 A:安全派
每次审批都是必要的,allow-always 是危险的懒政。
安全派的逻辑是:AI 的行为是不可预测的,你今天批准了 curl 上传文件,明天它就可能上传一个恶意脚本。Allow-always 本质上是把一个动态的、可能变化的 AI 行为,锁死在一个静态的授权里——这是用昨天的信任,透支明天的安全。
更极端一点的安全派会说:off 模式是自杀,on-miss 是在赌命,只有 always 模式才是正经做事的态度。
立场 B:效率派
权限限制过细就是浪费生命,YOLO 模式才是正确姿势。
效率派的反驳也很直接:如果你每跑一条命令都要审批,你和 AI 协作的效率会低到让你想回到纯手工时代。Allow-always 不是懒政,是对"我已经验证过这条命令可靠"的合理确认。你不会每次 ls 都要审批一次,为什么 AI 帮你 ls 就要审批?
而且,很多 AI Agent 的使用者本身就是经验丰富的工程师,他们有能力判断一条命令的风险——强制审批是对他们能力的否定,也是对时间的浪费。
六、那道裂缝依然在那里
回到文章开头。
你点了"允许"。
但你真的知道自己在允许什么吗?
这个问题,exec-approvals 没有解决,它只是把它显性化了。
审批机制的存在本身,就是在承认一件事:我们不完全信任 AI,但我们在用它。
安全派说:那就别用,用了就承担后果。
效率派说:那就让审批流程做到足够顺滑,让信任和效率兼得。
而 OpenClaw 的 exec-approvals,给了你配置这几层守卫的工具——但最终按不按"允许"的,是你。
你站哪边?
安全锁,还是效率杀手?
欢迎在评论区留言——告诉我你的立场和使用场景,我会在评论区等你们 🦞
如果你对 exec-approvals 的具体配置感兴趣,欢迎翻阅 OpenClaw 官方文档,那里有关于 policy 层、allowlist、safeBins 更详细的说明。但记住——工具是工具,选择还是你的。