Chuyển đến nội dung chính
Khi một quy tắc Firewall trả về verdict pending_approval, gateway giữ cuộc gọi tool lại và thông báo cho hệ thống phê duyệt của riêng bạn out-of-band. Thông báo đó là một HTTP POST đã ký — payload webhook firewall — và trang này tài liệu hóa hình dạng chính xác của nó để bạn có thể xác minh chữ ký, định tuyến event, và post quyết định của bạn trở lại. Đây là người anh em bất đồng bộ của luồng phê duyệt trong-console được mô tả trên trang Firewall. Đường console (một người duyệt nhấp approve/reject) không cần webhook nào cả. Webhook là để khi bạn muốn một cỗ máy — ticketing bot, Slack action, hoặc agent-runtime của riêng bạn — giải quyết lần giữ. Cả hai đường đều first-writer-wins, nên bạn có thể chạy chúng song song.
Webhook là một tín hiệu định tuyến best-effort, không phải kênh HITL có thẩm quyền. Long-poll của chính agent trên GET /api/v1/firewall/approvals/:id là phương án dự phòng — nếu một thông báo bị rớt hoặc endpoint của bạn tạm thời ngừng, cuộc gọi đã giữ vẫn nổi lên trong console và giải quyết bình thường. Webhook chỉ cho phép một cỗ máy phản ứng nhanh hơn con người.

1. Payload webhook firewall trong nháy mắt

OrcaRouter POST một JSON envelope tới URL bạn cấu hình, ký bằng một shared secret. Đây là một lần gửi hoàn chỉnh — header và body:
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
  }
}
Envelope có cùng hình dạng mà OrcaRouter dùng cho mọi event đã ký, nên một receiver có thể định tuyến nhiều kiểu event dựa trên X-Orca-Event mà không cần parse body.

2. Các trường của envelope

Luôn là firewall.approval.pending cho một lần giữ phê duyệt. Được phản chiếu trong header X-Orca-Event để bạn có thể định tuyến trước khi parse body.
Id số nguyên của workspace mà chính sách của nó giữ cuộc gọi. Hữu ích khi một endpoint nhận webhook từ nhiều workspace.
Timestamp RFC 3339 / UTC (độ chính xác nanosecond) cho thời điểm gateway xếp hàng lần phê duyệt. Parse được bởi bất kỳ công cụ event tiêu chuẩn nào.
Khối mà callback của bạn cần để giải quyết cổng. Các trường ở §3.

3. Payload data

Khối data mang theo mọi thứ cần để định tuyến và giải quyết lần giữ — có chủ đích không có argument tool. Webhook là một tín hiệu định tuyến; ngữ cảnh cuộc gọi đầy đủ (tool, args, quy tắc đã kích hoạt) sống trong tab Approvals của console và audit log, nơi nó được kiểm soát truy cập.
TrườngKiểuÝ nghĩa
approval_idstringId bạn post quyết định của mình đối với nó.
tool_namestringTool đã giữ, vd: db.export.
request_idstringRequest relay đã kích hoạt lần giữ.
conversation_idstringId cuộc trò chuyện / phiên của agent.
policy_idintChính sách firewall đã khớp.
rule_idintQuy tắc đã trả về pending_approval.
Cần các argument hoặc mệnh đề đã khớp để ra quyết định? Đọc chúng từ tab Approvals của console (Developer+), hoặc cho agent của bạn poll GET /api/v1/firewall/approvals/:id với gateway token của nó. Webhook có chủ đích không bao giờ mang args qua đường truyền.

4. Xác minh chữ ký

