Vai al contenuto principale
Quando una regola del firewall restituisce il verdetto pending_approval, la chiamata a tool dell’agent viene messa in attesa anziché dispatchata — ora sta aspettando un umano. Questa pagina è per il revisore: come approvare gli hold delle chiamate a tool degli agent (o rifiutarli) dalla console, cosa ti mostra la coda, e come OrcaRouter impedisce a due revisori di collidere sulla stessa decisione. È la metà di risoluzione dell’human-in-the-loop. Per il perché una chiamata viene messa in attesa e come l’agent in attesa ri-invia in seguito, vedi verdetti e il più approfondito riferimento delle approvazioni. Per risolvere dal tuo sistema invece che dalla console, vedi webhook di approvazione.

1. Il ciclo di vita di una chiamata in attesa, dal posto di un revisore

Una chiamata in attesa è un breve loop fuori banda. Il tuo compito è lo step centrale:
1

La chiamata viene messa in attesa

Una regola si risolve in pending_approval. Il relay restituisce HTTP 400 con codice firewall_approval_pending e un id di approvazione; la chiamata non raggiunge mai il tool. L’agent inizia a fare polling su quell’id.
2

Tu la risolvi

Apri la coda Approvals, leggi perché la chiamata è stata messa in attesa, e la approvi o la rifiuti — il focus di questa pagina.
3

L'agent procede (o si ferma)

All’approvazione, l’agent ri-invia la chiamata originale con un header monouso X-OrcaRouter-Firewall-Approval e il gateway la lascia passare quell’unica volta. Al rifiuto, la chiamata rimane bloccata.
Risolvere un hold è gated a Developer+ — lo stesso gate del feed Events del firewall. I ruoli inferiori possono leggere policy, impostazioni e discovered tools del firewall, ma solo i ruoli Developer-e-superiori possono elencare la coda di approvazione o approvare/rifiutare una chiamata a tool in attesa. Vedi ruoli e scope.

2. Elenca la coda in attesa

