Przejdź do głównej treści
Gdy reguła Firewall zwraca werdykt pending_approval, brama wstrzymuje wywołanie narzędzia i powiadamia twój własny system zatwierdzeń poza pasmem. To powiadomienie to podpisany HTTP POST — firewall webhook payload — a ta strona dokumentuje jego dokładny kształt, abyś mógł zweryfikować sygnaturę, skierować zdarzenie i wysłać swoją decyzję z powrotem. To asynchroniczny brat przepływu zatwierdzeń w konsoli opisanego na stronie Firewall. Ścieżka konsoli (recenzent klika zatwierdź/odrzuć) nie potrzebuje żadnego webhooka. Webhook jest dla sytuacji, gdy chcesz, by maszyna — twój własny bot ticketowy, akcja Slack lub środowisko wykonawcze agenta — rozstrzygnęła wstrzymanie. Obie ścieżki są first-writer-wins, więc możesz uruchamiać je obok siebie.
Webhook to sygnał routingu o najlepszym wysiłku, nie autorytatywny kanał HITL. Własne długie odpytywanie agenta na GET /api/v1/firewall/approvals/:id jest zabezpieczeniem — jeśli powiadomienie zostanie zgubione lub twój endpoint jest na chwilę wyłączony, wstrzymane wywołanie i tak pojawia się w konsoli i rozwiązuje się normalnie. Webhook po prostu pozwala maszynie zareagować szybciej, niż zrobiłby człowiek.

1. Ładunek firewall webhook w skrócie

OrcaRouter wysyła POST z kopertą JSON na URL, który skonfigurujesz, podpisaną współdzielonym sekretem. Oto kompletna dostawa — nagłówki i ciało:
POST /your-approval-endpoint HTTP/1.1
Content-Type: application/json
X-Orca-Event: firewall.approval.pending
X-Orca-Signature: sha256=9f86d0818988...c2c9a3e1b4d7

{
  "event": "firewall.approval.pending",
  "workspace_id": 42,
  "occurred_at": "2026-06-09T12:00:00.123456789Z",
  "data": {
    "approval_id": "665f1a2b3c4d5e6f7a8b9c0d",
    "tool_name": "db.export",
    "request_id": "req_01J9X...",
    "conversation_id": "conv_8f2a...",
    "policy_id": 7,
    "rule_id": 31
  }
}
Koperta ma ten sam kształt, którego OrcaRouter używa dla każdego podpisanego zdarzenia, więc jeden odbiorca może kierować wiele typów zdarzeń na podstawie X-Orca-Event bez parsowania ciała.

2. Pola koperty

Zawsze firewall.approval.pending dla wstrzymania zatwierdzenia. Odbite w nagłówku X-Orca-Event, abyś mógł kierować przed parsowaniem ciała.
Całkowite id przestrzeni roboczej, której polityka wstrzymała wywołanie. Przydatne, gdy jeden endpoint odbiera webhooki z kilku przestrzeni roboczych.
Znacznik czasu RFC 3339 / UTC (precyzja nanosekundowa) dla momentu, w którym brama zakolejkowała zatwierdzenie. Parsowalny przez dowolne standardowe narzędzia zdarzeń.
Blok, którego twój callback potrzebuje, by rozstrzygnąć bramkę. Pola w §3.

3. Ładunek data

Blok data niesie wszystko potrzebne, by skierować i rozstrzygnąć wstrzymanie — celowo bez argumentów narzędzia. Webhook to sygnał routingu; pełny kontekst wywołania (narzędzie, argumenty, reguła, która odpaliła) żyje w zakładce Approvals konsoli i logu audytu, gdzie jest kontrolowany dostępem.
PoleTypZnaczenie
approval_idstringId, względem którego wysyłasz swoją decyzję.
tool_namestringWstrzymane narzędzie, np. db.export.
request_idstringŻądanie relay, które wywołało wstrzymanie.
conversation_idstringId konwersacji / sesji agenta.
policy_idintPolityka firewalla, która dopasowała.
rule_idintReguła, która zwróciła pending_approval.
Potrzebujesz argumentów lub dopasowanej klauzuli, by podjąć decyzję? Odczytaj je z zakładki Approvals konsoli (Developer+) lub niech twój agent odpyta GET /api/v1/firewall/approvals/:id swoim tokenem bramy. Webhook celowo nigdy nie niesie argumentów po drucie.

4. Weryfikacja sygnatury

Każda dostawa jest podpisana, abyś mógł odrzucać podróbki. Nagłówek sygnatury to:
X-Orca-Signature: sha256=<hex HMAC-SHA256(secret, raw_body)>
gdzie secret to sekret webhooka zatwierdzeń, który ustawisz na przestrzeni roboczej, a raw_body to dokładne bajty ciała żądania. Oblicz HMAC nad surowymi bajtami — ponowna serializacja sparsowanego JSON zmieni białe znaki i zepsuje porównanie. Weryfikuj w stałym czasie:
import hmac, hashlib

