首页
首页/s03
s0365 行代码

Permission Gate

Check Before You Execute

核心洞察:

Dangerous actions need a harness decision point before the shell runs.

在执行工具之前,harness 会检查该操作是否需要权限。危险命令(如文件系统写入、网络访问和代码执行)会提示用户确认。只读操作则自动放行。由于这一权限门位于 harness 层,每个工具都能自动获得权限检查能力。

架构流程图

问题:自动化而不鲁莽

拥有任意工具访问权限的 agent 功能强大但也伴随着风险。一条因模型幻觉而生成的 bash 命令可能导致文件删除、恶意软件安装或数据泄露。解决方案并非移除工具,而是在执行前添加一个权限门,对每个操作进行分类。读取操作(如 glob、grep、read)自动放行。写入操作(如 edit、write、bash)则提示用户确认。这种方法在安全性与工作流畅性之间取得了平衡:agent 在安全操作上快速执行,在危险操作上暂停等待确认。

Harness 级别的安全机制

权限门位于 execute_tool() 中,而非单个处理函数中。这是有意为之:安全是一个横切关注点,不应在工具之间重复实现。单个权限门即可保护所有工具,包括尚不存在的未来工具。分类函数 classifyAction() 同时使用工具名称和输入参数来确定危险级别。写入 /etc/passwd 比写入 /tmp/test.txt 更危险,尽管两者都使用 write 工具。

设计决策

权限检查是异步的(使用 await promptUser),这意味着 agent 将控制权交给用户界面。Agent 在继续之前会等待人工输入,不存在静默批准的情况。

危险级别分类并非硬编码。插件可以通过钩子注册自定义分类器或覆盖默认分类器。这使得组织能够执行自己的安全策略。

对比 Claude Code

两者都优先使用权限门而非沙箱隔离。Claude Code 要求文件写入和 shell 命令必须获得用户明确批准。OpenCode 的权限系统则更进一步,通过 classifyAction() 这一使用通配符路径模式(allow、deny、ask)而非简单二元提示的结构化分类函数来实现。Deferred<PermissionEval> 模式意味着权限可以预先评估和缓存,从而减少用户提示疲劳。

深入设计决策

在 Harness 层而非工具层加权限门

权限在 harness 层检查,在工具执行之前。这意味着每个工具自动获得权限检查——不需要各自实现安全逻辑。

备选方案: 每个工具可以实现自己的权限检查,但那会导致行为不一致和安全漏洞。harness 层的权限门是单一控制点。

危险操作需要用户确认

修改文件系统、访问网络或执行任意代码的命令需要用户明确确认。只读操作自动放行。

备选方案: 对于可信场景存在完全自动批准模式,但默认是每次询问,以防止意外的副作用。

Learn OpenCode — Built with Next.js