Mọi lần gửi đều được ký để bạn có thể từ chối các giả mạo. Header chữ ký là:
X-Orca-Signature: sha256=<hex HMAC-SHA256(secret, raw_body)>
trong đó secret là approval-webhook secret bạn đặt trên workspace và raw_bodyđúng các byte của body request. Tính HMAC trên các byte thô — re-serialize JSON đã parse sẽ thay đổi whitespace và phá vỡ phép so sánh. Xác minh trong thời gian hằng số:
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)
Chữ ký webhook đi ra chỉ bao phủ body. Callback đi vào bạn post lại (§6) ký approval_id + một newline + body — một cấu trúc khác, có chủ đích, để một chữ ký bị bắt không thể phát lại giữa các lần phê duyệt. Đừng tái sử dụng một routine ký cho cả hai hướng.

5. Cấu hình webhook

URL đích và shared secret là các settings của workspace — đặt chúng một lần trong console (hoặc qua settings API; Developer+). Không có sự tham gia của operator và không có gì để triển khai.
1

Đặt URL và secret

Trong settings Firewall, đặt endpoint HTTPS của bạn làm URL webhook phê duyệt và một shared secret mạnh. URL phải là https:// — các đích plaintext bị từ chối — và secret là chỉ-ghi (nó không bao giờ được trả về khi đọc; phản hồi settings chỉ báo cáo liệu một cái có được đặt hay không).
2

Soạn một quy tắc pending_approval

Thêm một quy tắc Firewall mà verdict của nó là pending_approval (hoặc dùng preset HITL). Xem Quy tắc firewall.
3

Nhận và xác minh

Endpoint của bạn nhận POST đã ký ở lần giữ tiếp theo. Xác minh chữ ký (§4), rồi hoặc giải quyết qua callback hoặc làm nổi nó lên cho một con người.
Một cuộc gọi đã giữ vẫn hoạt động với không webhook nào được cấu hình — nó chỉ hiện ra trong console để một con người giải quyết. Và nếu bạn đặt một URL nhưng không có secret, gateway bỏ qua hoàn toàn việc dispatch, vì endpoint callback chỉ chấp nhận các request đã ký: một thông báo mà bạn không thể xác thực trở lại sẽ vô dụng.

6. Callback: giải quyết lần giữ

Để approve hoặc reject bằng cỗ máy, POST lại tới:
POST /api/v1/firewall/approvals/:id/callback
với cùng :id bạn nhận được dưới dạng approval_id, ký bằng cùng shared secret. Body là một quyết định:
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"
Trường bodyBắt buộcGiá trị
decisionapproved hoặc rejected
reasonkhôngGhi chú văn bản tự do, ghi vào audit log.
Một quyết định approved cho lần thử tiếp theo của agent đi qua một lần — agent gửi lại cuộc gọi gốc với một header dùng một lần X-OrcaRouter-Firewall-Approval. Một quyết định rejected giữ cuộc gọi bị chặn.
Việc giải quyết là idempotent và first-writer-wins. Nếu một con người đã giải quyết lần giữ từ console — hoặc một callback trùng lặp đến — endpoint trả về 200 với already_resolved: true và quyết định gốc vẫn giữ nguyên. An toàn để retry.

7. Các trạng thái phê duyệt

Một cuộc gọi đã giữ di chuyển qua các trạng thái này; callback của bạn điều khiển chuyển đổi ra khỏi pending:
Trạng tháiÝ nghĩa
pendingĐang chờ một quyết định (trạng thái lúc webhook).
approvedĐã giải quyết — cuộc gọi bị cổng có thể tiến hành một lần.
rejectedĐã giải quyết — cuộc gọi bị cổng vẫn bị chặn.
expiredLần giữ hết hạn mà không có quyết định.

8. Tham chiếu liên quan

Firewall — luồng HITL

Cách pending_approval giữ một cuộc gọi và agent gửi lại với header phê duyệt dùng một lần.

Mã lỗi

firewall_approval_pending và các phản hồi HTTP firewall khác.

Bảng thuật ngữ verdict

Mọi verdict firewall, bao gồm pending_approval.

Firewall API

Tham chiếu route console + gateway đầy đủ.
Về cách các lần giữ khớp với mô hình kiểm soát rộng hơn, xem Chế độ thực thiCuộc gọi tool nguy hiểm.