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-Agent、X-Forwarded-For)。大小写不敏感。Match Type 为 any 时留空(该类型不检查请求头)。 |
| Match Type | 匹配方式,见下表。 |
| Match Value | 匹配值。exists / absent / any 类型不需要填。 |
| Action | allow(放行)或 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-Agent 以 python-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会命中aaaa、xxaaaayy、aaaa123,只不命中aaab。想要完全匹配必须显式加首尾锚^...$,想要前缀匹配加首锚^...。常见误解的来源:某些语言或 API 会偷偷给正则加首尾锚,使其表现为完全匹配,例如 Java 的
String.matches(...)、Python 的re.fullmatch(...)、HTML<input pattern="...">。在这些环境里aaaa确实匹配不到xxaaaayy,于是留下「正则做不到包含」的印象。那是这些 API 自己加的隐式锚定行为,不是正则本身的语义。本引擎的正则匹配是包含语义、不锚定,故aaaa即「值包含 aaaa」。模式 值 aaaa值 xxaaaayy值 aaab实际语义 aaaa✅ ✅ ❌ 包含(contains) ^aaaa$✅ ❌ ❌ 完全相等(exact) ^aaa✅ — — 以 aaa开头(prefix)|表示「或」,可在一条规则内组合多个条件。 因为一条规则只持有一个condition_value,要在单条规则里表达「A 或 B 或 C」只能借助正则的 alternation。例如aaaa|bbb|^aaa即「包含 aaaa,或包含 bbb,或以 aaa 开头」。注意^只锚定它所在的那个分支。大小写:头名不敏感,头值敏感。 Header Name 在加载时已统一转小写,故
User-Agent与user-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 语义组合编排。
评估逻辑
- 合并当前请求作用域内的所有规则:全局规则 + 当前 key 的 per-key 规则 + 当前 group 的 per-group 规则。
- 按
sort_order升序排列(数值越小越先评估;相同 order 时按作用域 全局 → 密钥组 → 访问密钥 顺序),跳过enabled = false的规则。 - 逐条评估:按
condition_type匹配(any不读请求头,条件恒真;其余类型取请求头condition_key的值匹配)。 - 首条命中的规则决定结果:
deny→ 立即返回 403;allow→ 放行到下一层。 - 无规则命中时,按 default_action 链回退:per-key
acl_default_action→ per-groupacl_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 封禁。
