跳转到主要内容
一条 防火墙 规则在两个维度上匹配一次工具调用: 哪个工具(一个 tool_name_glob)和哪些参数(作用于 JSONPath 字段的 args_match 子句)。本页是 两者的精确语法——一个模式匹配什么、不匹配什么,以及每个操作符如何对类型 做强制转换——这样你在控制台里编写的一条规则,行为就和你在这里读到的 完全一致。 头号使用场景:把一个粗钝的”拦截 shell.exec”变成一个外科手术式的”仅当 命令看起来像 rm -rf 时才拦截 shell.exec”。glob 挑出工具族;参数操作符 挑出其中那个危险的调用。
这是语法参考。关于这些子句在一条规则上位于何处、规则排序以及判定,参见 防火墙规则 深入参考。关于规则字段本身,参见 防火墙 概览。

1. 这套语法在哪里适用

两种形式都在一条防火墙规则上编写,在控制台 /console/firewall 下(写入 需要 Developer+)。你从不直接调用匹配器——网关在每一次工具调用上对照 已解析的策略 评估它。当一条 规则的执行面、它的 tool_name_glob、它可选的技能 glob,以及它的 args_match 子句全部匹配时,该规则才匹配;首个匹配生效。
一条没有 args_match 子句的规则仅凭工具名 glob 匹配。只有在工具名不够 具体时,才加上参数子句。

2. 工具名 glob 语法

tool_name_glob 是一个刻意设计得小而可预测的语法——不是一个完整的正则。 模式以区分大小写的方式匹配(MCP 工具名按约定是小写加点,因此一次 大小写折叠会在你从 Discovered tools 标签复制一个名字时给你惊吓)。
一个空模式或一个裸 * 匹配所有工具。把它用在一条 catch-all 规则上, 或者改为依赖策略的 default_verdict
shell.* 匹配 shell.execshell.readshell.write。它匹配 裸的 shell(点是必需的——一个前缀 glob 只覆盖带命名空间的子项)。
*.exec 匹配带命名空间的 shell.exec匹配裸的、无命名空间的 exec(提供商原生函数调用和不带命名空间的 MCP 服务器把工具暴露在裸 动词之下,因此一条后缀规则覆盖两种形态)。后缀锚定在一个点或字符串 起始处,因此 *.exec 匹配 shell.execute
*.shell.* 匹配任何 <server>.shell.<verb> 形态——local.shell.execbyo.shell.run。它要求中缀两侧各至少有一个字符,因此 *.shell.* 匹配裸的 shell 或单独的 .shell.。只有对称的 *.X.* 形态才被 当作中缀;一个像 foo.*.bar 这样的混合模式会落到精确匹配。
任何不属于上述四种通配形态的模式(包括一个字面工具名,或一个像 foo.*.bar 这样畸形的组合)都作为一个精确的、区分大小写的字符串来比较。
没有 ? 单字符通配符,没有字符类,也没有 token 中间的 * (例如 sh*l.exec)。一个不属于这四种受支持形态的模式会被字面匹配 ——sh*l.exec 只匹配一个字面命名为 sh*l.exec 的工具。用上面的形态来 编写,而不是正则的肌肉记忆。

3. JSONPath 参数子句

args_match 是一组子句,每一个都是一个 {path, op, value} 三元组。 path 是进入工具调用参数对象的一个 JSONPath;op 是七个操作符之一; value 是要比较的对象。一条规则中的所有子句都以 AND 相连——每个子句 都必须匹配,规则才触发。
{
  "clauses": [
    {"path": "$.command", "op": "regex", "value": "rm -rf|drop table"},
    {"path": "$.connection", "op": "in", "value": ["prod", "replica"]}
  ]
}

受支持的 JSONPath 子集

形态匹配
$.foo一个顶层键。
$.foo.bar一个嵌套键。
$.foo[0]按索引取一个数组元素。
$.arr[1].k先索引后键(以上各项的组合)。
那就是整个子集。没有通配符($.*)、过滤器($.foo[?(...)])、 切片($.foo[0:2])或递归下降($..foo)。
对路径故障关闭(Fail-closed)。 如果一个子句的路径解析为空——键缺失、 参数不是有效的 JSON,或值对于该操作符是错误的类型——那个子句求值为 false,规则触发,求值落到下一条规则或策略默认值。一个畸形的 参数永远不会自动拒绝,也永远不会让引擎崩溃。