def verify(raw_body: bytes, header: str, secret: str) -> bool:
    expected = "sha256=" + hmac.new(
        secret.encode(), raw_body, hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(expected, header)
Sygnatura webhooka wychodzącego pokrywa tylko ciało. Przychodzący callback, który wysyłasz z powrotem (§6), podpisuje approval_id + znak nowej linii + ciało — inna konstrukcja, na cel, aby przechwycona sygnatura nie mogła być powtórzona między zatwierdzeniami. Nie używaj ponownie jednej procedury podpisującej dla obu kierunków.

5. Konfiguracja webhooka

Docelowy URL i współdzielony sekret to ustawienia przestrzeni roboczej — ustaw je raz w konsoli (lub przez API ustawień; Developer+). Nie ma zaangażowania operatora ani niczego do wdrożenia.
1

Ustaw URL i sekret

W ustawieniach Firewall ustaw swój endpoint HTTPS jako URL webhooka zatwierdzeń oraz mocny współdzielony sekret. URL musi być https:// — cele w postaci jawnej są odrzucane — a sekret jest tylko-do-zapisu (nigdy nie jest zwracany przy odczycie; odpowiedź ustawień raportuje tylko, czy jest ustawiony).
2

Zautoruj regułę pending_approval

Dodaj regułę Firewall, której werdyktem jest pending_approval (lub użyj presetu HITL). Zobacz Reguły Firewall.
3

Odbierz i zweryfikuj

Twój endpoint odbiera podpisany POST przy następnym wstrzymanym wywołaniu. Zweryfikuj sygnaturę (§4), a potem albo rozstrzygnij przez callback, albo wystaw to dla człowieka.
Wstrzymane wywołanie działa też z żadnym skonfigurowanym webhookiem — po prostu pojawia się w konsoli dla człowieka do rozstrzygnięcia. A jeśli ustawisz URL, ale nie sekret, brama pomija dyspozycję całkowicie, ponieważ endpoint callbacku akceptuje tylko podpisane żądania: powiadomienie, którego nie mógłbyś uwierzytelnić z powrotem, byłoby bezużyteczne.

6. Callback: rozstrzyganie wstrzymania

Aby zatwierdzić lub odrzucić maszynowo, wyślij POST z powrotem na:
POST /api/v1/firewall/approvals/:id/callback
z tym samym :id, które odebrałeś jako approval_id, podpisanym tym samym współdzielonym sekretem. Ciało to decyzja:
BODY='{"decision":"approved","reason":"ticket OPS-4821 approved by on-call"}'
SIG="sha256=$(printf '%s\n%s' "$APPROVAL_ID" "$BODY" \
  | openssl dgst -sha256 -hmac "$SECRET" -hex | sed 's/^.* //')"

curl https://api.orcarouter.ai/api/v1/firewall/approvals/$APPROVAL_ID/callback \
  -H "Content-Type: application/json" \
  -H "X-Orca-Signature: $SIG" \
  -d "$BODY"
Pole ciałaWymaganeWartości
decisiontakapproved lub rejected
reasonnieNotatka tekstowa, zapisana w logu audytu.
Decyzja approved przepuszcza następną próbę agenta jeden raz — agent ponownie wysyła oryginalne wywołanie z jednorazowym nagłówkiem X-OrcaRouter-Firewall-Approval. Decyzja rejected utrzymuje wywołanie zablokowane.
Rozstrzygnięcie jest idempotentne i first-writer-wins. Jeśli człowiek już rozstrzygnął wstrzymanie z konsoli — lub przybywa zduplikowany callback — endpoint zwraca 200 z already_resolved: true, a oryginalna decyzja obowiązuje. Bezpieczne do ponawiania.

7. Stany zatwierdzenia

Wstrzymane wywołanie przechodzi przez te stany; twój callback napędza przejście z pending:
StanZnaczenie
pendingOczekuje na decyzję (stan w czasie webhooka).
approvedRozstrzygnięte — bramkowane wywołanie może przejść raz.
rejectedRozstrzygnięte — bramkowane wywołanie zostaje zablokowane.
expiredWstrzymanie przeterminowało się bez decyzji.

8. Powiązane referencje

Firewall — przepływ HITL

Jak pending_approval wstrzymuje wywołanie, a agent ponownie wysyła z jednorazowym nagłówkiem zatwierdzenia.

Kody błędów

firewall_approval_pending i pozostałe odpowiedzi HTTP firewalla.

Słownik werdyktów

Każdy werdykt firewalla, w tym pending_approval.

API Firewall

Pełna referencja tras konsoli + bramy.
Po to, jak wstrzymania pasują do szerszego modelu kontrolnego, zobacz Tryby egzekwowania i Niebezpieczne wywołania narzędzi.