跳轉到主要內容
對一個工具做允許清單回答了一個代理可以呼叫哪個工具。它無法回答 以哪些引數shell.exec 用於 ls 沒問題;用於 rm -rf / 則是一場 災難。db.query 對著一個副本沒問題;對著 prod 則是一個風險。差別 存在於引數之中,而一條工具名稱規則看不見它。 防火牆的引數子句args_match_json)填補了那個缺口。它們審查 模型為一次工具呼叫所選的具體引數,並從它們的決定裁決——所以 你能廣泛地許可一個工具,同時拒絕它能採取的那一種危險形狀。本頁是 撰寫那些子句的聚焦指南;關於完整的規則詞彙參見 防火牆規則,圍繞它們的政策模型參見 防火牆
引數值只在模型選擇了如何呼叫一個工具之後才存在,所以引數子句 屬於 responsemcp 介面。在 inbound 上——那裡代理只公告工具定義——沒有呼叫時引數可檢查。

1. 何時驗證工具呼叫引數

每當一個工具在一般情況下安全、但在某個特定形狀中危險時,就去拿 一個引數子句:

破壞性指令

允許 shell.exec,但在指令匹配 rm -rfmkfsdd if= 時拒絕。

生產波及範圍

允許 db.query,但在連線目標是 prod 時拒絕(或保留待審批)。

內部目的地

允許一個擷取工具,但在它的 url/ip 引數落入一個 RFC-1918 範圍或 cloud-metadata IP 時拒絕。

超大操作

允許一個批次工具,但在一個 limitcount 引數超過一個數值 上限時拒絕。
規則仍會先匹配工具名稱;子句將它從哪個工具收窄為哪次呼叫

2. 一個子句集的形狀

args_match_json 是一個 JSON 編碼的字串,其解碼後的值是一個 持有一份 clauses 清單的物件。每個子句是一個 { path, op, value } 三元組,而所有子句一起做 AND——只在每個子句都為真時規則才 觸發。解碼後,該值看起來像:
{
  "clauses": [
    { "path": "$.command",    "op": "regex",      "value": "rm -rf|drop table" },
    { "path": "$.connection", "op": "in",         "value": ["prod", "replica"] },
    { "path": "$.ip",         "op": "cidr_match", "value": "10.0.0.0/8" }
  ]
}
在一個規則主體中,該欄位將那個 JSON 攜帶為單一跳脫過的字串——例如 "args_match_json": "{\"clauses\":[{\"path\":\"$.command\",\"op\":\"regex\",\"value\":\"rm -rf\"}]}" 一個空的或不存在的 args_match_json空虛地為真——規則僅靠它的 工具名稱 glob 匹配,與一條僅有名稱的規則完全相同。

3. 運算子

七個運算子構成這套封閉的詞彙。當你儲存時主控台會驗證運算子與它的 值形狀,所以一個格式錯誤的子句永遠不會被持久化。
運算子在以下情況匹配
eq純量相等(數字以數值比較;類型不符即不匹配)。
contains子字串——兩個運算元都必須是字串。
regex一個 Go RE2 模式匹配該字串值(線性時間,無反向參照)。
in該值是給定 JSON 陣列的一個元素。
cidr_match該字串 IP 落入給定的 CIDR 之中。
gt / lt數值大於/小於(字串不被強制轉換)。

4. Path 語法

一個子句的 path 是工具引數物件上的一個小型 JSONPath 子集
依名稱讀取一個頂層或巢狀的物件欄位。
索引進一個陣列,可選擇性地繼續進入該元素的欄位。
對照整個引數 blob 匹配(與 containsregex 搭配做一次粗略 掃描很有用)。
沒有萬用字元、篩選器、切片或遞迴下降——這套文法刻意很小,所以 匹配在熱路徑上維持線性時間且可預測。

5. 一個完整範例

你讓你的代理自由執行 shell.exec,但一次遞迴強制刪除絕不應抵達 shell。撰寫一條 response 介面的規則,在指令引數看起來具破壞性 時才拒絕 shell.exec
1