4. 参数操作符

七个操作符,一个封闭集合。控制台校验器和实时引擎共享完全相同的词汇, 因此一个能保存的子句就是一个能运行的子句。
操作符比较什么类型规则
eq精确相等。类型化:string↔string、bool↔bool 或 number↔number。混合类型永不匹配。
contains子串包含。两侧都必须是字符串;其他任何情况都是非匹配。一个空 value 匹配任何字符串。
regex一个 RE2 模式(线性时间,无反向引用)对照一个字符串。value 和已解析的参数必须都是字符串。一个无效模式会禁用该子句(永不匹配)。
in成员资格——value 等于一个列表的任意元素。value 必须是一个 JSON 数组;每个元素以 eq 语义比较。
cidr_match已解析的值是给定网络内的一个 IP。value 是一个 CIDR 字符串(IPv4 或 IPv6,例如 10.0.0.0/8fd00::/8);参数必须能解析为一个 IP。
gt大于,数值。两侧都必须能强制转换为一个数字。一个看起来像数字的字符串****不被强制转换——它是一次类型不匹配(非匹配)。
lt小于,数值。gt 相同的仅数值规则。
gtlt 是严格数值的。如果一个工具发送 {"max_rows": "10000"} (一个字符串),一个 gt 5000 子句不会触发——该字符串永不被强制转换。 用数字对照数字来比较;对字符串形态的值用 regexcontains

5. 一个完整示例

拦截一次破坏性的数据库导出,但仅当它瞄准一个经由私有网络主机的生产 连接时:
{
  "tool_name_glob": "db.*",
  "args_match": {
    "clauses": [
      {"path": "$.statement", "op": "regex", "value": "(?i)drop|truncate|delete from"},
      {"path": "$.connection.name", "op": "in", "value": ["prod", "prod-replica"]},
      {"path": "$.connection.host_ip", "op": "cidr_match", "value": "10.0.0.0/8"}
    ]
  }
}
从上往下读:glob db.* 把规则限定到数据库工具族;三个子句以 AND 相连, 因此判定(比如说一个 deny仅当语句是破坏性的连接是两个命名 生产目标之一它的主机落在私有 10.0.0.0/8 范围内时才触发。一次针对 公网 IP 上某个开发连接的 db.query 会毫发无损地从这条规则旁边掠过。
在你信任一个子句之前先证明它:一条策略上的 Test 标签会对一个样本工具 调用做 dry-run,并显示匹配到的规则和判定,不持久化任何内容,不派发任何 内容。参见 防火墙可观测性

6. Egress(host / CIDR)规则

上面的 cidr_match 操作符匹配一个工具在其参数里报告的 IP。那不同于一条 egress 执行面规则——后者用一个 host/CIDR 允许或拒绝列表来评估一个工具 实际触达的出站目的地——是首要的 SSRF 和 数据外泄 防御。egress 规则使用 同样的 CIDR 记法但存在于 egress 执行面上;egress 列表格式参见 防火墙规则
没有任何预设为你提供 CIDR egress 规则——tight 自治级别拒绝的是常见的 fetch 形态工具名http_fetchfetch_urlweb_searchrequest), 而不是网络范围。当你需要把 egress 钉定到特定目的地时,编写你自己的 host/CIDR 拒绝规则。

7. 快速参考

Glob 形态

* 全部 · foo.* 前缀 · *.exec 后缀(+ 裸动词)· *.X.* 中缀 · 其他任何为精确。区分大小写。

JSONPath

$.foo · $.foo.bar · $.foo[0] · $.arr[1].k。没有通配符、 过滤器、切片或递归下降。

字符串操作符

eq(类型化)· contains(子串)· regex(RE2)· in(列表成员资格)。

数值与网络操作符

gt / lt(仅数值,无字符串强制转换)· cidr_match (范围内的 IPv4/IPv6)。

相关

防火墙规则

完整的规则模型——执行面、排序、sanitizer、序列和 egress 列表。

危险的工具调用

这些子句所防御的威胁,以及如何把一条规则限定到它。

判定词汇表

一条规则匹配后,allowauditdenysanitize 等各做什么。

为什么这次被拦下了?

把一次具体拦截追溯到触发的规则和子句。