透传路由
透传路由(passthrough route)将匹配到的请求转发到一个上游目标,不转换请求正文。它适用于 AISIX 尚未建模为一等路由的服务提供方原生端点,也适用于携带原始 Host 请求头的正向代理流量。
每条路由定义流量如何匹配、发送到何处、AISIX 如何认证调用方,以及 AISIX 是注入服务提供方凭证还是转发调用方凭证。AISIX 仍可围绕中继流量实施调用方访问控制、请求限制、护栏和遥测。
原有的隐式 /passthrough/<provider>/... 通道已被移除。未被任何路由认领的 /passthrough/* 路径遵循普通的空正文 404 处理流程。请先创建并验证替代路由,再迁移客户端流量。
透传路由不会改写模型标识符。如果服务提供方原生请求在正文、路径、查询参数或请求头中指定模型,请发送该服务提供方预期的标识符。
准备工作
请准备以下内容:
- 一个 AISIX 部署:
- 对于 AISIX Cloud,需要一个已挂载网关的环境和具备写入权限的管理员 Token。
- 对于开源 AISIX 网关,需要一个已配置为加载声明式资源文件的网关。
inject路由所需的上游服务提供方凭证。示例使用 OpenAI;forward_client路由则会中继调用方的上游凭证。curl和jq。
了解透传流程
AISIX 保留请求正文,同时处理网关身份认证、目标构造、有意的请求头过滤、护栏和遥测:
路由匹配分两个阶段进行:
- 入站
Host命中某条路由hosts白名单的请求,会在网关的类型化路由之前分发。这样,正向代理便可中继/v1/messages之类的上游路径,而不会被网关当作自身端点处理。 - 路径前缀匹配在类型化路由之后运行,因此纯路径路由无法遮蔽网关的
/v1、/mcp或/a2a端点。
多条路由同时匹配时,主机名匹配优先于纯路径匹配,较长的匹配前缀优先于较短的前缀。
配置服务提供方原生路由
以下示例在 /passthrough/openai/v1/models 暴露 OpenAI 的原生模型列表端点。AISIX 注入已配置的 OpenAI 凭证,并要求调用方 Key 已获得 openai-tunnel 授权。
AISIX Cloud
导出 AISIX Cloud 连接信息和服务提供方凭证:
# AISIX_CP 包含 /api,末尾不含斜杠。
export AISIX_CP="YOUR_AISIX_CLOUD_ADMIN_API_BASE_URL"
export AISIX_TOKEN="YOUR_ADMIN_TOKEN"
export ENV_ID="YOUR_ENVIRONMENT_ID"
export OPENAI_API_KEY="YOUR_OPENAI_API_KEY"
创建一个可供该环境使用的 OpenAI 服务提供方 Key:
PROVIDER_KEY_ID=$(curl --fail-with-body -sS -X POST \
"$AISIX_CP/provider_keys" \
-H "Authorization: Bearer $AISIX_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"display_name": "OpenAI passthrough",
"provider": "openai",
"api_key": "'"${OPENAI_API_KEY}"'",
"api_base": "https://api.openai.com/v1",
"allowed_environments": ["'"${ENV_ID}"'"]
}' | jq -er '.provider_key.id')
使用服务提供方 Key ID 创建路由:
ROUTE_RESPONSE=$(curl --fail-with-body -sS -X POST \
"$AISIX_CP/environments/$ENV_ID/passthrough_routes" \
-H "Authorization: Bearer $AISIX_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "openai-tunnel",
"path_prefix": "/passthrough/openai",
"target_url": "https://api.openai.com/v1",
"credential_mode": "inject",
"provider_key_id": "'"${PROVIDER_KEY_ID}"'"
}')
export ROUTE_ID=$(printf '%s' "$ROUTE_RESPONSE" | jq -er '.passthrough_route.id')
printf '%s' "$ROUTE_RESPONSE" | jq '.warnings // []'
保留 ROUTE_ID,以便更新路由或挂载路由作用域的护栏。
创建专用调用方 Key,并在同一请求中授予该路由。明文 Key 只返回一次:
CALLER_RESPONSE=$(curl --fail-with-body -sS -X POST \
"$AISIX_CP/environments/$ENV_ID/api_keys" \
-H "Authorization: Bearer $AISIX_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"display_name": "OpenAI passthrough caller",
"allowed_models": [],
"allowed_routes": ["openai-tunnel"]
}')
export AISIX_API_KEY=$(printf '%s' "$CALLER_RESPONSE" | jq -er '.plaintext')
printf '%s' "$CALLER_RESPONSE" | jq '.warnings // []'
控制平面会将服务提供方 Key、路由和调用方授权下发到已挂载的网关。上线前请检查返回的所有兼容性警告。警告仅供参考,因此请通过每个网关验证流量。在控制台中,可分别通过 Provider keys、环境的 Passthrough Routes 以及调用方 Key 的 Passthrough route access 部分完成相同操作。
如果改为授权现有调用方,请包含其应保留的全部路由授权。更新 allowed_routes 字段时,AISIX Cloud Admin API 会替换完整列表。
开源 AISIX 网关
在完整资源文件中准备一个 openai-prod 服务提供方 Key,然后选择一个专用调用方凭证:
export PASSTHROUGH_CALLER_KEY="YOUR_CALLER_API_KEY"
将路由和调用方条目添加到相应集合中。保持服务提供方 Key 和其他资源不变:
passthrough_routes:
- name: openai-tunnel
path_prefix: /passthrough/openai
target_url: https://api.openai.com/v1
provider_key: openai-prod
api_keys:
- display_name: passthrough-caller
key_env: PASSTHROUGH_CALLER_KEY
allowed_models: []
allowed_routes: [openai-tunnel]
AISIX 加载文件时,会将 provider_key 名称解析为服务提供方 Key 的派生 ID。未知名称会导致验证失败。allowed_routes 中的精确条目也会根据文件中定义的路由进行检查;允许使用通配符模式。
加载前,验证组装好的完整文件:
aisix validate --resources resources.yaml
由于本示例引入了 PASSTHROUGH_CALLER_KEY,请在网关进程环境中设置该变量,然后启动或重新创建网关。加载完成后,使用同一 个值进行验证请求:
export AISIX_API_KEY="$PASSTHROUGH_CALLER_KEY"
验证路由
导出末尾不带斜杠的网关源地址:
# 本地快速入门使用 http://127.0.0.1:3000。
export AISIX_PROXY="YOUR_AISIX_GATEWAY_ORIGIN"
通过 AISIX 请求 OpenAI 的原生模型列表:
curl --fail-with-body -sS \
"$AISIX_PROXY/passthrough/openai/v1/models" \
-H "Authorization: Bearer $AISIX_API_KEY"
该路由会剥离其 path_prefix,避免重复添加 target_url 中已有的 /v1 路径段,注入 OpenAI 服务提供方凭证,并中继上游响应。
比较 Cloud 与资源文件引用
大多数路由字段在两种管理方式中使用相同名称。服务提供方凭证和调用方凭证的引用方式有所不同:
| 用途 | AISIX Cloud Admin API | 推荐的资源文件字段 | 资源文件接受的显式 ID |
|---|---|---|---|
| 注入的服务提供方凭证 | provider_key_id(UUID) | provider_key(display_name) | provider_key_id |
| 匿名调用方主体 | anonymous_key_id(UUID) | anonymous_key(display_name) | anonymous_key_id |
资源文件中的名称引用在加载时会受到更严格的检查,引用未知时还会给出候选名称。应优先使用名称引用,而非显式 ID。AISIX Cloud 会验证服务提供方 Key 对该环境可见,并验证匿名调用方 Key 属于该环境。
在 AISIX Cloud 中,路由 name 创建后便固定不变。在资源文件中,更改名称会改变路由身份,因此必须同时更新每个调用方的 allowed_routes 条目。
配置参考
| 字段 | 行为 |
|---|---|
name | 路由身份,由调用方的 allowed_routes 模式引用,并记录在用量事件中。 |
path_prefix | 网关路径前缀,按路径段边界匹配。target_url 路由会先剥离前缀,再将剩余路径拼接到目标;preserve_host 路由则保留完整路径。纯路径路由不能占用 /v1、/mcp、/a2a、/admin、/livez、/readyz 或 /metrics;同时匹配 hosts 的路由可以使用这些归上游所有的路径。 |
hosts | 入站 Host 白名单,不区分大小写并忽略端口。前导 *. 通配符匹配一个额外标签,且必须保留至少两个字面标签。 |
target_url | 显式上游基础 URL。必须且只能配置一种目标形式:target_url 或 preserve_host: true。 |
preserve_host | 将 https://<matched-host> 推导为目标。仅可与 hosts 一同配置,由 hosts 限定推导出的目的地。 |
auth_mode | gateway_key(默认)、header_key 或 anonymous。 |
auth_header_name | header_key 模式下包含网关凭证的小写专用请求头。除非 forward_client_headers 完整写出它的名称,否则 AISIX 会在转发前将其剥离;x-* 这类通配符触及不到它。authorization、proxy-authorization、cookie、set-cookie 和 x-api-key 会被拒绝。 |
source_cidrs | 客户端来源白名单。anonymous 模式要求该列表非空;其他模式可将其作为可选的安全加固措施。 |
credential_mode | inject(默认)或 forward_client。 |
forward_client_headers | 即使该路由本会剥离,也仍要中继给上游的入站客户端请求头 ,取值为精确名称或含一个 * 的通配符,匹配不区分大小写。默认为空。PATCH 会整体替换已存储的列表;发送 null 可清空。在控制台中,它是 Advanced 下的 Forward client headers,每行一个条目。参见上游请求头。 |
identity_header | 可选的小写设备注入身份请求头。AISIX 将长度受限的值记录为 client_identity,并在转发前剥离该请求头(除非 forward_client_headers 完整写出它的名称;x-* 这类通配符触及不到它)。仅应在可信设备之后配置,并由该设备删除并替换客户端提供的任何值。authorization、proxy-authorization、cookie、set-cookie 和 x-api-key 会被拒绝。 |
timeout_ms | 限制上游响应头和非 SSE 正文的读取时长,不限制健康的 SSE 中继。 |
enabled | 停用的路由不匹配任何请求。默认值:true。 |
必须至少配置一个匹配维度:path_prefix 或 hosts。同时配置两者时,请求必须同时满足两项条件。
网关身份认证模式
gateway_key从Authorization: Bearer或x-api-key读取标准网关凭证。header_key从auth_header_name读取网关凭证,从而将Authorization留给 调用方的上游凭证。这是正向代理中forward_client的标准搭配。anonymous不接收网关凭证。请求以配置的调用方 Key 主体运行,并且必须来自source_cidrs范围内。
解析出的任一主体仍须通过 allowed_routes 获得路由名称授权;* 授予全部路由。有效 Key 缺少匹配授权时会收到 403。
在 AISIX Cloud 中,已适用于解析后调用方的预算会在分发前检查。透传用量目前不携带模型 ID,按零成本记录,也不会增加这些预算的支出。开源 AISIX 网关没有本地预算资源。
上游凭证模式
inject剥离入站凭证请求头,并注入已配置的服务提供方 Key。对于 Anthropic,AISIX 使用x-api-key和anthropic-version;对于其他服务提供方,则使用Authorization: Bearer。服务提供方 Key 上配置的请求头剥离规则和 TLS 设置也会生效。forward_client在网关凭证通过header_key传入或路由为匿名模式时,转发调用方的上游凭证。使用gateway_key时,AISIX 会删除Authorization和x-api-key,因为任一请求头都可能携带网关凭证。
路由默认中继调用方的其他请求头,只剥离一小部分:逐跳请求头和传输请求头、host、content-length、x-aisix-* 命名空间、proxy-authorization,以及调用方的 W3C 链路请求头。AISIX 会使用有效的 W3C 上下文建 立自身的 OTLP 链路,并向上游发送网关请求 ID。
forward_client_headers 会覆盖该剥离行为,也是把路由本会移除的请求头放回去的唯一方式。因此,在 auth_mode: gateway_key 下点名 authorization,会中继调用方自己的凭证——正是网关刚刚用来认证该调用方的那个请求头——取代注入的那份;这就是让按最终用户授权的内网服务能够继续这样工作的方式。无论模式如何,host、content-length、逐跳请求头和 x-aisix-* 都会被剥离;凭证或链路上下文请求头必须精确点名,通配符不会匹配到它们。路由自己的 auth_header_name 和 identity_header 同理:AISIX 会消费掉这两个请求头,因此通配符触及不到,完整写出名称才会转发它。路由剥离的其他任何名称,通配符都足以放回去,包括服务提供方密钥 strip_headers 里的条目——不过该列表四个默认值中有三个(authorization、cookie、x-api-key)属于凭证槽位,仍需单独点名,只有 set-cookie 是通配符能放回的默认项。
凭证不存在回退机制:inject 路由没有可解析的服务提供方 Key 时会拒绝请求,forward_client 路由则不能携带服务提供方 Key 引用。
信封识别与用量
AISIX 识别请求形态仅用于提取;识别不会改变中继 的正文。如果出现多个可识别的载体字段,则按以下顺序识别:
messages,用于 OpenAI 兼容聊天或 Anthropic Messages 流量。input,用于 OpenAI Responses 形态。prompt,用于旧式 completions 或 fill-in-the-middle 流量。- 其余所有正文均按不透明内容处理,包括 JSON-RPC、REST、非 JSON 和空正文。
识别结果决定提供给护栏的文本以及记录到用量事件中的 Token 字段。如果识别出的形态没有生成文本,AISIX 会改为扫描完整正文。请求和响应正文仍不经 Schema 转换便直接中继。
不透明的缓冲响应不会进行推测性 Token 提取。不透明的 SSE 流可通过顶层 usage 对象,或 event: usage / event: token_usage 帧中的扁平 Token 报告来上报用量。
限流
调用方 API Key、团队和成员的请求限制会在分发前生效。在 inject 路由上,如果顶层 JSON model 解析为同一服务提供方下已配置的 AISIX 模型,还会预留该模型的请求限制。forward_client 路由不执行此模型查找。
AISIX 会强制执行请求数维度限制(rps、rpm、rph 和 rpd)。当适用的 tpm 或 tpd 计数器已经耗尽时,AISIX 也会拒绝请求,但透传 Token 用量不会增加这些计数器。记录的用量应只用于遥测,而不是透传 Token 配额执行。
并发检查在向上游分发之前执行。对于 SSE,AISIX 返回流式响应时便会释放预留,而不是等到流结束。
透传路由没有限流字段或策略作用域。若要对不同路由应用不同的请求限制,请将路由授予不同的调用方 Key,并为这些调用方身份配置限制。
护栏与流式传输
在 AISIX Cloud 中,可以通过选择 Passthrough routes 作用域,将护栏挂载到一条透传路由。挂载使用路由 UUID。环境、调用方 Key 和团队护栏也可同时生效。
开源资源文件通过 guardrail_attachments 集合声明挂载关系,因此文件中定义的安全护栏只有在 Attachment 将其作用域覆盖到透传流量时才会生效:可以使用 scope_type: env 覆盖整个环境,也可以使用 scope_type: passthrough_route 并指定该路由。
输入护栏在向上游分发前运行。拦截会返回 422,且不会联系上游。缓冲响应在交付前检查。SSE 响应一旦开始,拦截会以 SSE content_filter 错误帧结束流,无法再将 HTTP 状态码改为 422。
除非 hold-back 护栏缓冲帧进行检查,否则 SSE 响应会增量中继。AISIX 不会改写服务提供方原生正文来应用脱敏。对于内置 pii 护栏,仅配置掩码动作时,匹配内容会在不掩码的情况下转发;如果匹配内容不得发送到上游,请使用拦截动作。Presidio 和 Lakera 等其他护栏类型在透传没有回写通道时,会改为拦截可掩码的结果。
审计捕获
对于成功中继的流量,配置了 content_mode: full 的可观测性导出 器会以字符串形式接收请求正文,并受导出器内容上限约束。缓冲响应与受支持的提取形态匹配时记录提取出的文本,否则将正文记录为文本。流式响应记录累积的提取文本;不透明数据载荷保留为文本。捕获的内容仅发送给导出器,绝不会通过 AISIX Cloud 遥测路径发送。
用量事件包含路由名称、调用方、记录的 Token 数量和 client_identity。外部导出器可以公开这些值。当前 AISIX Cloud Request Logs UI 显示调用方和 Token 元数据,但不显示 passthrough_route_name 或 client_identity。
从已移除的隐式通道迁移
已移除的通道通过可访问的模型间接选择服务提供方 Key。显式路由以固定的目标和凭证绑定取代了这种含糊的选择。
对于客户端仍在使用的每个服务提供方前缀:
- 使用旧路径前缀和预期的上游目标创建显式路由。
- 在
inject模式下绑定预期的服务提供方 Key。 - 将路由名称授予应保留访问权限的每个调用方。
- 迁移或重启客户端前验证路由。
显式路由认领相同前缀后,客户端可以继续使用现有的 /passthrough/<provider>/... URL。在该路由生效前,请求会返回普通 404。
原有通道的两项行为不会保留:透传路由只尝试一次上游请求,不会进行传输重试;路由失败也不会将已配置模型标记为冷却状态。
错误
| 状态码或信号 | 含义 |
|---|---|
401 | 按路由身份认证模式缺失或提供了无效的网关凭证。 |
403 | 解析出的调用方 Key 未授予该路由,或客户端来源不在 source_cidrs 范围内。 |
404 | 未被认领的 /passthrough/* 路径进入普通的空正文未找到处理流程。 |
422 | 护栏在分发前拦截了请求,或在交付前拦截了缓冲响应。 |
SSE content_filter 帧 | 护栏在流开始后拦截了内容。 |
429 | 网关请求限制或预算检查拒绝了请求,或上游返回了被中继的 429。 |
| 其他上游状态码 | AISIX 过滤响应头后,中继上游状态码和正文。 |
未匹配的 404 响应正文为空。AISIX 生成的其他失败使用网关错误信封;上游错误状态码和正文经过响应头过滤后中继。
下一步
- 使用主机名匹配路由接收经 TLS 终止的 IDE 流量:IDE AI 流量正向代理。
- 配置护栏行为:护栏行为。
- 导出请求和响应内容:可观测性导出器。