From bf1fcf2e5fea6535fc88fdfcdea2908a74a6236e Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Thu, 2 Apr 2026 17:30:30 +0100 Subject: [PATCH] docs(approvals): clarify auto native approval routing --- CHANGELOG.md | 1 + docs/channels/discord.md | 2 +- docs/channels/slack.md | 38 +++++++++++++++++++++++++++++++----- docs/channels/telegram.md | 2 +- docs/help/faq.md | 21 ++++++++++++++++++++ docs/tools/exec-approvals.md | 32 +++++++++++++++++++++++++----- 6 files changed, 84 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c0c55a6ef6c..6014075da70 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -37,6 +37,7 @@ Docs: https://docs.openclaw.ai - Agents/compaction: resolve `agents.defaults.compaction.model` consistently for manual `/compact` and other context-engine compaction paths, so engine-owned compaction uses the configured override model across runtime entrypoints. (#56710) Thanks @oliviareid-svg. - Agents/compaction: add `agents.defaults.compaction.notifyUser` so the `🧹 Compacting context...` start notice is opt-in instead of always being shown. (#54251) Thanks @oguricap0327. - WhatsApp/reactions: add `reactionLevel` guidance for agent reactions. Thanks @mcaxtr. +- Exec approvals/channels: auto-enable DM-first native chat approvals when supported channels can infer approvers from existing owner config, while keeping channel fanout explicit and clarifying forwarding versus native approval client config. ### Fixes diff --git a/docs/channels/discord.md b/docs/channels/discord.md index 77e6c233c32..da996e9fd1c 100644 --- a/docs/channels/discord.md +++ b/docs/channels/discord.md @@ -952,7 +952,7 @@ Default slash command settings: - `channels.discord.execApprovals.target` (`dm` | `channel` | `both`, default: `dm`) - `agentFilter`, `sessionFilter`, `cleanupAfterResolve` - Discord becomes an approval client when `enabled: true` and at least one approver can be resolved, either from `execApprovals.approvers` or from the account's existing owner config (`allowFrom`, legacy `dm.allowFrom`, or explicit DM `defaultTo`). + Discord auto-enables native exec approvals when `enabled` is unset or `"auto"` and at least one approver can be resolved, either from `execApprovals.approvers` or from the account's existing owner config (`allowFrom`, legacy `dm.allowFrom`, or explicit DM `defaultTo`). Set `enabled: false` to disable Discord as a native approval client explicitly. When `target` is `channel` or `both`, the approval prompt is visible in the channel. Only resolved approvers can use the buttons; other users receive an ephemeral denial. Approval prompts include the command text, so only enable channel delivery in trusted channels. If the channel ID cannot be derived from the session key, OpenClaw falls back to DM delivery. diff --git a/docs/channels/slack.md b/docs/channels/slack.md index 5c87605c080..cb8bfcfd48d 100644 --- a/docs/channels/slack.md +++ b/docs/channels/slack.md @@ -487,19 +487,47 @@ Exec approval prompts can route natively through Slack using interactive buttons This uses the same shared approval button surface as other channels. When `interactivity` is enabled in your Slack app settings, approval prompts render as Block Kit buttons directly in the conversation. -Configuration uses the shared `approvals.exec` config with Slack targets: +Config path: + +- `channels.slack.execApprovals.enabled` +- `channels.slack.execApprovals.approvers` (optional; falls back to `commands.ownerAllowFrom` when possible) +- `channels.slack.execApprovals.target` (`dm` | `channel` | `both`, default: `dm`) +- `agentFilter`, `sessionFilter` + +Slack auto-enables native exec approvals when `enabled` is unset or `"auto"` and at least one +approver resolves. Set `enabled: false` to disable Slack as a native approval client explicitly. +Set `enabled: true` to force native approvals on when approvers resolve. + +Default behavior with no explicit Slack exec approval config: ```json5 { - approvals: { - exec: { - enabled: true, - targets: [{ channel: "slack", to: "U12345678" }], + commands: { + ownerAllowFrom: ["slack:U12345678"], + }, +} +``` + +Explicit Slack-native config is only needed when you want to override approvers, add filters, or +opt into origin-chat delivery: + +```json5 +{ + channels: { + slack: { + execApprovals: { + enabled: true, + approvers: ["U12345678"], + target: "both", + }, }, }, } ``` +Shared `approvals.exec` forwarding is separate. Use it only when approval prompts must also route +to other chats or explicit out-of-band targets. + Same-chat `/approve` also works in Slack channels and DMs that already support commands. See [Exec approvals](/tools/exec-approvals) for the full approval forwarding model. ## Troubleshooting diff --git a/docs/channels/telegram.md b/docs/channels/telegram.md index 87c245a9c4c..a5ad77d65b0 100644 --- a/docs/channels/telegram.md +++ b/docs/channels/telegram.md @@ -810,7 +810,7 @@ openclaw message poll --channel telegram --target -1001234567890:topic:42 \ - `channels.telegram.execApprovals.target` (`dm` | `channel` | `both`, default: `dm`) - `agentFilter`, `sessionFilter` - Approvers must be numeric Telegram user IDs. Telegram becomes an exec approval client when `enabled` is true and at least one approver can be resolved, either from `execApprovals.approvers` or from the account's numeric owner config (`allowFrom` and direct-message `defaultTo`). Approval requests otherwise fall back to other configured approval routes or the exec approval fallback policy. + Approvers must be numeric Telegram user IDs. Telegram auto-enables native exec approvals when `enabled` is unset or `"auto"` and at least one approver can be resolved, either from `execApprovals.approvers` or from the account's numeric owner config (`allowFrom` and direct-message `defaultTo`). Set `enabled: false` to disable Telegram as a native approval client explicitly. Approval requests otherwise fall back to other configured approval routes or the exec approval fallback policy. Telegram also renders the shared approval buttons used by other chat channels. The native Telegram adapter mainly adds approver DM routing, channel/topic fanout, and typing hints before delivery. diff --git a/docs/help/faq.md b/docs/help/faq.md index c78ce0b5f56..96d8e99968d 100644 --- a/docs/help/faq.md +++ b/docs/help/faq.md @@ -173,6 +173,27 @@ Quick answers plus deeper troubleshooting for real-world setups (local dev, VPS, + + They control different layers: + + - `approvals.exec`: forwards approval prompts to chat destinations + - `channels..execApprovals`: makes that channel act as a native approval client + + The host exec policy is still the real approval gate. Chat config only controls where approval + prompts appear and how people can answer them. + + In most setups you do **not** need both: + + - If the chat already supports commands and replies, same-chat `/approve` works through the shared path. + - If a supported native channel can infer approvers safely, OpenClaw now auto-enables DM-first native approvals when `channels..execApprovals.enabled` is unset or `"auto"`. + - Use `approvals.exec` only when prompts must also be forwarded to other chats or explicit ops rooms. + - Use `channels..execApprovals.target: "channel"` or `"both"` only when you explicitly want approval prompts posted back into the originating room/topic. + + Short version: forwarding is for routing, native client config is for richer channel-specific UX. + See [Exec Approvals](/tools/exec-approvals). + + + Node **>= 22** is required. `pnpm` is recommended. Bun is **not recommended** for the Gateway. diff --git a/docs/tools/exec-approvals.md b/docs/tools/exec-approvals.md index c4792380fc8..6420e9b7365 100644 --- a/docs/tools/exec-approvals.md +++ b/docs/tools/exec-approvals.md @@ -485,24 +485,46 @@ resolved approver list for authorization even when native approval delivery is d ### Native approval delivery -Discord, Slack, and Telegram can also act as native approval-delivery adapters with channel-specific config. +Some channels can also act as native approval clients. Native clients add approver DMs, origin-chat +fanout, and channel-specific interactive approval UX on top of the shared same-chat `/approve` +flow. + +Generic model: + +- host exec policy still decides whether exec approval is required +- `approvals.exec` controls forwarding approval prompts to other chat destinations +- `channels..execApprovals` controls whether that channel acts as a native approval client + +Native approval clients auto-enable DM-first delivery when all of these are true: + +- the channel supports native approval delivery +- approvers can be resolved from explicit `execApprovals.approvers` or existing owner config +- `channels..execApprovals.enabled` is unset or `"auto"` + +Set `enabled: false` to disable a native approval client explicitly. Set `enabled: true` to force +it on when approvers resolve. Public origin-chat delivery stays explicit through +`channels..execApprovals.target`. + +FAQ: [Why are there two exec approval configs for chat approvals?](/help/faq#why-are-there-two-exec-approval-configs-for-chat-approvals) - Discord: `channels.discord.execApprovals.*` -- Slack: uses shared `approvals.exec.targets` with `channel: "slack"` and renders Block Kit approval buttons when interactivity is enabled +- Slack: `channels.slack.execApprovals.*` - Telegram: `channels.telegram.execApprovals.*` -These native delivery adapters are opt-in. They add DM routing and channel fanout on top of the -shared same-chat `/approve` flow and the shared approval buttons. +These native approval clients add DM routing and optional channel fanout on top of the shared +same-chat `/approve` flow and shared approval buttons. Shared behavior: - Slack, Matrix, Microsoft Teams, and similar deliverable chats use the normal channel auth model for same-chat `/approve` +- when a native approval client auto-enables, the default native delivery target is approver DMs - for Discord and Telegram, only resolved approvers can approve or deny - Discord and Telegram approvers can be explicit (`execApprovals.approvers`) or inferred from existing owner config (`allowFrom`, plus direct-message `defaultTo` where supported) +- Slack approvers can be explicit (`execApprovals.approvers`) or inferred from `commands.ownerAllowFrom` - the requester does not need to be an approver - the originating chat can approve directly with `/approve` when that chat already supports commands and replies -- when channel delivery is enabled, approval prompts include the command text +- when native `target` enables origin-chat delivery, approval prompts include the command text - pending exec approvals expire after 30 minutes by default - if no operator UI or configured approval client can accept the request, the prompt falls back to `askFallback`