pending_approval, o gateway
retém a chamada de ferramenta e notifica seu próprio sistema de aprovação fora de
banda. Essa notificação é um HTTP POST assinado — o payload de webhook de
firewall — e esta página documenta seu formato exato para que você possa
verificar a assinatura, rotear o evento e postar sua decisão de volta.
Este é o irmão assíncrono do fluxo de aprovação no console descrito na página de
Firewall. O caminho de console
(um revisor clica aprovar/rejeitar) não precisa de webhook algum. O webhook é
para quando você quer que uma máquina — seu próprio bot de ticketing, ação de
Slack ou runtime de agente — resolva o hold. Ambos os caminhos são
first-writer-wins, então você pode rodá-los lado a lado.
O webhook é um sinal de roteamento de melhor esforço, não o canal HITL
autoritativo. O próprio long-poll do agente em
GET /api/v1/firewall/approvals/:id
é o backstop — se uma notificação for perdida ou seu endpoint estiver brevemente
fora do ar, a chamada retida ainda aparece no console e resolve normalmente. O
webhook apenas deixa uma máquina reagir mais rápido do que um humano reagiria.1. O payload de webhook de firewall em resumo
O OrcaRouter faz POST de um envelope JSON para a URL que você configura, assinado com um segredo compartilhado. Aqui está uma entrega completa — headers e corpo:X-Orca-Event sem fazer parse do corpo.
2. Campos do envelope
event — o nome do evento
event — o nome do evento
Sempre
firewall.approval.pending para um hold de aprovação. Espelhado no
header X-Orca-Event para que você possa rotear antes de fazer parse do
corpo.workspace_id — o workspace de origem
workspace_id — o workspace de origem
O id inteiro do workspace cuja política reteve a chamada. Útil quando um
endpoint recebe webhooks de vários workspaces.
occurred_at — quando o hold foi criado
occurred_at — quando o hold foi criado
Timestamp RFC 3339 / UTC (precisão de nanossegundos) de quando o gateway
enfileirou a aprovação. Parseável por qualquer ferramenta de evento padrão.
data — o payload de aprovação
data — o payload de aprovação
O bloco que seu callback precisa para resolver o portão. Campos em
§3.
3. O payload data
O bloco data carrega tudo que é necessário para rotear e resolver o hold —
deliberadamente sem argumentos de ferramenta. O webhook é um sinal de
roteamento; o contexto completo da chamada (ferramenta, args, a regra que
disparou) vive na aba Approvals do console e no log de auditoria, onde tem
controle de acesso.
| Campo | Tipo | Significado |
|---|---|---|
approval_id | string | O id contra o qual você posta sua decisão. |
tool_name | string | A ferramenta retida, ex.: db.export. |
request_id | string | A requisição de relay que disparou o hold. |
conversation_id | string | O id da conversa / sessão do agente. |
policy_id | int | A política de firewall que correspondeu. |
rule_id | int | A regra que retornou pending_approval. |
4. Verificando a assinatura
Toda entrega é assinada para que você possa rejeitar falsificações. O header de assinatura é:secret é o segredo de webhook de aprovação que você define no workspace e
raw_body são os bytes exatos do corpo da requisição. Compute o HMAC sobre
os bytes brutos — re-serializar o JSON parseado mudará o whitespace e quebrará a
comparação. Verifique em tempo constante:
5. Configurando o webhook
A URL de destino e o segredo compartilhado são configurações de workspace — defina-os uma vez no console (ou via a API de settings; Developer+). Não há envolvimento de operador e nada a fazer deploy.Defina a URL e o segredo
Nas configurações de Firewall, defina seu endpoint HTTPS como a URL de
webhook de aprovação e um segredo compartilhado forte. A URL deve ser
https:// — destinos em texto puro são rejeitados — e o segredo é
somente-escrita (ele nunca é retornado na leitura; a resposta de settings só
reporta se um está definido).Crie uma regra pending_approval
Adicione uma regra de Firewall cujo veredito é
pending_approval (ou use o
preset HITL). Veja Regras de firewall.Receba e verifique
Seu endpoint recebe o POST assinado na próxima chamada retida. Verifique a
assinatura (§4), depois resolva via o callback
ou exponha-a para um humano.
Uma chamada retida ainda funciona com nenhum webhook configurado — ela apenas
aparece no console para um humano resolver. E se você definir uma URL mas nenhum
segredo, o gateway pula o dispatch inteiramente, porque o endpoint de callback só
aceita requisições assinadas: uma notificação que você não conseguisse
autenticar de volta seria inútil.
6. O callback: resolvendo o hold
Para aprovar ou rejeitar por máquina, faça POST de volta para::id que você recebeu como approval_id, assinado com o mesmo
segredo compartilhado. O corpo é uma decisão:
| Campo do corpo | Obrigatório | Valores |
|---|---|---|
decision | sim | approved ou rejected |
reason | não | Nota em texto livre, registrada no log de auditoria. |
approved deixa a próxima tentativa do agente passar uma vez — o
agente reenvia a chamada original com um header de uso único
X-OrcaRouter-Firewall-Approval. Uma decisão rejected mantém a chamada
bloqueada.
A resolução é idempotente e first-writer-wins. Se um humano já resolveu o
hold a partir do console — ou um callback duplicado chega — o endpoint retorna
200 com already_resolved: true e a decisão original prevalece. Seguro para
retry.7. Estados de aprovação
Uma chamada retida passa por estes estados; seu callback aciona a transição para fora depending:
| Estado | Significado |
|---|---|
pending | Aguardando uma decisão (o estado no momento do webhook). |
approved | Resolvida — a chamada bloqueada pode prosseguir uma vez. |
rejected | Resolvida — a chamada bloqueada permanece bloqueada. |
expired | O hold expirou sem uma decisão. |
8. Referências relacionadas
Firewall — fluxo HITL
Como
pending_approval retém uma chamada e o agente reenvia com o header de
aprovação de uso único.Códigos de erro
firewall_approval_pending e as outras respostas HTTP do firewall.Glossário de vereditos
Cada veredito de firewall, incluindo
pending_approval.API de Firewall
A referência completa de rotas de console + gateway.
