快速开始
插件权限请求
插件权限请求让插件代码可以暂停一次工具调用或插件自有操作,直到用户批准或拒绝。它们使用 Gateway 网关
plugin.approval.* 流程,以及处理聊天审批按钮和 /approve 命令的同一组审批 UI 界面。
将插件权限请求用于插件/应用权限。它们不会取代主机 Exec 审批、可选工具允许列表,或 Codex 的原生权限审查。
选择正确的门控
选择与你需要的决策点匹配的门控:
| 门控 | 使用场景 | 控制内容 |
|---|---|---|
| 可选工具 | 在用户选择加入前,工具不应对模型可见。 | 通过 tools.allow 控制工具暴露。 |
| 插件权限请求 | 插件钩子或插件自有操作必须在某个操作运行前询问。 | 通过 plugin.approval.* 进行运行时审批。 |
| Exec 审批 | 主机命令或类似 shell 的工具需要操作员批准。 | 主机 Exec 策略和持久 Exec 允许列表。 |
| Codex 原生权限请求 | Codex 在执行原生 shell、文件、MCP 或应用服务器操作前询问。 | Codex 应用服务器或原生钩子审批处理;当 OpenClaw 拥有提示词时,通过插件审批路由。 |
| MCP 审批请求 | Codex MCP 服务器为工具调用请求审批。 | 通过 OpenClaw 插件审批桥接的 MCP 审批响应。 |
可选工具是设备发现时门控。插件权限请求是按调用门控。当敏感工具需要在模型能看到它之前显式选择加入,并且在操作运行前需要审批时,两者都要使用。
在工具调用前请求审批
大多数插件编写的提示词应从 before_tool_call 钩子开始。该钩子在模型选择工具之后、OpenClaw 执行工具之前运行:
export default definePluginEntry({ id: "deploy-policy", name: "Deploy Policy", register(api) { api.on("before_tool_call", async (event) => { if (event.toolName !== "deploy_service") { return; } const environment = typeof event.params.environment === "string" ? event.params.environment : "unknown"; return { requireApproval: { title: "Deploy service", description: `Deploy service to ${environment}.`, severity: environment === "production" ? "critical" : "warning", allowedDecisions: environment === "production" ? ["allow-once", "deny"] : ["allow-once", "allow-always", "deny"], timeoutMs: 120_000, timeoutBehavior: "deny", onResolution(decision) { console.log(`deploy approval resolved: ${decision}`); }, }, }; }); },});为将批准该操作的人编写提示词文本:
- 保持
title简短并聚焦操作。Gateway 网关最多接受 80 个字符。 - 保持
description具体且范围明确。Gateway 网关最多接受 256 个字符。 - 包含操作、目标和风险。不要包含不应出现在聊天审批界面中的密钥、令牌或私有载荷。
- 仅对错误决策可能造成生产损害或数据丢失的操作使用
severity: "critical"。 - 当该操作不适合持久信任时,使用
allowedDecisions: ["allow-once", "deny"]。
决策行为
OpenClaw 会创建一个带有 plugin: ID 的待处理审批,将其发送到可用的审批界面,并等待决策。
| 决策 | 结果 |
|---|---|
allow-once |
当前调用继续。 |
allow-always |
当前调用继续,并将决策传递给插件。 |
deny |
调用会被一个已拒绝的工具结果阻止。 |
| 超时 | 除非 timeoutBehavior 为 "allow",否则调用会被阻止。 |
| 取消 | 当运行被中止时,调用会被阻止。 |
| 无审批路由 | 调用会被阻止,因为没有已连接的审批界面可以解析它。 |
只有当发起请求的插件或运行时实现了持久化时,allow-always 才是持久的。对于普通的 before_tool_call.requireApproval 钩子,OpenClaw 会将 allow-once 和 allow-always 视为当前调用的审批决策,并将解析后的值传递给 onResolution。如果你的插件提供 allow-always,请准确记录并实现它信任哪些未来调用。
如果钩子还返回 params,OpenClaw 只会在审批成功后应用这些参数变更。较低优先级的钩子仍然可以在较高优先级的钩子请求审批后阻止调用。
allowedDecisions 会限制显示给用户的按钮和命令。对于请求未提供的任何决策,Gateway 网关都会拒绝解析尝试。
路由审批提示
审批提示可以在本地 UI 界面中解析,也可以在支持审批处理的聊天渠道中解析。要将插件审批提示转发到显式聊天目标,请配置 approvals.plugin:
{ approvals: { plugin: { enabled: true, mode: "targets", agentFilter: ["main"], targets: [{ channel: "slack", to: "U12345678" }], }, },}approvals.plugin 独立于 approvals.exec。启用 Exec 审批转发不会路由插件审批提示,启用插件审批转发也不会更改主机 Exec 策略。
当提示包含手动审批文本时,使用所提供决策之一进行解析:
/approve <id> allow-once/approve <id> allow-always/approve <id> deny请参阅高级 Exec 审批,了解完整的转发模型、同聊天审批行为、原生渠道投递,以及特定渠道的审批者规则。
Codex 原生权限
Codex 原生权限提示也可以通过插件审批传递,但它们的所有权不同于插件编写的钩子。
- Codex 应用服务器审批请求会在 Codex 审查后通过 OpenClaw 路由。
- 启用原生钩子
permission_request中继后,该中继可以通过plugin.approval.request发起询问。 - 当 Codex 将
_meta.codex_approval_kind标记为"mcp_tool_call"时,MCP 工具审批请求会通过插件审批路由。
请参阅 Codex harness runtime,了解 Codex 特定行为和回退规则。
故障排除
工具提示插件审批不可用。 没有审批 UI 或已配置的审批路由接受该请求。连接支持审批的客户端,使用支持同聊天 /approve 的渠道,或配置 approvals.plugin。
出现 allow-always,但下一次调用又提示。 通用插件审批流程不会自动为任意钩子持久化信任。在 onResolution("allow-always") 之后在你的插件中持久化插件自有信任,或者只提供 allow-once 和 deny。
/approve 拒绝该决策。 该请求限制了 allowedDecisions。请使用提示中打印的决策之一。
Slack、Discord、Telegram 或 Matrix 提示的路由与 Exec 审批不同。 插件审批和 Exec 审批使用单独的配置,并且可能使用不同的授权检查。请验证 approvals.plugin 和该渠道的插件审批支持,而不是只检查 approvals.exec。