- Exec Approvals: OpenClaw’s command-execution gate. One request reaches you two ways at once. It arrives live over your own tab’s Gateway connection, and Clawboo’s server separately mirrors it into the shared
tool_call_approvalstable as akind='exec'row, which is what keeps the card alive when no tab is open. Either card resolves back through the Gateway, and, when the agent is known, the decision is also logged to Clawboo’s history table. - Native
run_commandapprovals: a Clawboo Native Boo asking to run one program, on a Boo whose shell you switched on. These are Clawboo’s own rows end to end, and none of them is ever remembered. - The shared tool-approval queue: Clawboo’s own database-mediated handshake for brokered tool calls and risky delegations. The same queue (and the same resolve buttons) is reused by the Governance dashboard, so there is one resolve path, not two.
Prerequisites
There is no standalone Approvals nav view. Approvals surface where they were raised, so you resolve them in context rather than on a separate screen. Whether anything appears at all depends on whether an agent is configured to ask before acting.
- Approvals appear in two places, both always available:
- The Needs you column on the board, the first column, under Approval pending. The column is always expanded; it also holds tasks that failed or stalled and are waiting on you.
- An inline tray above the composer in group chat and 1:1 agent chat, scoped to that team or agent (capped at three cards, with a “view on the board” link for the rest).
- For exec approvals to appear, the agent’s command-execution policy must be set to ask. Open an OpenClaw agent, go to the Permissions tab → Execution Permissions, and set Command Execution to Always Ask or Ask for Unknown. Then ask the agent to run a command. It pauses and the request appears here. See command permissions for what each posture means.
- For native
run_commandapprovals to appear, the Boo’s shell must be switched on (Permissions tab → Running commands) and the run must have a working folder, which in practice means a board task. Every native Boo created through Clawboo’s own screens starts with that switch off. - For tool / delegation approvals, no extra setup is needed; the broker writes a pending row when a risky or availability-gated tool call needs sign-off, and the governance delegation gate writes one for a risky delegation.
Steps
1. Find the pending items and read them
Every surface is scoped. On the board, when a team is selected, exec approvals are filtered to that team’s agents (requests with noagentId always show); selecting no team shows all. The chat tray is scoped to the team or agent you have open. Exec approvals are sorted oldest-first.
Each exec approval card shows:
- An amber “Exec Approval” label with a pulsing alert dot.
- The owning agent’s name and a live
expires Nscountdown. It counts down to the deadline the Gateway sent with the request; when a request arrives without one, Clawboo holds the mirrored card for 30 minutes. - The command in a code block, plus any of
cwd,host,path, andsecurityas detail rows, and an error line if the request carried one.
- The app’s logo and name when the call goes through a connector, otherwise the agent’s name, and a live
expires Nscountdown. - A one-sentence headline in the second person naming the actor and the effect, plus a short factual chip. The chip states what the call does and never reassures: an action is classified from its verb as reads, sends, changes or destroys, and an unrecognised verb falls to
changesrather than toreads, so a call can never resolve downward into looking safer than it is. - The decisive fields inline (who it is addressed to, what it is about, which file or record), with the rest behind one disclosure. Credential-shaped values are masked before display.
- The agent’s own words, quoted and attributed, when it supplied a reason. They are never used as the headline.
2. Resolve each item
Every card carries an allow and a deny, and, where the decision can be remembered at all, a way to say so. The live exec card in your own tab has three buttons (Allow Once, Always, Deny). A card from Clawboo’s own queue has two buttons plus an Always checkbox you tick before pressing allow, and on a command card the allow button reads Run it rather than “Allow”.
What happens under the hood differs by surface:
- Exec approval. The decision goes to the Gateway via
exec.approval.resolve, then (when the agent is known) is persisted to Clawboo’s history throughPOST /api/approvals. The card buttons disable while the decision is in flight. After an allow, Clawboo runs a deterministic followup to recover the command’s output in webchat-only setups where the Gateway’s own delivery would otherwise drop it. One caveat: a decision made from a tab that has no Gateway socket of its own still reaches the Gateway, but writes noapproval_historyrecord and runs no output-recovery followup. The decision lands; the history entry does not. - Tool / delegation approval. The decision is written to the
tool_call_approvalsrow viaPOST /api/tools/approvals/:id/resolve. The broker (or the delegation gate) is long-polling that row in another process, so it unblocks the moment you resolve. The queue re-polls every 3 seconds, so the card clears on its own.
Resolving the same tool/delegation row twice is a no-op; the resolve is guarded on
status='pending', so a stale double-click can’t flip an already-decided approval. Answering the same exec card twice is safe as well: the second answer comes back as alreadyResolved rather than an error, and an exec approval that has already expired Gateway-side resolves silently (the card just disappears) rather than showing a confusing error.3. Watch the per-Boo indicator
While a Boo has an exec approval pending, its node in the Ghost Graph shows a pulsing amber ring around the circle. The ring is matched byagentId, so it points at exactly the Boo waiting on you. It clears the instant you resolve.
An exec approval outlives your browser tab
Clawboo’s server keeps its own long-lived connection to the Gateway and declares, as a browser tab does, that it can answer exec approvals. When a request arrives it mirrors it into the shared queue as akind='exec' row, keyed by the Gateway’s own request id, which is what makes a redelivered request land on the card that is already there instead of a duplicate.
What that buys you:
- Close the tab while a command is waiting and the card is still there when you come back.
- Refresh mid-decision and you get the same card, not a second one.
- Open a tab halfway through the window and the waiting command is already in the queue.
- Before this, a browser tab was the only connection that could answer, so a command raised with no tab open was not queued for later. It was refused outright, reported as
exec denied: Headless runs cannot wait for interactive exec approval.
- The countdown is the deadline the Gateway sent with the request. When a request arrives without one, Clawboo holds the mirrored card for 30 minutes, the window it expects the Gateway to be using.
- Once that passes, a sweep running every 30 seconds retires the row to
expired. Deliberately not todeny: nobody answered, and recording an expiry as a denial would claim a human refused something nobody was asked about.
Native run_command approvals
A Clawboo Native Boo can ask to run a program, but only when you have switched that on for it (Permissions tab → Running commands) and only on a run that has a working folder, which in practice means a board task. On 1:1 chat, team-room turns, dispatch turns, and on Windows, the tool is absent rather than gated, so nothing asks. It raises the same command card a mirrored exec request does. The headline names the Boo and says it wants to run a command on this computer, the chip reads Runs a command, the Command and the Folder sit inline rather than behind the disclosure, and the allow button reads Run it. What is different about it:- Run it or Don’t allow, and nothing else. There is no allowlist at this tier, so Always is never offered. A command you allow today asks again the next time, because an “Always” that behaved as an allow-once would be a control that lies.
- The card does not tell you why. The Boo supplies a one-sentence reason with the call and Clawboo stores it on the row, but the command card does not display it. What you see is the command and the folder.
- The card is held for 10 minutes, and the run makes no other progress while it waits. A card nobody answers blocks the task for the full window.
- Ten commands per run. After ten asks in one driver run the tool refuses to ask again. That ceiling is per driver run, not per task, so a task that is re-driven starts again at zero.
- Declining can end the task, not just the command. A refusal latches the tool for the rest of that run, and a second attempt trips the host circuit breaker, which aborts the board task.
- It leaves no tool-audit row. A
run_commandexecution is not written to the tool audit, so it does not appear inGET /api/tools/audit.
What the cards report
Exec approval card
A card restored from Clawboo’s own queue deliberately carries less than the live one.
host, security, the resolved path and the session key are null rather than invented, so what you get back is the command and the folder.
Tool / delegation card
The two surfaces overlap now. They still speak different decision strings: an exec decision is
allow-once / allow-always / deny (with hyphens) and is logged to approval_history, while a tool or delegation decision is allow_once / allow_always / deny (with underscores) and is written to the tool_call_approvals row. What is no longer true is that they write different tables. A mirrored exec request is itself a tool_call_approvals row, carrying kind='exec', and a native run_command request is a row in that same table under the ordinary kind='tool'. The buttons read the same in the UI; the wire values differ.When Always is offered
Always is not on every card, and the card you are looking at decides it.
On a mirrored exec card the answer is worked out on the server when the request arrives, not guessed at render time. Always is offered only when both of these hold, and withheld when either fails:
- The request’s
askis notalways. A Boo set to Always Ask is a Boo that can never remember a command, so offering the button would be a control that lies. - The request’s
unavailableDecisionslist does not containallow-always. That is the Gateway’s own statement about this particular request.
Tool availability (read-only)
Under the queue, the panel lists every broker tool with an Available / Unavailable pill, sourced fromGET /api/tools. A tool is unavailable when an availability requirement (auth, config, env, or plugin) is unmet; the card greys out and its tooltip shows the diagnostics. A non-safe risk tool also shows an amber warning icon. This is informational; there are no actions here; it tells you which brokered tools an agent can actually reach.
Verify it worked
- The resolved card disappears from the board’s Needs you column (its amber count drops by one, and the column reads “Nothing needs you right now” once nothing is left) and from any in-chat tray. For an exec approval, the Boo’s amber ring also clears in the Ghost Graph.
- For an exec allow, the agent resumes and (after the followup) reports the command’s output back into the chat transcript.
- For a tool/delegation approval, the waiting tool call / delegation proceeds (on allow) or is rejected (on deny) within a few seconds.
- The decision history is queryable:
GET /api/approvals?agentId=<id>returns the persisted exec-approval decisions for that agent (most recent first).
Troubleshooting
Always outlives the run. For a tool approval it mints a standing rule bound to the grant the call was made under, covering any arguments for that tool, and it expires after 30 days: a rule with no expiry would be a permission nobody revisits. Revoking the grant deletes its rules, so a later re-grant cannot silently inherit approvals you gave under different circumstances. Use Allow Once when you want to keep the gate for next time.For an exec approval, Always is no longer a one-way door. The Gateway remembers the command, and what it remembered is listed under Commands this Boo can run without asking on the Boo’s Permissions tab, where you can revoke it. See command permissions for what each entry means, what revoking warns you about, and what it cannot reach. There is still no undo for the command that already ran.Sometimes there is no Always at all. Which card you are looking at decides it, and a native
run_command card never offers it. The cases are listed in When Always is offered above.Related
- Governance, how budgets, circuit breakers, caps, and approvals form the guardrail layer
- Command permissions, the standing grants an exec Always creates, and how to take one back
- Governance dashboard, reuses the same tool-approval queue
- The Ghost Graph, where the per-Boo pending-approval ring renders
/api/governancereference, the/api/approvals,/api/tools/approvals, and delegation-approval shapes