跳到正文

Header ACL 规则字段

访问规则基于 HTTP 请求头做准入控制,支持三级作用域:全局、密钥组、访问密钥。规则按 sort_order 升序匹配,首条命中决定 allow/deny。

注意:访问规则同时作用于推理路由/v1/chat/completions/v1/messages 等)和模型列表路由/v1/models/v1beta/models)。拒绝某个 header 模式时,模型列表查询也会被拦截。运维人员需知晓此行为,避免误配导致客户端无法获取模型列表。

任务视角的常见用法与示例见 配置 Header ACL 访问规则。本章是字段/语义参考。

规则字段

字段说明
Rule Name规则唯一标识,全局唯一。建议使用作用域前缀(如 key:mykey__rule1)避免命名冲突。创建后不可修改。
Order排序权重,升序匹配,数值越小越先评估。相同 order 的规则按作用域 全局 → 密钥组 → 访问密钥 的顺序评估(即同 order 下全局规则先命中);因此密钥级或组级规则若要覆盖同 order 的全局规则,必须填更小的 order。
Header Name要匹配的 HTTP 请求头名称(如 User-AgentX-Forwarded-For)。大小写不敏感。Match Type 为 any留空(该类型不检查请求头)。
Match Type匹配方式,见下表。
Match Value匹配值。exists / absent / any 类型不需要填。
Actionallow(放行)或 deny(拒绝,返回 403)。
Scope作用域:Global(所有请求)、Key(指定一个或多个 access key)、Group(指定一个或多个密钥组)。Key 和 Group 互斥,支持多选。
Scope value当 Scope 为 Key 或 Group 时,从下拉列表选择目标密钥或密钥组。
Enabled规则开关。禁用后规则在加载时被忽略,不影响其他规则。

匹配类型

类型说明示例
exact请求头值与 Match Value 完全相等User-Agent = BadBot/1.0
prefix请求头值以 Match Value 开头User-Agentpython-requests/ 开头
regex请求头值匹配正则表达式User-Agent 匹配 `(?i)curl
exists请求头存在(不论值)检查 X-Custom-Header 是否存在
absent请求头不存在检查 Authorization 是否缺失
any条件恒真,不检查任何请求头,规则仅靠作用域(Scope)生效对某 key「全部放行/拒绝」:Match Type=any + Scope=Key,Header Name 留空

regex 匹配语义

regex 是最灵活也最容易被误解的类型,使用前请理解以下几点:

  • 默认是「包含」,不是「完全匹配」。 正则表达式在标准语义下做的是搜索——在请求头值里查找是否存在一段子串满足模式,不要求匹配整个值。因此一个不锚定的模式天然就是 contains:模式 aaaa 会命中 aaaaxxaaaayyaaaa123,只不命中 aaab。想要完全匹配必须显式加首尾锚 ^...$,想要前缀匹配加首锚 ^...

    常见误解的来源:某些语言或 API 会偷偷给正则加首尾锚,使其表现为完全匹配,例如 Java 的 String.matches(...)、Python 的 re.fullmatch(...)、HTML <input pattern="...">。在这些环境里 aaaa 确实匹配不到 xxaaaayy,于是留下「正则做不到包含」的印象。那是这些 API 自己加的隐式锚定行为,不是正则本身的语义。本引擎的正则匹配是包含语义、不锚定,故 aaaa 即「值包含 aaaa」。

    模式aaaaxxaaaayyaaab实际语义
    aaaa包含(contains)
    ^aaaa$完全相等(exact)
    ^aaaaaa 开头(prefix)
  • | 表示「或」,可在一条规则内组合多个条件。 因为一条规则只持有一个 condition_value,要在单条规则里表达「A 或 B 或 C」只能借助正则的 alternation。例如 aaaa|bbb|^aaa 即「包含 aaaa,或包含 bbb,或以 aaa 开头」。注意 ^ 只锚定它所在的那个分支。

  • 大小写:头名不敏感,头值敏感。 Header Name 在加载时已统一转小写,故 User-Agentuser-agent 等价;但 Match Value 的正则匹配区分大小写aaaa 不命中 AAAA。需要忽略大小写时用内联标志包裹:(?i:aaaa|bbb)

  • 正则引擎为线性时间实现、抗 ReDoS。 用户填写的正则在加载时受尺寸与复杂度上限保护,恶意或病态模式会被拒绝加载(编译失败的规则被跳过并记录告警,不影响其余规则)。代价是不支持回溯引用与 lookaround(如 (?=...)(?!...)\1)。因此「值包含某子串」这类否定条件无法用单条正则表达——见下方能力边界说明。

  • condition_value 长度上限 1024 字节。 过长的 alternation 列表请拆成多条规则。

表达力边界

  • 没有独立的 contains 类型:「包含」语义请用不锚定的 regex(或退而用多条 exact/prefix 规则)。
  • 否定匹配需靠规则编排:正则引擎不支持 lookahead,故「值不含 X」写不成单条正则。需要「不含 X 才放行」时,反过来编排——把 default_action 设为 deny,再用一条「含 X 则 allow」的规则放行匹配项;或拆成多条规则覆盖。
  • 多条件「与」需拆多条规则:一条规则只有一个条件,无法在单条内写 AND。要求「同时满足 A 和 B」时,用 default_action 与多条规则的 first-match-wins 语义组合编排。

评估逻辑

  1. 合并当前请求作用域内的所有规则:全局规则 + 当前 key 的 per-key 规则 + 当前 group 的 per-group 规则。
  2. sort_order 升序排列(数值越小越先评估;相同 order 时按作用域 全局 → 密钥组 → 访问密钥 顺序),跳过 enabled = false 的规则。
  3. 逐条评估:按 condition_type 匹配(any 不读请求头,条件恒真;其余类型取请求头 condition_key 的值匹配)。
  4. 首条命中的规则决定结果:deny → 立即返回 403;allow → 放行到下一层。
  5. 无规则命中时,按 default_action 链回退:per-key acl_default_action → per-group acl_default_action → 全局 Allow

常见问题

Q:规则改了不生效? 规则编译失败时被跳过并记录告警。检查 condition_value 是否符合语法(不支持 lookahead / 回溯引用)。condition_value 长度上限 1024 字节。

Q:怎么让某密钥组的规则覆盖全局规则? 同 order 下全局先命中。要覆盖必须填更小的 order,或把全局规则改成 enabled = false

Q:怎么对某个密钥「无条件放行/拒绝」? Match Type=any + Scope=Key + Header Name 留空。规则仅靠作用域生效,对此密钥的所有请求生效。

Q:模型列表调用也被拦截? 是的,规则同时作用于 /v1/models/v1beta/models。运维需知晓此行为,避免误配导致客户端无法获取模型列表。

下一步配置 Header ACL 访问规则 看常见用法和复杂配置示例;访问密钥与密钥组字段 看密钥组维度;审计与安全配置 看限流与 IP 封禁。