Passer au contenu principal
Quand une règle de firewall renvoie pending_approval, l’appel d’outil est mis en attente et votre agent attend. Par défaut, un relecteur lève cette mise en attente depuis la console. Le webhook d’approbation firewall câble la même porte dans votre système : la passerelle POSTe une notification signée à votre endpoint au moment où un appel est mis en attente, et votre système POSTe une décision signée HMAC en retour pour le libérer — aucun siège de console, aucune interrogation d’un humain. C’est la moitié async (callback) du human-in-the-loop. L’appel mis en attente, le verdict et le chemin de résolution par console sont couverts dans Résoudre les approbations et la référence du Firewall ; cette page n’est que le câblage du webhook.
Le webhook est un avertissement fast-path, pas le système de référence. Le long-poll du relais sur l’appel mis en attente est la porte qui fait autorité — si une notification est abandonnée ou que votre récepteur est en panne, la mise en attente tient toujours et un relecteur peut la lever depuis la console. Configurer le webhook ne fait qu’ajouter une façon programmatique de le résoudre.

1. Quand utiliser un webhook d’approbation firewall

Recourez-y quand une porte firewall human-in-the-loop doit être résolue par autre chose qu’une personne cliquant un bouton :

Router vers votre propre UI d'approbations

Poussez les appels d’outils mis en attente dans Slack, PagerDuty, ou une file de revue interne et résolvez-les là où votre équipe travaille déjà.

Politique programmatique

Auto-approuver un db.query mis en attente contre un read replica, auto-rejeter un contre prod — votre code décide, la passerelle applique.

2. Le configurer dans la console

Les deux moitiés vivent sur un réglage d’espace de travail. Ouvrez Firewall → Settings et remplissez deux champs (une action Developer+ — l’écriture des réglages est filtrée par rôle) :
L’endpoint https:// auquel nous POSTons quand un appel est mis en attente. HTTP est refusé, et l’URL passe par un préflight SSRF à l’enregistrement, de sorte qu’une destination loopback, en plage privée ou cloud-metadata est rejetée avant de pouvoir être stockée. Laissez-le vide pour désactiver entièrement le chemin async.
Un secret HMAC en écriture seule (jusqu’à 255 caractères). Il signe notre notification sortante et authentifie votre callback entrant. La console ne le renvoie jamais en écho — une fois enregistré, vous voyez seulement qu’un secret est défini ; faites une rotation en écrivant une nouvelle valeur.
L’endpoint de callback est HMAC uniquement. Tant qu’un secret partagé n’est pas défini, la passerelle ne délivrera pas de notifications et rejette chaque callback — la porte ne peut être levée que depuis la console. Définissez le secret pour activer le chemin async.
Vous préférez l’API REST ? Les mêmes champs se mettent à jour via la route des réglages de la console (UserAuth, Developer+) :
curl -X PUT https://api.orcarouter.ai/api/workspace/firewall/settings \
  -H "Authorization: Bearer $ORCA_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
        "approval_webhook_url": "https://hooks.example.com/orca/firewall",
        "approval_webhook_secret": "whsec_your_shared_secret"
      }'

3. La notification que nous vous envoyons

Quand un appel est mis en attente, nous POSTons une enveloppe JSON signée à votre URL :
POST /orca/firewall HTTP/1.1
Content-Type: application/json
X-Orca-Event: firewall.approval.pending
X-Orca-Signature: sha256=<hex>
{
  "event": "firewall.approval.pending",
  "workspace_id": 42,
  "occurred_at": "2026-06-09T17:04:11.482Z",
  "data": {
    "approval_id": "665f1b...",
    "tool_name": "db.query",
    "request_id": "req_9f2c...",
    "conversation_id": "conv_77a1...",
    "policy_id": 7,
    "rule_id": 31
  }
}
L’enveloppe est un signal de routage, pas le contexte complet — elle porte l’approval_id dont vous avez besoin pour résoudre et des identifiants pour corréler, jamais les arguments de l’outil. Le détail des arguments vit dans la file d’approbations et le journal d’événements du firewall.
Vérifiez la signature sortante avant de faire confiance au payload : X-Orca-Signature est sha256= + le hex HMAC-SHA256(secret, raw_body) sur les octets exacts que vous avez reçus. Comparez en temps constant. La livraison est at-least-once et réessayée en cas d’échecs transitoires, donc rendez votre handler idempotent sur approval_id.

