規則
匹配語言——工具 glob、引數子句、egress 清單、
淨化器與序列。
MCP 伺服器
在單一受稽核的閘道後方註冊並治理 Model Context Protocol 伺服器。
技能
在你的代理安裝的能力能夠執行之前,掃描它們並為其評定風險分數。
1. 什麼是防火牆
AI 代理不只是產生文字——它會行動。它會呼叫shell.exec、
查詢 db.query、擷取一個 URL、載入一個社群技能,或透過
第三方 MCP 伺服器路由一次工具呼叫。其中每一項都是具有
真實世界後果的動作,而提示詞層級的防護欄看不見它們。
防火牆是一個工作區層級的、命名的政策,閘道會在
每次工具呼叫時對它進行評估。你撰寫一次政策,將一個 API 金鑰綁定
到它(或將其中一個設為工作區預設值),從此該金鑰發出的每一次工具
呼叫都會在抵達工具之前被對照該政策檢查。
每個政策是一份有序的規則清單。一條規則決定一件事——
它套用於哪些工具呼叫(一個工具名稱 glob,可選擇性地限定到某個
技能與某個強制執行介面),以及要對它們做什麼(一個
裁決:allow、audit、deny、sanitize、保留待審批,或設定成本
上限)。引擎會按優先順序走訪規則,第一個匹配者勝出,
若無任何匹配則回退到政策的預設裁決。
編輯政策會在下次呼叫時對綁定到它的每個金鑰生效。
無需重新部署。無需修改代理程式碼。政策在閘道處強制執行
——你的代理像以前一樣繼續發出工具呼叫。
偵測發生在閘道處,於首次使用時。 防火牆位於
LLM 中繼路徑上,而不是在你代理的套件管理器或
檔案系統內部。代理自行安裝的工具、MCP 伺服器或技能,會在
其呼叫首次穿越閘道時被捕捉——而不是在安裝時。這是
刻意設計:它是那個唯一能看見每一個供應商、每一個
代理與每一次工具呼叫的咽喉要道,無論該能力是如何進來的。
2. 四個強制執行介面
每一次工具呼叫都會對照恰好一個介面進行評估——即 防火牆在請求生命週期中看見它的那個點:| 介面 | 它看見什麼 |
|---|---|
inbound | 代理在請求上向模型公告的工具(工具定義)。讓你能在模型甚至無法選擇某個危險工具之前就將其封鎖。 |
response | 模型在其回覆中發出的 tool_calls。 |
mcp | 透過 防火牆 MCP 閘道派發或透過 SDK hook 評估的 tools/call。 |
egress | 由某工具回報的外送網路目的地(host / IP / CIDR)——SSRF 與資料外洩介面。 |
3. 核心概念
| 概念 | 定義 |
|---|---|
| 政策 | 一組命名的、工作區層級的規則。具有 enabled、is_default、一個 default_verdict 以及一個 shadow_mode 旗標。 |
| 規則 | 政策內的一項檢查:一個優先順序、一個工具/技能匹配、一個可選的介面、一個可選的引數判定式,以及一個裁決。參見 規則。 |
| 裁決 | 一條規則(或預設值)所產生的動作——參見 §4。 |
| 預設裁決 | 在無任何規則匹配時套用。為 allow、audit(預設)或 deny 之一。 |
| 影子模式(Shadow mode) | 政策會評估並記錄,但永不封鎖——每個強制執行的裁決都會被降級為 audit,原因會被加上前綴 [shadow] would …。你的安全上線開關。 |
| 觀察模式(Observe mode) | 一個工作區層級的設定。當一個請求解析出沒有政策且觀察模式開啟時,呼叫會被允許但記錄為一個涵蓋缺口——這就是填充 Discovered-tools 檢視的東西。 |
範圍限定與解析
政策的解析方式與防護欄和 API 金鑰完全一致——當你有作用中的 工作區時為工作區共享。對任何工具呼叫,閘道會按此順序解析政策:- 金鑰綁定——如果呼叫的金鑰有
firewall_policy_id,則套用該 政策(當它存在且已啟用時)。 - 工作區預設值——否則套用工作區已啟用的
is_default政策。 - 兩者皆無——不執行任何強制。在觀察模式開啟時,呼叫會被 允許並記錄為一個缺口;在它關閉時,呼叫會被靜默允許 (與從未啟用此功能的工作區位元組完全一致)。
對未知事物失敗開放(fail-open),對模稜兩可的事物失敗關閉(fail-closed)。 如果政策
解析遇到暫時性錯誤,閘道會降級為 observe/allow,
而不是讓流量中斷。但在不強制執行就會使規則失效之處
——一份沒有可用目的地的 egress 回報、一個無法觸及的審批儲存
、一個無法解析其擁有權的技能——引擎會
失敗關閉(deny 或 hold)。可用性得以保留;在那些重要的情況下,
安全性不會被靜默跳過。
4. 裁決
一條規則(或預設裁決)會產生以下其中之一:| 裁決 | 作用 |
|---|---|
allow | 讓呼叫通過。會被記錄。 |
audit | 允許,但記錄下來以供審查。預設的 default_verdict——觀察一切、封鎖無物,直到你準備好為止。 |
deny | 封鎖呼叫。代理會看到一個工具錯誤(或在 inbound 介面上看到 HTTP 400)。 |
sanitize | 從工具引數中遮罩匹配到的子字串(密鑰、PII),並轉送清理後的呼叫。參見 淨化器。在 inbound 介面上——那裡尚無呼叫時引數——sanitize 會升級為封鎖。 |
pending_approval | 為人類保留該呼叫。代理會得到一個「保留中」的回應;審查者在頻道外批准或拒絕;代理再帶著一次性的審批權杖重新提交。參見 §7。 |
cap_cost | 一旦代理執行的累計花費超過每規則的分(cents)上限就拒絕。一個用於失控迴圈的斷路器。 |
deny / sanitize / pending_approval 全都會被降級
為 audit,讓你能在某政策改變流量之前先衡量它的影響。
5. 一次工具呼叫如何被評估
- 一次工具呼叫抵達閘道(在 inbound 公告、在回應中發出、 透過 MCP 閘道派發,或被回報為 egress)。
- 引擎解析作用中的政策(§3)。
- 它按優先順序走訪政策的規則(優先順序較低者 先;同分時以規則 id 決定)。當一條規則的介面、它的 工具名稱 glob、它可選的技能名稱 glob、它可選的引數 子句,以及它可選的 egress 範圍全都匹配時,該規則才匹配。
- 第一個匹配者勝出 → 套用該規則的裁決。若無任何規則匹配 →
政策的
default_verdict。 - 如果該呼叫由一個受治理的技能擁有,
則該技能的強制執行模式會疊加套用於其上——處於
block模式的技能會強制 deny;處於quarantine模式的技能會將任何 未達 deny 的裁決升級為pending_approval。 - 決策會被記錄為一個防火牆事件(除非它是一次乾跑), 並與該代理執行和工作階段相關聯。
6. 封鎖的樣子
在 inbound 介面上被拒絕的呼叫會傳回 HTTP 400,帶有一個 OpenAI 形狀的錯誤主體、錯誤代碼firewall_blocked,以及一條
指明工具與原因的訊息——例如 tool "shell.exec" blocked by firewall: destructive shell command。該錯誤會攜帶結構化的
metadata(原因代碼、風險因子、分數),並被標記為 skip-retry
(重跑同一個呼叫只會再次被封鎖)。
透過 MCP 閘道派發的呼叫會被封鎖為一個工具錯誤
(firewall deny: <reason>),而不是傳輸失敗,因此模型
會看到該拒絕並能做出反應——選擇另一個工具、詢問使用者,或
停止——而不是崩潰。
一個被保留的呼叫(pending_approval)會傳回 HTTP 400,帶有代碼
firewall_approval_pending 以及一個客戶端用於輪詢的審批 id。
7. 人工審批(HITL)
一個pending_approval 裁決會把一次工具呼叫變成一次頻道外的審查:
- 引擎將一筆審批記錄排入佇列,並傳回一個攜帶其 id 的 「保留中」回應;該呼叫不會抵達工具。
- 一位審查者解決它——從主控台(Developer+),或透過一個 HMAC 簽署的 webhook 回呼到你自己的審批系統。
- 你的代理(或 MCP SDK)對該審批 id 進行輪詢;一旦獲批,它
會帶著一次性的
X-OrcaRouter-Firewall-Approval標頭重新提交原始 呼叫,閘道便會讓它通過那一次。
rule_changed,好讓審查者知道
情境已經改變。
8. 自主等級——一個開關掌控你的整體姿態
逐條規則調校政策是精確的路徑;自主等級則是 快速的路徑。單一控制項會在一次交易中以一鍵還原的方式,原子性地 取代你工作區的防火牆與防護欄姿態:| 等級 | 姿態 |
|---|---|
tight | 封鎖破壞性 shell、引數中的密鑰,以及 SSRF egress(預設 deny);開啟 PII Shield + Secrets Blocker 防護欄;觀察模式關閉。 |
balanced | 稽核破壞性 shell、標記 PII;觀察模式關閉。建議的起始姿態。 |
permissive | 沒有強制執行的政策,沒有防護欄;觀察模式開啟,因此你仍然能看見一切。 |
9. 異常偵測
在靜態規則之外,防火牆會學習每個工作區正常的工具使用 形態,並在一個檢視者可讀的動態上標記偏差:- 速率/成本飆升——每個工具的活動會被對照一個習得的
週小時基線(一個 14 天的滾動平均)評分,所以即使每次呼叫
各自都被允許,「週日凌晨 3 點的 100 次
db.query呼叫」仍會顯得突兀。 retry_loop——一個代理反覆敲打同一個失敗的工具。novel_path——這個工作區從未做過的一次工具到工具的轉移。
10. 可觀測性
防火牆會留下你可以採取行動的軌跡,全部都是工作區層級的:| 介面 | 它給你什麼 |
|---|---|
| Events | 每一次評估,可按裁決、介面、工具、執行與工作階段篩選。其他一切背後的原始記錄。 |
| Runs & sessions | 按代理執行或對話彙整的事件——裁決細分、不同的工具與模型、首次/最近一次出現。「這個代理實際上做了什麼」的檢視。 |
| Discovered tools | 工作區看過的每一個工具,標記為 covered(有規則套用)或 gap(沒有任何規則套用)。從真實流量驅動政策撰寫。 |
| Simulate | 在你套用某個自主等級之前,預覽它會改變什麼。 |
| Test | 對一個樣本工具呼叫乾跑一個政策,並查看裁決、匹配到的規則與原因——不持久化任何東西,不派發任何東西。 |
| Audit | 每一次政策、規則與設定變更都會在變更提交之後寫入一筆稽核列(工作區 + 中央)。密鑰與規則 blob 永不被記錄。 |
11. 與閘道其他部分的關係
12. 將一個代理連接到防火牆閘道
工具呼叫抵達引擎有兩種方式:- MCP 閘道——將你的 MCP 客戶端(Claude Desktop、Cursor、一個
代理框架)指向
https://api.orcarouter.ai/api/v1/firewall/mcp。 閘道會公開每個可觸及的已註冊伺服器的工具,以<server>.<tool>命名空間化,並就地評估每一次tools/call。參見 MCP 伺服器。 - Evaluate hook——在派發一次工具呼叫之前,從你自己的
代理迴圈呼叫
POST /api/v1/firewall/evaluate,並依裁決行動。
403。
13. API 參考
所有主控台路由都透過工作區情境進行工作區限定,並一致地 強制執行 RBAC:讀取與 test/simulate 沙盒對每個成員開放; 寫入需要 Developer+。政策與設定
| 方法與路徑 | 角色 | 用途 |
|---|---|---|
GET /api/workspace/firewall/settings | Member | 讀取工作區防火牆設定(觀察模式、預設值)。 |
PUT /api/workspace/firewall/settings | Developer+ | 更新設定。 |
GET /api/workspace/firewall/policies | Member | 列出政策(含規則 + 已綁定金鑰計數)。 |
GET /api/workspace/firewall/policies/:id | Member | 單個政策詳情。 |
POST /api/workspace/firewall/policies | Developer+ | 建立一個政策。 |
PUT /api/workspace/firewall/policies | Developer+ | 更新一個政策。 |
DELETE /api/workspace/firewall/policies/:id | Developer+ | 刪除一個政策(若仍有金鑰綁定則回傳 409)。 |
姿態、預設集與沙盒
| 方法與路徑 | 角色 | 用途 |
|---|---|---|
GET /api/workspace/firewall/presets | Member | 內建規則預設集。 |
POST /api/workspace/firewall/autonomy | Developer+ | 套用一個自主等級。 |
POST /api/workspace/firewall/autonomy/undo/:audit_id | Developer+ | 還原一次自主變更。 |
GET /api/workspace/firewall/simulate | Member | 預覽一個自主等級(?level=)。 |
POST /api/workspace/firewall/test | Developer+ | 對一個樣本工具呼叫乾跑一個政策。 |
可觀測性
| 方法與路徑 | 角色 | 用途 |
|---|---|---|
GET /api/workspace/firewall/discovered-tools | Member | 看過的工具,標記為 covered / gap。 |
GET /api/workspace/firewall/events | Developer+ | 列出防火牆事件(可篩選)。 |
GET /api/workspace/firewall/events/by-request/:request_id | Developer+ | 一個請求的事件。 |
GET /api/workspace/firewall/events/aggregate | Developer+ | Runs / sessions 彙整。 |
GET /api/workspace/firewall/trace/by-run | Developer+ | 一次執行的追蹤節點(?run_id=)。 |
GET /api/workspace/firewall/anomalies | Member | 異常動態(?window=)。 |
POST /api/workspace/firewall/anomalies/snooze | Developer+ | 暫停異常動態。 |
閘道(機器對機器)
這些在一個防火牆閘道範圍的權杖上執行,而不是主控台工作階段:| 方法與路徑 | 用途 |
|---|---|
POST /api/v1/firewall/evaluate | 對一次工具呼叫的派發前裁決。 |
POST /api/v1/firewall/evaluate_plan | 對一個多步驟計畫的執行前檢查。 |
ANY /api/v1/firewall/mcp | 統一的 MCP 閘道端點。 |
GET /api/v1/firewall/approvals/:id | 輪詢一個被保留呼叫的審批狀態。 |
POST /api/v1/firewall/approvals/:id/callback | HMAC 簽署的審批回呼。 |
14. FAQ
如果一次工具呼叫上沒有解析出任何政策會怎樣?
如果一次工具呼叫上沒有解析出任何政策會怎樣?
在觀察模式關閉時,行為與從未啟用該功能的工作區
位元組完全一致——不封鎖、不記錄任何東西。在
觀察模式開啟時,呼叫會被允許但記錄為一個涵蓋
缺口,以便它出現在 Discovered tools 中。
我如何安全地上線一個政策?
我如何安全地上線一個政策?
開啟影子模式。政策會像在生產環境中那樣評估並
記錄,但每個強制執行的裁決都會被降級為
audit,原因會被加上前綴 [shadow] would …。觀察
events 與 runs 檢視,確認它在你預期的事物上觸發、在你
不預期的事物上不觸發,然後關閉影子模式以開始強制執行。一次被封鎖的工具呼叫會消耗配額嗎?
一次被封鎖的工具呼叫會消耗配額嗎?
一個 inbound 封鎖在上游模型呼叫之前觸發,所以它不消耗
模型權杖。Audit / allow 裁決不改變計費。一個
cap_cost 規則本身就是一個計費控制項——它會在執行的
花費跨越你的分(cents)上限時拒絕。防火牆還是防護欄——我該用哪一個?
防火牆還是防護欄——我該用哪一個?
兩者都用,用於不同的層次。防護欄審查提示與
回應中的文字(PII、密鑰、越獄)。防火牆治理
代理採取的動作(哪些工具、哪些 MCP 伺服器、哪些主機)。
一個請求可以同時通過兩者。
tight 自主等級會把
它們一起設定好。對代理執行的每個工具都保證會強制執行嗎?
對代理執行的每個工具都保證會強制執行嗎?
防火牆會對穿越閘道的工具呼叫強制執行——
中繼路徑、MCP 閘道與 evaluate hook。一個你的代理
完全在自己的行程內執行、從不觸及閘道的工具,
在防火牆的視野之外。設計目標是讓閘道成為那些
重要呼叫(模型中介的工具、MCP 派發、網路 egress)的單一
受稽核路徑;將那些呼叫透過它路由,它們就會被治理。
延伸閱讀
想更深入了解代理安全?**保護你的代理(零信任)**指南會將此功能放入零信任工作流程中。保護你的代理(零信任)
零信任代理防火牆手冊——工具允許清單、引數檢查與外向流量控制。
安全代理基準
一個開關,同時設定你的防火牆與防護欄姿態。