開啟規則編輯器

在主控台中,開啟綁定到你代理金鑰的防火牆政策(或工作區 預設值)並加入一條規則。編輯政策是一項 Developer+ 動作—— Members 可以讀取政策但不能寫入它們。
2

在 response 介面上匹配工具

將介面設為 response,工具 glob 設為 shell.execresponse 介面 攜帶模型所選的引數,那是子句所需要的。
3

加入引數子句

$.command 上加入一個 regex 子句,然後將裁決設為 deny
{
  "stage": "response",
  "tool_name_glob": "shell.exec",
  "verdict": "deny",
  "args_match_json": "{\"clauses\":[{\"path\":\"$.command\",\"op\":\"regex\",\"value\":\"rm\\\\s+-rf|mkfs|dd\\\\s+if=\"}]}"
}
args_match_json 是一個 JSON 編碼的字串;它解碼後的值是 §2 中 顯示的 { "clauses": [ … ] } 物件。
4

在你依賴它之前乾跑它

使用 Test 分頁對照一個樣本 shell.exec 呼叫評估該規則。它會傳回裁決、匹配到的規則與原因—— 不派發、不持久化任何東西。
現在帶有 "command": "ls -la"shell.exec 像以前一樣流過,而帶有 "command": "rm -rf /var" 的則被拒絕。response 上的一個 deny 讓 模型看見一個工具錯誤並做出反應——選擇另一個工具、詢問使用者,或 停止——而不是崩潰。
想許可該呼叫但剝除一個外洩的值而非封鎖?將裁決換成 sanitize。 Sanitize 並不遮罩子句匹配到的東西——它對引數字串執行一個獨立的 遮罩器(像 openai_keyanthropic_keyssn_us 這樣的命名預設集, 加上你自己的自訂 regex),用一個 [redacted:…] 權杖替換每一個命中, 並轉送清理後的呼叫。args_match_json 子句仍決定規則是否觸發; 遮罩器決定什麼被擦除。參見 淨化引數。Sanitize 只 遮罩工具呼叫引數——絕不遮罩工具回傳的內容。

6. 子句失敗關閉——影響規則,而非請求

如果一個子句無法被評估——path 不解析、引數格式錯誤,或一個 regex / CIDR 無效——該子句評估為,而規則就是不觸發。呼叫 落到下一條規則或政策的 default_verdict。一個壞掉的子句絕不自動 拒絕,也絕不擾動中繼。
由於一個無法評估的子句會讓它的規則匹配,絕不要倚賴一個子句以 某種特定方式失敗。將你的「捕捉一切危險」規則撰寫為一個帶有它自己 工具 glob 的明確 deny,並用引數子句來收窄一個許可——而不是作為 你的最後一道防線。

7. 將子句與規則的其餘部分組合

引數子句與一條規則表達的其他一切堆疊——它們是數個 AND 連接條件 中的一個:
與之組合效果
tool_name_glob子句只在工具名稱匹配後才執行——名稱在先,引數在後。
skill_name_glob擁有它的技能以不同方式把關同一工具的引數(例如對 community.* 更嚴)。
verdict將子句與 denysanitizepending_approvalcap_cost 搭配,而不只是 deny
多個子句全部都必須成立——將一個 regex 指令檢查與一個 in 環境檢查組合以緊密地限定一個 deny。
關於每個搭配產生的精確裁決語意,參見 裁決;關於一個被保留的呼叫如何 解決,參見審批

8. 這如何契合

防火牆規則

完整的規則參考——glob、子句、淨化器、egress 與序列。

引數食譜

為常見危險形狀準備的複製貼上 args_match_json 食譜。

防火牆介面

為何引數子句存在於 responsemcp,而非 inbound

封鎖工具

當沒有引數是安全的時,直接拒絕一個工具。
關於更廣的圖景,參見 危險的工具呼叫OrcaRouter 如何審查