plugin.approval.* 流程,以及处理聊天批准按钮和
/approve 命令的相同批准 UI 表面。
将插件权限请求用于插件/应用权限。它们不能替代
宿主 exec 批准、可选工具允许列表,或 Codex 的原生权限
审查。
选择合适的闸门
选择与你需要的决策点相匹配的闸门:| 闸门 | 适用场景 | 它控制什么 |
|---|---|---|
| 可选工具 | 在用户主动选择之前,工具不应对模型可见。 | 通过 tools.allow 控制工具暴露。 |
| 插件权限请求 | 某个插件 hook 或插件拥有的操作必须在单次动作运行前询问。 | 通过 plugin.approval.* 进行运行时批准。 |
| Exec 批准 | 宿主命令或类 shell 工具需要操作员批准。 | 宿主 exec 策略和持久化 exec 允许列表。 |
| Codex 原生权限请求 | Codex 在原生 shell、文件、MCP 或应用服务器操作前询问。 | Codex app-server 或原生 hook 的批准处理;当 OpenClaw 拥有该提示时,会路由到插件批准。 |
| MCP 批准引发请求 | Codex MCP 服务器请求某个工具调用的批准。 | 通过 OpenClaw 插件批准桥接的 MCP 批准响应。 |
在工具调用前请求批准
大多数插件编写的提示都应该从before_tool_call hook 开始。该 hook
在模型选择工具之后、OpenClaw 执行它之前运行:
- 保持
title简短且以动作导向为主。Gateway 最多接受 80 个 字符。 - 保持
description具体且有边界。Gateway 最多接受 256 个 字符。 - 包含动作、目标和风险。不要包含不应出现在聊天批准界面中的密钥、 token 或私有负载。
- 仅对错误决策可能导致生产损害或数据丢失的操作使用
severity: "critical"。 - 当对该动作进行持久化信任不安全时,使用
allowedDecisions: ["allow-once", "deny"]。
决策行为
OpenClaw 会创建一个带有plugin: ID 的待批准项,将其发送到
可用的批准界面,并等待决策。
| 决策 | 结果 |
|---|---|
allow-once | 当前调用继续执行。 |
allow-always | 当前调用继续执行,并将该决策传递给插件。 |
deny | 该调用被阻止,并返回拒绝的工具结果。 |
| 超时 | 除非 timeoutBehavior 为 "allow",否则该调用会被阻止。 |
| 取消 | 当运行被中止时,该调用会被阻止。 |
| 没有批准路由 | 由于没有连接的批准界面能够处理它,该调用被阻止。 |
allow-always 只有在请求的插件或运行时实现了
该持久化时才是持久化的。对于普通的 before_tool_call.requireApproval hook,
OpenClaw 会将 allow-once 和 allow-always 视为当前调用的批准决策,
并将解析后的值传递给 onResolution。如果你的插件提供 allow-always,
请明确记录并实现它未来会信任哪些调用。
如果该 hook 还返回了 params,OpenClaw 只会在批准成功后应用这些参数更改。
较低优先级的 hook 仍然可以在较高优先级的 hook 请求批准后进行阻止。
allowedDecisions 会限制展示给用户的按钮和命令。对于请求未提供的任何决策,
Gateway 都会拒绝解析尝试。
路由批准提示
批准提示可以在本地 UI 界面中解析,也可以在支持批准处理的聊天渠道中解析。 要将插件批准提示转发到显式聊天目标,请配置approvals.plugin:
approvals.plugin 与 approvals.exec 相互独立。启用 exec 批准
转发不会路由插件批准提示,启用插件批准转发也不会改变宿主 exec 策略。
当提示包含手动批准文本时,请使用其中一个提供的决策进行解析:
Codex 原生权限
Codex 原生权限提示也可以通过插件批准流转,但它们与 插件编写的 hooks 拥有不同的所有权。- Codex app-server 批准请求会在 Codex 审查后通过 OpenClaw 路由。
- 原生 hook
permission_request转发可在启用该转发时通过plugin.approval.request发起询问。 - 当 Codex 将
_meta.codex_approval_kind标记为"mcp_tool_call"时, MCP 工具批准引发请求会通过插件批准路由。
故障排查
工具提示插件批准不可用。 没有批准 UI 或已配置的 批准路由接受该请求。连接一个支持批准的客户端,使用支持同一聊天/approve 的渠道,或配置 approvals.plugin。
allow-always 出现了,但下一次调用又再次提示。 通用插件
批准流程不会自动为任意 hooks 持久化信任。请在你的插件中于
onResolution("allow-always") 后持久化插件拥有的信任,或者
只提供 allow-once 和 deny。
/approve 拒绝该决策。 该请求限制了
allowedDecisions。请使用提示中打印出的决策之一。
Slack、Discord、Telegram 或 Matrix 提示的路由方式与 exec
批准不同。 插件批准和 exec 批准使用不同的配置,并且可能使用
不同的授权检查。请验证 approvals.plugin 以及该渠道对
插件批准的支持,而不仅仅是检查 approvals.exec。