4. Le callback que vous POSTez en retour

Pour libérer (ou rejeter) la mise en attente, POSTez votre décision à l’endpoint de callback avec l’approval_id de la notification :
POST /api/v1/firewall/approvals/665f1b.../callback
X-Orca-Signature: sha256=<hex>
Content-Type: application/json

{ "decision": "approved", "reason": "read-replica query, auto-approved" }
decision est approved ou rejected — aucune autre valeur n’est acceptée. reason est optionnel et apparaît sur la piste d’audit de l’approbation résolue.
La signature du callback est liée à l’id d’approbation, de sorte qu’une signature capturée ne peut pas être rejouée contre un appel mis en attente différent. Signez la chaîne <approval_id> + un saut de ligne littéral (\n) + le corps de requête brut :
X-Orca-Signature = "sha256=" + HMAC_SHA256(secret, approval_id + "\n" + body)
Cela diffère de la notification sortante, qui signe le corps seul. Un callback dont la signature ne se vérifie pas reçoit 401 — et un id d’approbation manquant, non concordant ou inexistant renvoie le même 401, de sorte que l’endpoint ne confirme jamais si un id existe.
Le callback est first-decision-wins et idempotent : celui qui résout en premier — votre webhook ou un relecteur de console — définit le résultat, et un callback répété pour une approbation déjà résolue renvoie 200 de sorte que votre système cesse de réessayer.

5. Libérer l’appel mis en attente

Résoudre l’approbation ne rejoue pas l’appel d’outil pour vous — cela lève la porte pour que votre agent puisse le ré-émettre. Le runtime de l’agent :
  1. Interroge l’état de la mise en attente à GET /api/v1/firewall/approvals/:id (une clé scopée à la passerelle firewall, pas votre clé de relais ni votre session console) jusqu’à ce qu’elle quitte pending.
  2. Sur approved, re-soumet l’appel d’outil d’origine portant un en-tête X-OrcaRouter-Firewall-Approval à usage unique — la passerelle laisse passer cet unique appel et le token est dépensé.
Si la règle sous-jacente a été éditée après que l’appel a été mis en attente, la file d’approbations signale que la règle a depuis changé et supprime la clause « held because… » désormais périmée, de sorte qu’un relecteur de console n’agit pas sur une provenance qui ne correspond plus à ce qui a mis l’appel en attente.

6. Vérifier le câblage

Une vérification rapide de bout en bout avant de vous y fier :
ÉtapeQuoi faireAttendu
Mettre un appel en attenteDéclencher une règle avec un verdict pending_approval400 firewall_approval_pending
NotificationSurveiller votre endpointUn POST signé firewall.approval.pending arrive
CallbackPOSTer un { "decision": "approved" } signé200 avec l’état résolu
Garde anti-rejeuPOSTer le callback à nouveau200, déjà résolue (pas de double application)
Si la notification n’arrive jamais, confirmez que le secret est défini (sans lui la passerelle ne délivrera pas) et que l’URL a passé les vérifications HTTPS + SSRF au moment de l’enregistrement.

7. Où cela s’insère

Résoudre les approbations

Le chemin du relecteur de console et le cycle de vie complet d’un appel mis en attente.

Verdicts

D’où vient pending_approval et comment il se compose avec les autres verdicts.

Clés de passerelle

Frappez la clé scopée à la passerelle firewall dont le flux interrogation
  • re-soumission a besoin.

Agence excessive

La menace que les portes human-in-the-loop sont conçues pour contenir.
Pour le modèle de verdict, les surfaces d’application et le reste du firewall, voir la référence du Firewall.