> 原始 Markdown 孪生体（构建期从源 Markdown 生成）。渲染页：https://docs.gatellm.io/zh-CN/reference/header-acl-rules · 文档索引：https://docs.gatellm.io/zh-CN/llms.txt


# Header ACL 规则字段

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

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

任务视角的常见用法与示例见 [配置 Header ACL 访问规则](/zh-CN/howto/configure-header-acl.md)。本章是字段/语义参考。

## 规则字段

| 字段 | 说明 |
|------|------|
| **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|wget|scrapy` |
| `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 语义组合编排。

## 评估逻辑

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 访问规则](/zh-CN/howto/configure-header-acl.md) 看常见用法和复杂配置示例；[访问密钥与密钥组字段](/zh-CN/reference/access-keys-groups-fields.md) 看密钥组维度；[审计与安全配置](/zh-CN/reference/audit-and-security-config.md) 看限流与 IP 封禁。
