pending_approval, the tool call is held and
your agent waits. By default a reviewer clears that hold from the console.
The firewall approval webhook wires the same gate into your system:
the gateway POSTs a signed notification to your endpoint the moment a call
is held, and your system POSTs an HMAC-signed decision back to release it —
no console seat, no polling a human.
This is the async (callback) half of human-in-the-loop. The held call, the
verdict, and the console resolve path are covered in
Resolve approvals and the
Firewall reference; this page is
just the webhook wiring.
The webhook is a fast-path heads-up, not the system of record. The
relay’s long-poll on the held call is the authoritative gate — if a
notification is dropped or your receiver is down, the hold still stands and
a reviewer can clear it from the console. Configuring the webhook only adds
a programmatic way to resolve it.
1. When to use a firewall approval webhook
Reach for it when a human-in-the-loop firewall gate has to be resolved by something other than a person clicking a button:Route to your own approvals UI
Push held tool calls into Slack, PagerDuty, or an internal review queue
and resolve them where your team already works.
Programmatic policy
Auto-approve a held
db.query against a read replica, auto-reject one
against prod — your code decides, the gateway enforces.2. Configure it in the console
Both halves live on one workspace setting. Open Firewall → Settings and fill in two fields (a Developer+ action — the settings write is role-gated):Approval webhook URL — where we notify you
Approval webhook URL — where we notify you
The
https:// endpoint we POST to when a call is held. HTTP is refused,
and the URL is run through an SSRF preflight on save, so a loopback,
private-range, or cloud-metadata destination is rejected before it can
be stored. Leave it empty to disable the async path entirely.Shared secret — how both sides authenticate
Shared secret — how both sides authenticate
3. The notification we send you
When a call is held, we POST a signed JSON envelope to your URL:approval_id you need to resolve and identifiers to correlate, never the
tool arguments. The argument detail lives in the
Approvals queue and the firewall
events log.
4. The callback you POST back
To release (or reject) the hold, POST your decision to the callback endpoint with theapproval_id from the notification:
decision is approved or rejected — no other value is accepted.
reason is optional and shows up on the resolved approval’s audit trail.
The callback is first-decision-wins and idempotent: whoever resolves
first — your webhook or a console reviewer — sets the outcome, and a repeat
callback for an already-resolved approval returns 200 so your system
stops retrying.
5. Releasing the held call
Resolving the approval doesn’t replay the tool call for you — it lifts the gate so your agent can re-issue it. The agent runtime:- Polls the hold’s state at
GET /api/v1/firewall/approvals/:id(a firewall-gateway-scoped key, not your relay key or console session) until it leavespending. - On
approved, re-submits the original tool call carrying a single-useX-OrcaRouter-Firewall-Approvalheader — the gateway lets that one call through and the token is spent.
If the underlying rule was edited after the call was held, the
Approvals queue flags that the
rule has since changed and suppresses the now-stale “held because…”
clause, so a console reviewer doesn’t act on provenance that no longer
matches what held the call.
6. Verify the wiring
A quick end-to-end check before you depend on it:| Step | What to do | Expected |
|---|---|---|
| Hold a call | Trigger a rule with a pending_approval verdict | 400 firewall_approval_pending |
| Notification | Watch your endpoint | Signed firewall.approval.pending POST arrives |
| Callback | POST a signed { "decision": "approved" } | 200 with the resolved state |
| Replay guard | POST the callback again | 200, already resolved (no double-apply) |
7. Where this fits
Resolve approvals
The console reviewer path and the full held-call lifecycle.
Verdicts
Where
pending_approval comes from and how it composes with other
verdicts.Gateway keys
Mint the firewall-gateway-scoped key the poll + re-submit flow needs.
Excessive agency
The threat human-in-the-loop gates are built to contain.
