上游请求头
forward_client_headers 用于点名调用方发来、需要由 AISIX 中继给上游的入站请求头。它在 AISIX 代理的四个面上是同一个字段、同一套语义,取值是一个请求头名称模式数组,默认为空。
需要配置它的场景,是上游需要某些只有调用方才能提供的信息:服务提供方的 Beta 功能标记、应用路由提示、链路关联请求头;或者当上游是按最终用户(而不是按网关)授权的内网服务时,调用方自己的凭证。
字段所在的位置取决于由哪个面访问上游:
| 字段 | 适用范围 |
|---|---|
provider_key.request.forward_client_headers | 使用该服务提供方密钥的标准协议端点(/v1/chat/completions、/v1/completions、/v1/messages、/v1/responses、/v1/realtime,以及 embeddings、rerank、音频、图像、视频和 files/batches/fine-tuning 接口)。/v1/realtime 上该字段生效,但 default_headers 不生效,详见下文。 |
passthrough_route.forward_client_headers | 由该透传路由处理的请求。 |
mcp_server.forward_client_headers | 对该 MCP 服务器的工具调用,type: mcp 和 type: openapi 均适用。 |
a2a_agent.forward_client_headers | 对该 A2A Agent的调用——/a2a/<name> 上的每个 JSON-RPC 方法,以及 agent card 拉取,均适用。 |
两种管理路径都可以在这四个资源上配置该字段。加载声明式资源文件的网关支持本文的全部内容,AISIX Cloud Admin API 和控制台同样如此——包括精确点名凭证槽位的条目,而这正是按最终用户授权的内网上游所依赖的写法。
该字段在各处的行为一致——被模式点名的请求头就会到达上游——但各个面的默认行为并不相同,因此设置它的实际含义也不同:
- 在标准端点、MCP 和 A2A 上,AISIX 从头构建上游请求,不中继任何调用方请求头。此时该列表是白名单:它是调用方请求头到达上游的唯一途径。
- 在透传路由上,AISIX 默认中继调用方的请求头,只剥离一小部分。此时该列表是对剥离集合的覆盖:它只对路由本会删除的那些请求头有意义,其中包括网关刚刚用来认证调用方的那个凭证槽位。
服务提供方密钥上还有另一个与之无关的请求头设置:request.default_headers 添加由 AISIX 生成的请求头,其值可以引用当前请求。两者都位于服务提供方密钥上,因此引用该密钥的每个模型都会继承它们。
前置条件
开始前请准备:
- 上游服务提供方凭证和端点。示例会在服务提供方密钥上配置这些设置;该资源的其他字段参见服务提供方密钥。
- 对于 AISIX Enterprise 或 AISIX Cloud,需要环境、已关联网关和具有写入作用域的 Admin Token。AISIX Enterprise 用户请按照 AISIX Enterprise 快速入门操作。如需申请 AISIX Cloud 访问权限,请联系 API7。
- 对于开源 AISIX 网关,需要一个加载声明式资源文件的网关。
配置上游请求头
请使用与你的部署方式对应的管理路径配置服务提供方密钥。两种路径下,这些设置的运行时行为相同。
AISIX Enterprise 或 AISIX Cloud
导出控制面连接信息和上游凭证:
# AISIX_CP 是 Admin API 基础 URL;应包含 /api,且不含尾部斜杠
# 本地 AISIX Enterprise 快速入门使用 http://localhost:8080/api
export AISIX_CP="YOUR_AISIX_CONTROL_PLANE_API_URL"
export AISIX_TOKEN="YOUR_ADMIN_TOKEN"
export ENV_ID="YOUR_ENVIRONMENT_ID"
export UPSTREAM_API_KEY="YOUR_UPSTREAM_API_KEY"
创建一个注入网关上下文并转发获准客户端请求头的服务提供方密钥。这两项设置可以独立配置;下例展示它们如何共存于同一密钥:
curl -sS -X POST "$AISIX_CP/provider_keys" \
-H "Authorization: Bearer $AISIX_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"display_name": "internal-vllm",
"provider": "byo",
"adapter": "openai",
"api_key": "'"${UPSTREAM_API_KEY}"'",
"api_base": "https://models.internal.example.com/v1",
"allowed_environments": ["'"${ENV_ID}"'"],
"request": {
"default_headers": {
"x-tenant-id": "${request.api_key.team_id}",
"x-audit-context": "key=${request.api_key.id};model=${model.name}",
"x-correlation-id": "${request.id}",
"x-upstream-tier": "premium"
},
"forward_client_headers": [
"anthropic-beta",
"x-routing-hint",
"x-trace-*"
]
}
}'
❶ 调用方 API Key 所属团队,可用于标识租户,以便上游进行配额或路由决策。
❷ 由字面文本、调用方 API Key 标识符和面向调用方的模型名称组合而成的值。
❸ 当前请求的关联 ID,与 AISIX 在 x-aisix-request-id 中发送并写入自身日志的值相同。
❹ 字面值,每个请求都会原样发送。
❺ 入站请求头名称和模式的允许列表。AISIX 在向上游发送请求前,仍会移除绝不转发的请求头。凭证或链路上下文请求头需要精确点名;这里的 x-trace-* 模式并不会匹配 traceparent。
响应中会包含服务提供方密钥 ID。如需稍后更改请求头设置,请保存该 ID:
export PK_ID="YOUR_PROVIDER_KEY_ID"
后续修改配置
PATCH /provider_keys/{id} 会整体替换 request 配置块,变更会影响引用该密钥的每个模型。请先读取当前配置块,然后在编辑后的请求中发送要保留的所有字段:
curl -sS "$AISIX_CP/provider_keys/$PK_ID" \
-H "Authorization: Bearer $AISIX_TOKEN" \
| jq '.provider_key.request'
curl -sS -X PATCH "$AISIX_CP/provider_keys/$PK_ID" \
-H "Authorization: Bearer $AISIX_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"request": {
"default_headers": {
"x-tenant-id": "${request.api_key.team_id}"
},
"forward_client_headers": ["anthropic-beta", "x-trace-*"]
}
}'
空的 "request": {} 会清除已存储的覆盖设置。目录服务提供方密钥会恢复为服务提供方的内置默认值;BYO 密钥清除后没有请求覆盖设置。省略 request 则会保留已存储的配置块。
在控制台中,相同配置块位于服务提供方密钥编辑表单的 Advanced wire-shape overrides 下,并会预填已存储值。
开源 AISIX 网关
将 request 配置块添加到 resources.yaml 中的服务提供方密钥条目。保留该条目已有的凭证字段,以及其他无关条目和集合。下例使用 UPSTREAM_API_KEY,该变量必须可供网关进程使用:
provider_keys:
- display_name: internal-vllm
provider: byo
adapter: openai
api_key: ${UPSTREAM_API_KEY}
api_base: https://models.internal.example.com/v1
request:
default_headers:
x-tenant-id: $${request.api_key.team_id}
x-audit-context: key=$${request.api_key.id};model=$${model.name}
x-correlation-id: $${request.id}
forward_client_headers:
- anthropic-beta
- x-trace-*
在资源文件中,未转义的每个 ${NAME} 都会在文件加载时从环境中替换。请将请求上下文引用中的美元符号转义为 $${...}。加载器会将 $$ 转换为字面 $,因此 $${request.id} 到达网关运行时会变成 ${request.id}。转义后的名称如果不在可用变量中,运行时不会解析,AISIX 会丢弃该请求头。
添加或更改该配置块后,请验证并重新加载完整资源文件。完整工作流参见重新加载资源文件,完整字段目录参见资源文件参考。
请求上下文请求头值
当上游需要知道调用者身份时,使用 request.default_headers。内部模型服务可以据此应用租户配额、把成本归属到团队,或将自身访问日志与 AISIX 请求 ID 关联。这些请求头可以避免为每个租户准备单独的上游凭证。
请求头值可以是字面字符串、${...} 引用,也可以是字面文本与多个引用的组合。AISIX 会在认证调用方并选择模型后解析每个引用。
可用变量
| 变量 | 值 |
|---|---|
request.id | 当前请求的关联 ID。 |
request.api_key.id | 调用方 API Key 的标识符。 |
request.api_key.name | 调用方 API Key 的名称。 |
request.api_key.team_id | 调用方 API Key 所属团队。 |
request.api_key.user_id | 拥有调用方 API Key 的组织成员。 |
model.id | 解析后模型的标识符。 |
model.name | 解析后模型面向调用方的名称,而不是上游模型名称。 |
provider_key.id | 当前服务提供方密钥的标识符。 |
provider_key.name | 当前服务提供方密钥的名称。 |
只有这些变量会在请求时解析。保存服务提供方密钥时,如果值引用了其他名称,AISIX Cloud Admin API 会拒绝该值,使拼写错误立即失败,而不是变成一个永远无法到达上游的请求头。资源文件另有一个加载时插值步骤,因此请求上下文引用需要按开源 AISIX 网关一节所述进行转义。
所有变量都不会暴露密钥。调用方 API Key、上游凭证和签名材料都不属于请求头值可以读取的请求上下文。
如果请求头引用的变量在某次请求中并非都有值,AISIX 会从该请求中删除整个请求头,而不是发送空值。如果调用方 API Key 不属于任何团队,上述示例的请求会包含 x-audit-context 和 x-correlation-id,但不会包含 x-tenant-id。空的 x-tenant-id 会让上游误以为租户是空字符串。