跳转到主要内容
点名一个工具并拒绝它很直接:它会为每一次调用杀掉那个工具。大多数时候那个 工具没问题,而一种调用形态才是问题——shell.exec 在命令是 rm -rf 之前都没问题,db.query 在它撞上 prod 之前都没问题。那个区分正是一个 参数子句所表达的:一个 jsonpath 工具参数 谓词, 匹配智能体传入的,所以判定只在那次危险的调用上触发,而让其余的不受 影响。 本页是一本 cookbook——针对最常出现情况的少数几个可复制粘贴的 args_match_json 配方。关于完整的子句语法、运算符表和故障关闭语义,参见 验证参数规则 schema 参考。

1. 一个 jsonpath 工具参数子句如何工作

一条规则的 args_match_json 是一个携带一组子句JSON 编码字符串, 所有子句以 AND 组合。解码后的值是一个对象 {"clauses": [ … ]},其中每个 子句是一个 { path, op, value } 三元组:
  • path——工具参数对象之上的一个小 JSONPath 子集:$.command$.foo.bar$.items[0],或代表整个对象的 $。没有通配符、过滤器、 切片或递归下降。
  • op——一个封闭集合之一:eqcontainsregexincidr_matchgtlt
  • value——要比较的字面量(一个字符串、数字、布尔值,或——对于 in——一个 JSON 数组)。
一个子句被 AND 到规则的 tool_name_glob 上:该规则只在工具名匹配 每个子句都成立时触发。完全省略 args_match_json(或把它留为一个空的 "{}"),该规则就仅靠 glob 匹配。
子句故障关闭——影响规则,而非请求。 如果一个路径无法解析、参数格式 不正确,或一个值类型错误,该子句评估为 false,该规则就不触发——该调用 落到下一条规则或默认判定。一个损坏的子句绝不会自动拒绝。把你的硬后盾 写成一个普通的 glob deny,而非一个你依赖它以某种方式失败的子句。

2. 配方:拦截一个破坏性命令

标准案例。总体上允许 shell.exec,只在命令看起来具破坏性时拒绝它。一个 针对 $.commandregex 子句即可做到:
{
  "label": "block destructive shell commands",
  "tool_name_glob": "*.exec",
  "verdict": "deny",
  "args_match_json": "{\"clauses\":[{\"path\":\"$.command\",\"op\":\"regex\",\"value\":\"rm -rf|mkfs|dd if=\"}]}"
}
正则是 Go RE2——线性时间,无反向引用,无灾难性回溯——所以它们在每一次 工具调用上运行都是安全的。一个非字符串的 $.command(或一个缺失的) 永不匹配,所以一个格式不正确的调用会落空,而非被错误地拦截。
当你匹配一个固定子串时,优先用 contains 而非 regex——它读起来更简单, 且不会被一个未转义的元字符绊倒。仅当你确实需要交替或锚点时才使用 regex

3. 配方:对照一个命名环境拒绝一个工具

db.query 运行,但只对照安全连接——在目标是 prod 或一个 replica 时拒绝它。in 运算符把解析出的值与一个 JSON 数组的任何元素匹配:
{
  "label": "no agent queries against prod",
  "tool_name_glob": "db.query",
  "verdict": "deny",
  "args_match_json": "{\"clauses\":[{\"path\":\"$.connection\",\"op\":\"in\",\"value\":[\"prod\",\"replica\"]}]}"
}
in 的值必须是一个 JSON 数组——一个非数组在你保存规则时被拒绝。元素 以标量相等比较,所以数字和字符串各自匹配它们自己的类型。

4. 配方:拒绝一个私有 IP 或元数据目的地

当一个工具把一个目标 IP 作为参数时,cidr_match 测试它是否落入一个 CIDR——即”一个智能体抓取 10.x 或云元数据地址”的 SSRF 形态:
{
  "label": "deny tool calls aimed at RFC-1918",
  "tool_name_glob": "*",
  "verdict": "deny",
  "args_match_json": "{\"clauses\":[{\"path\":\"$.target_ip\",\"op\":\"cidr_match\",\"value\":\"10.0.0.0/8\"}]}"
}
该参数值必须解析为一个落在该 CIDR 内的 IP 字面量;一个主机名或一个非 IP 字符串永不匹配。
cidr_match 只检查一个已经在工具参数中的值。要治理一个工具在网络层 实际触及的目的地——host/CIDR 白名单与黑名单——改在 egress 执行面上用一条 专用的 egress 规则。两者互补:进来 路上的参数检查,出去路上的 egress 控制。