La scheda Approvals legge GET /api/workspace/firewall/approvals. Senza filtro restituisce la coda pending, dalla più vecchia — così la chiamata che aspetta da più tempo sta in cima e lavori il backlog in ordine.
GET /api/workspace/firewall/approvals?state=pending
state è l’unico filtro che conta. I valori mappano sul ciclo di vita dell’approvazione:
stateApprovazioni restituite
pending (default)In attesa, in attesa di una decisione — la tua coda di lavoro.
approvedGià fatte passare.
rejectedGià bloccate.
Questa è una rotta di console sulla tua sessione — configurala e revisionala dal dashboard, non con una chiave di relay sk-orca-…. Le chiavi di relay sono per le chiamate al modello /v1/*; la gestione del firewall gira sotto il tuo login di console.

3. Leggi perché la chiamata è stata messa in attesa

Ogni riga porta gli input di decisione di cui un revisore ha bisogno — il nome del tool (tool_name), un’impronta degli argomenti (args_hash, lo SHA-256 degli argomenti della chiamata canonicalizzati — i valori grezzi degli argomenti non sono memorizzati nell’approvazione), il request id, e una riga di provenienza in inglese semplice che nomina la policy, la regola e la clausola che è scattata:
La policy nominata a cui appartiene la regola corrisposta, risolta con scope sul workspace così un id stantio non può mai far emergere il nome di policy di un altro tenant.
L’etichetta della regola e un descrittore “perché” su una riga — es. command contains rm -rf, o tool matches "http_fetch" per una regola solo-glob. Questo rende la riga “Held because…” nella coda.
true quando la regola corrisposta è stata modificata a partire da quando questa approvazione è stata creata. L’etichetta e la clausola live vengono allora soppresse (potrebbero non riflettere più ciò che ha effettivamente messo in attesa la chiamata), e la coda mostra una nota “rule since changed” anziché una provenienza stantia. Il nome del tool e gli argomenti — i veri input di decisione — sono sempre mostrati.
rule_changed è un segnale di onestà deliberato, non un errore. Se qualcuno modifica la regola del firewall mentre una chiamata sta nella coda, OrcaRouter preferisce nascondere una motivazione possibilmente-sbagliata anziché mostrarti una provenienza che non corrisponde più. Decidi in base al nome del tool e al nome della policy (ancora mostrati) in quel caso.

4. Approva o rifiuta

Risolvere invia PATCH /api/workspace/firewall/approvals/:id con un decision di approved o rejected e un reason opzionale. La console lo fa per te quando clicchi il pulsante; la forma è:
PATCH /api/workspace/firewall/approvals/507f1f77bcf86cd799439011
Content-Type: application/json

{ "decision": "approved", "reason": "verified target host with the on-call" }
  • approved → la chiamata in attesa può procedere. Il prossimo ri-invio dell’agent, che porta l’header di approvazione monouso, viene fatto passare una volta.
  • rejected → la chiamata rimane bloccata. L’agent vede il rifiuto e può scegliere un altro percorso, chiedere all’utente o fermarsi.
decision è validato rispetto all’insieme chiuso {approved, rejected} — qualsiasi altra cosa viene rifiutata. Il reason è registrato con la decisione e scritto nel log di audit del firewall insieme all’attore, al nome del tool e al request id.
Ogni risoluzione scrive una riga di audit del workspace che nomina chi ha deciso, la decisione e la motivazione. Le risoluzioni di console registrano l’attore umano; le risoluzioni via webhook registrano un attore di sistema. La provenienza della risoluzione non viene mai silenziosamente scartata.

5. First-writer-wins: nessuna doppia risoluzione

Un’approvazione in attesa può andare in race — due revisori nella console, o un clic di console e un webhook callback che arrivano insieme. OrcaRouter risolve questo con una singola regola first-writer-wins:
  • La decisione è un update condizionale atomico che scatta solo finché l’approvazione è ancora pending. Il primo writer vince e applica la decisione.
  • Ogni writer successivo osserva “già risolta” ed è trattato come un no-op idempotente — ottiene HTTP 200 con il documento già risolto, non un errore.
La risposta ti dice da che parte eri:
{
  "resolved": false,
  "already_resolved": true,
  "approval": { "state": "approved", "decision": "approved", "...": "..." }
}
resolved: true significa che la tua chiamata ha applicato la decisione; already_resolved: true significa che qualcuno (o qualche webhook) è arrivato prima e stai vedendo il suo esito. In ogni caso la coda si riconcilia a uno stato coerente.
Poiché la risoluzione è idempotente, una rete instabile o un doppio clic non può corrompere un hold o ribaltare una decisione. La prima approvazione/rifiuto è l’unica che conta; tutto ciò che viene dopo si limita a rileggere il risultato.

6. Un passaggio concreto attraverso la coda

Un workspace ad autonomia balanced mette in attesa la chiamata shell.exec di un agent perché una regola ha corrisposto command contains rm -rf. Come revisore tu:
  1. Apri Approvals — la shell.exec in attesa sta in cima alla lista pending dalla più vecchia.
  2. Leggi la riga: tool shell.exec, l’impronta args_hash, il request id, e la riga “Held because… command contains rm -rf” (resa dalla clausola della regola corrisposta). Nessun flag rule_changed, quindi la provenienza è attuale.
  3. Il target è una directory scratch, quindi approvi con una motivazione.
  4. Il tuo PATCH restituisce resolved: true; il prossimo polling dell’agent vede approved, ri-invia con il suo header monouso, e il comando gira esattamente una volta.
Se un compagno di team l’avesse approvata un secondo prima, il tuo clic avrebbe restituito already_resolved: true con la loro decisione — nessun danno, nessuna doppia esecuzione.

Dove andare dopo

Riferimento delle approvazioni

Il loop HITL completo: hold, polling, ri-invio e l’header monouso.

Webhook di approvazione

Risolvi gli hold dal tuo sistema con un callback firmato con HMAC.

Verdetti

Dove si colloca pending_approval tra i sei verdetti del firewall.

Log degli eventi

Conferma l’esito a valle di una chiamata risolta nel feed.
Per i rischi che questi hold sono pensati per catturare, vedi chiamate a tool pericolose e agenzia eccessiva.