跳轉到主要內容
當一條防火牆規則傳回 pending_approval 裁決時,代理的工具呼叫會被 保留而非被派發——它現在在等待一個人類。本頁是給審查者的:如何 從主控台批准代理工具呼叫保留(或拒絕它們)、佇列向你顯示什麼, 以及 OrcaRouter 如何防止兩位審查者在同一個決定上相撞。 這是人工介入的解決那一半。關於一個呼叫為何被保留,以及被保留的 代理之後如何重新提交,參見 裁決與更深入的 審批參考。要從你自己的系統而非 主控台解決,參見審批 webhook

1. 被保留呼叫的生命週期,從一位審查者的位置

一個被保留的呼叫是一個短暫的頻道外迴圈。你的工作是中間那一步:
1

呼叫被保留

一條規則解析為 pending_approval。中繼傳回 HTTP 400,帶有 代碼 firewall_approval_pending 與一個審批 id;該呼叫永遠不抵達 工具。代理開始輪詢那個 id。
2

你解決它

你開啟 Approvals 佇列、讀取該呼叫為何被保留,並批准拒絕它——本頁的重點。
3

代理繼續(或停止)

在批准時,代理帶著一個一次性的 X-OrcaRouter-Firewall-Approval 標頭重新提交原始呼叫,而閘道讓它通過那一次。在拒絕時,該呼叫 保持被封鎖。
解決一個保留把關到 Developer+——與防火牆 Events 動態相同的閘門。 較低的角色可以讀取防火牆政策、設定與 discovered tools,但只有 Developer 及以上的角色能列出審批佇列或批准/拒絕一個被保留的工具 呼叫。參見角色與範圍

2. 列出待處理佇列

Approvals 分頁讀取 GET /api/workspace/firewall/approvals。沒有篩選時, 它傳回 pending 佇列,最舊在前——所以等待最久的呼叫坐在頂端, 而你依序處理積壓。
GET /api/workspace/firewall/approvals?state=pending
state 是那個重要的篩選。各值對應到審批的生命週期:
state傳回的審批
pending (預設)已保留,等待一個決定——你的工作佇列。
approved已讓通過。
rejected已封鎖。
這是你工作階段上的一個主控台路由——從儀表板設定並審查它,而不是 用一個 sk-orca-… 中繼金鑰。中繼金鑰是給 /v1/* 模型呼叫的;防火牆 管理在你的主控台登入下執行。

3. 讀取呼叫為何被保留

每一列攜帶一位審查者需要的決策輸入——工具名稱tool_name)、 一個引數指紋args_hash,正規化後呼叫引數的 SHA-256——原始 引數值不儲存在審批中)、請求 id,以及一行指名觸發的政策、規則 與子句的白話來源行:
匹配到的規則所屬的命名政策,以工作區範圍解析,所以一個過時的 id 絕不會浮現另一個租戶的政策名稱。
規則的標籤與一行「為何」描述符——例如 command contains rm -rf, 或對一個僅 glob 的規則為 tool matches "http_fetch"。這渲染佇列中 的「Held because…」那一行。
當匹配到的規則在這個審批被建立時或之後被編輯時為 true。 即時的標籤與子句接著會被抑制(它們可能不再反映實際保留了該呼叫 的東西),而佇列會改顯示一個「rule since changed」備註而非過時的 來源。工具名稱與引數——真正的決策輸入——總是會被顯示。
rule_changed 是一個刻意的誠實訊號,而非一個錯誤。如果有人在一個 呼叫坐在佇列中時編輯了防火牆規則,OrcaRouter 寧願隱藏一個可能錯誤 的原因,也不向你顯示一個不再相符的來源。在那種情況下,根據工具 名稱與政策名稱(仍會顯示)做決定。

4. 批准或拒絕

解決會發送 PATCH /api/workspace/firewall/approvals/:id,帶有一個 approvedrejecteddecision 與一個可選的 reason。當你 點擊按鈕時主控台會為你做這個;其形狀是:
PATCH /api/workspace/firewall/approvals/507f1f77bcf86cd799439011
Content-Type: application/json

{ "decision": "approved", "reason": "verified target host with the on-call" }
  • approved → 被保留的呼叫可以繼續。代理的下一次重新提交,攜帶 那個一次性的審批標頭,會被讓通過一次。
  • rejected → 該呼叫保持被封鎖。代理看見該拒絕並能挑選另一條 路徑、詢問使用者,或停止。
decision 會對照封閉的 {approved, rejected} 集合驗證——任何其他 東西都會被拒絕。reason 會與決定一起被記錄,並與行為者、工具名稱 與請求 id 一起寫入防火牆稽核記錄。
每一次解決都會寫入一筆工作區稽核列,指名誰決定、決定為何,以及 原因。主控台解決記錄人類行為者; webhook 解決記錄一個 系統行為者。解決來源絕不會被靜默丟棄。

5. 先寫者勝出:沒有重複解決

一個待處理的審批可能被競爭——主控台中的兩位審查者,或一次主控台 點擊與一個webhook 回呼 同時抵達。OrcaRouter 以一個單一的先寫者勝出規則解決這個:
  • 該決定是一個原子性的條件式更新,只在審批仍是 pending 時觸發。 第一個寫者勝出並套用該決定。
  • 每個稍後的寫者觀察到「已解決」,並被當作一個冪等的 no-op——它 得到 HTTP 200 與已解決的文件,而非一個錯誤。
回應告訴你你在哪一側:
{
  "resolved": false,
  "already_resolved": true,
  "approval": { "state": "approved", "decision": "approved", "...": "..." }
}
resolved: true 意味著你的呼叫套用了該決定;already_resolved: true 意味著有某人(或某個 webhook)先到那裡了,而你看見的是他們的 結果。無論哪種方式,佇列都調和到一個一致的狀態。
由於解決是冪等的,一個不穩定的網路或一次雙擊無法損壞一個保留或 翻轉一個決定。第一個批准/拒絕是唯一算數的;在它之後的一切只是 讀回結果。

6. 一次具體地走過佇列

一個 balanced 自主的工作區因為一條規則匹配 command contains rm -rf 而保留一個代理的 shell.exec 呼叫。作為審查者,你:
  1. 開啟 Approvals——被保留的 shell.exec 坐在最舊在前的 pending 清單頂端。
  2. 讀取該列:工具 shell.execargs_hash 指紋、請求 id,以及 「Held because… command contains rm -rf」那一行(從匹配到的規則 子句渲染)。沒有 rule_changed 旗標,所以來源是當前的。
  3. 目標是一個暫存目錄,所以你帶著一個原因批准
  4. 你的 PATCH 傳回 resolved: true;代理的下一次輪詢看見 approved、帶著它的一次性標頭重新提交,而該指令正好執行一次。
要是一位隊友早一秒批准了它,你的點擊就會帶著他們的決定傳回 already_resolved: true——沒有傷害、沒有重複執行。

接下來去哪裡

審批參考

完整的 HITL 迴圈:保留、輪詢、重新提交,以及一次性標頭。

審批 webhook

用一個 HMAC 簽署的回呼從你自己的系統解決保留。

裁決

pending_approval 在六個防火牆裁決中坐落的位置。

事件記錄

在動態中確認一個已解決呼叫的下游結果。
關於這些保留意在捕捉的風險,參見 危險的工具呼叫過度代理權