5. 配方:对一个数值参数封顶

gtlt 比较数字。用它们来拒绝一个荒谬的批大小、一个超大的 limit, 或任何失控的计数——这里,拒绝一个目标超过 100 行的批量删除:
{
  "label": "block large bulk deletes",
  "tool_name_glob": "*.bulk_delete",
  "verdict": "deny",
  "args_match_json": "{\"clauses\":[{\"path\":\"$.count\",\"op\":\"gt\",\"value\":100}]}"
}
两侧都必须是数字——一个看起来像数字的字符串"500" 是类型不匹配, 匹配,所以该规则不会在一个字符串型参数上触发。把参数保持为数值型, 或在工具看到它之前对它做归一化。

6. 配方:组合子句(AND)

一条规则中的所有子句以 AND 组合,所以你可以把一个判定收窄到一次非常特定 的调用——例如,shell.exec 是一个破坏性命令它指向一个 prod 主机时拒绝它:
{
  "label": "destructive shell on a prod host",
  "tool_name_glob": "*.exec",
  "verdict": "deny",
  "args_match_json": "{\"clauses\":[{\"path\":\"$.command\",\"op\":\"regex\",\"value\":\"rm -rf|drop table\"},{\"path\":\"$.host\",\"op\":\"in\",\"value\":[\"db-prod-1\",\"db-prod-2\"]}]}"
}
需要一个 OR?在单个 args_match_json 内没有 OR——在不同优先级上编写 两条规则(或两个 glob)。引擎按优先级顺序遍历规则,首个匹配生效,所以 把窄的规则放在前面。参见 规则优先级

7. 为匹配到的形态挑选判定

一个子句决定哪些调用匹配;规则的 verdict 决定发生什么。deny 是 cookbook 的默认,但同一个子句可以携带一个更柔和的判定:
当匹配到的参数携带一个密钥或 PII 而非一个危险指令时,sanitize 从工具 参数中脱敏匹配的子串并转发清理后的调用。它只脱敏参数——绝不脱敏 工具返回的内容。参见 脱敏响应
把恰好那个有风险的形态挂起以供审查,而非直接拦截它:一名审查者带外 批准或拒绝,智能体把获批的调用重新提交一次。参见 审批
把判定设为 audit 以在你调优子句时记录匹配到的调用而不拦截。与 影子模式 搭配,在一个 deny 改变 任何东西之前对照实时流量衡量它。

8. 在依赖子句之前测试它

控制台 Test 标签对一个样本工具调用 dry-run 一条策略,并返回判定、 匹配到的规则和原因——不派发任何内容,不持久化任何内容。粘贴一个真实的 参数对象,确认该子句在你想要的调用上触发,且只在那些上触发,因为一个 无法解析一个值的子句会静默地不触发。参见 测试规则
子句在保存时被严格验证——未知运算符、错误路径、一个非数组的 in 值、 一个无法编译的 regex 以及无效的 CIDR 都被拒绝,所以一个格式不正确的子句 从一开始就无法被持久化。

9. 谁能编写参数子句

所有这些都在控制台中于你的会话下运行(/api/workspace/firewall/*):
操作角色
读取策略、预设、discovered toolsMember
创建 / 编辑 / 删除规则Developer+
Test 沙箱(dry-run 一条策略)Developer+
读取事件和运行汇总Developer+
编写或更改一个参数子句是一个 Developer+ 写入。Test 沙箱也是 Developer+——它可以对照一条草稿策略预览,而它的判定 trace 暴露策略 名称和规则标签,所以它处在分界线的写入一侧,而非读取一侧。

相关

验证参数

完整的参数匹配用例。

拦截工具

按名称拒绝一整个工具——无需子句。

Egress 控制

治理出站 host / IP / CIDR 目的地。

规则 schema

一条规则能携带的每一个字段。

规则优先级

首个匹配生效——把窄的排在宽的之前。

危险工具调用

这些配方应对的威胁。