上游身份认证
每个已注册的 MCP 服务器都可以定义 AISIX 如何向上游服务器执行身份认证。AISIX 在网关侧持有所有上游凭证,并在列出工具或转发工具调用时提供该凭证。MCP 客户端发送给 AISIX 的调用方 API Key 用于向 AISIX 认证调用方;默认情况下,没有任何调用方请求头会到达上游服务器。确实需要看到某个请求头(包括调用方自己的凭证)的服务器,通过 forward_client_headers 显式开启。
有两种模式不使用网关凭证,而是代表调用方访问上游:oauth_delegate 转发调用方为上游发送的令牌,oauth2_token_exchange 用调用方的 Microsoft Entra ID 令牌换取访问上游的令牌。
使用 auth_type 字段和对应身份认证模式要求的字段设置凭证。AISIX Enterprise 和 AISIX Cloud 的控制面路径,以及 AISIX OSS 的资源文件路径,支持相同的模式。
前置条件
开始前,请准备以下环境:
- 对于 AISIX Enterprise 或 AISIX Cloud,准备一个环境和写入作用域管理员 Token。对于 AISIX Enterprise,请按照 AISIX Enterprise 入门操作。若要申请 AISIX Cloud 访问权限,请联系 API7。
- 请完成 AISIX Enterprise、AISIX Cloud 或开源 AISIX 网关的设置 MCP 网关。如需执行可选的端到端验证,请保持同一个 Shell、网关、Everything 测试服务器和临时 Docker 网络运行。
- 控制面示例需要 cURL。
身份认证模式
选择与上游 MCP 服务器期望 AISIX 使用的身份认证方式相匹配的模式:
auth_type | 上游凭证 | AISIX 的提供方式 |
|---|---|---|
none | 无 | 不发送凭证。 |
bearer | secret 中的 Bearer Token | Authorization: Bearer <secret> |
api_key | secret 中的 API Key | x-api-key: <secret> |
oauth2 | client_id + token_url + secret | AISIX 获取访问 Token,然后发送 Authorization: Bearer <access_token>。 |
oauth_delegate | 无 | AISIX 原样转发调用方自己的 Authorization 请求头。参见委托调用方令牌。 |
oauth2_token_exchange | token_exchange_profile + client_id + token_url + secret + scopes | AISIX 用调用方经验证的 JWT 换取访问 Token,然后发送 Authorization: Bearer <access_token>。参见 Entra 代理(On-Behalf-Of)令牌交换。 |
secret 保存 AISIX 提供给上游的明文凭证,或 AISIX 向令牌端点认证时使用的客户端密钥。该值仅在网关侧使用,永远不会发送给调用客户端。若要轮换凭证,请使用新的 secret 更新资源。
使用凭证的上游应采用 HTTPS。如果为 http:// URL 配置了 Bearer Token、API Key 或 OAuth 凭证,网关会记录警告,因为凭证将以明文通过网络传输。对于 OAuth,当 token_url 使用 http:// 时,网关也会发出警告,因为客户端密钥会发送到该端点。
配置上游身份认证
请通过与你的部署对应的管理路径配置上游身份认证。
AISIX Enterprise 或 AISIX Cloud
AISIX Cloud Admin API 会同时创建 服务器及其上游凭证。allowed_environments 列出接收该服务器的环境。列表为空或缺失时,服务器不会公开给任何环境,因此以下每个示例都包含目标环境。
导出控制面连接值:
# AISIX_CP 包含 /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"
无身份认证
上游 MCP 服务器不要求凭证时使用 none,例如只能通过受信任内部网络访问的服务器。
以下示例创建不带上游凭证的服务器资源:
curl -sS -X POST "$AISIX_CP/mcp_servers" \
-H "Authorization: Bearer $AISIX_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "runbooks",
"url": "https://runbooks.internal/mcp",
"auth_type": "none",
"allowed_environments": ["'"$ENV_ID"'"]
}'
auth_type 默认为 none,因此也可以省略。对于 none 服务器,不要设置 secret、client_id、token_url 和 scopes。
Bearer Token
上游服务器要求在 Authorization 请求头中提供静态 Token 时使用 bearer。
以下示例创建服务器资源,并配置 AISIX 应发送给上游的 Bearer Token:
curl -sS -X POST "$AISIX_CP/mcp_servers" \
-H "Authorization: Bearer $AISIX_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "github",
"url": "https://mcp.example.com/mcp",
"auth_type": "bearer",
"secret": "YOUR_UPSTREAM_MCP_TOKEN",
"allowed_environments": ["'"$ENV_ID"'"]
}'
❶ bearer 会在发送给此上游的每个请求上添加 Authorization: Bearer <secret>。
❷ secret 为必填字段,且不能为空。
API Key
上游服务器要求在 x-api-key 请求头中提供 Key 时使用 api_key。
以下示例创建服务器资源,并配置 AISIX 应发送给上游的 API Key:
curl -sS -X POST "$AISIX_CP/mcp_servers" \
-H "Authorization: Bearer $AISIX_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "catalog",
"url": "https://catalog.example.com/mcp",
"auth_type": "api_key",
"secret": "YOUR_UPSTREAM_API_KEY",
"allowed_environments": ["'"$ENV_ID"'"]
}'
❶ api_key 会在发送给此上游的每个请求上添加 x-api-key: <secret>。
❷ secret 为必填字段,且不能为空。
OAuth 2.0 客户端凭证
上游服务器接受 OAuth 2.0 访问 Token,且你拥有其机器到机器客户端凭证时使用 oauth2。
AISIX 在 Token 端点交换客户端凭证,把访问 Token 发送给上游,并在临近过期前复用该 Token。如果上游服务器因未授权而拒绝 Token,AISIX 会丢弃缓存的 Token,并在下次调用时获取新 Token。
以下示例创建服务器资源,并配置 AISIX 应对此上游使用的 OAuth 客户端凭证:
curl -sS -X POST "$AISIX_CP/mcp_servers" \
-H "Authorization: Bearer $AISIX_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "orders",
"url": "https://orders.example.com/mcp",
"auth_type": "oauth2",
"client_id": "aisix-gateway",
"token_url": "https://auth.example.com/oauth/token",
"secret": "YOUR_OAUTH_CLIENT_SECRET",
"scopes": ["mcp.read", "mcp.write"],
"allowed_environments": ["'"$ENV_ID"'"]
}'
❶ oauth2 对此上游使用 OAuth 2.0 客户端凭证授权。
❷ oauth2 服务器必须配置 client_id、token_url 和 secret。
❸ scopes 可选。AISIX 使用空格连接这些值,作为 Token 请求的 scope 参数。
AISIX 把访问 Token 保留在网关侧,永远不会返回给调用方。
开源 AISIX 网关
将以下经过身份认证的 github 条目添加到 mcp_servers;如果已存在同名条目,则替换它。保持其他资源不变,并通过环境变量插值提供机密信息:
mcp_servers:
- name: github
type: mcp
url: https://mcp.example.com/mcp
auth_type: bearer
secret: ${GITHUB_MCP_TOKEN}
在网关进程环境中设置 GITHUB_MCP_TOKEN。对于 none,省略 secret。对于 api_key,同一个 secret 字段会作为 x-api-key 发送。对于 oauth2,添加 client_id、token_url 和 secret,并可选择添加 scopes。对于 oauth_delegate,省略 secret;oauth2_token_exchange 参见 Entra 代理(On-Behalf-Of)令牌交换。
环境变量属于网关进程。正在运行的进程无法接收后来在主机 Shell 中新增或更改的变量。添加或轮换通过环境变量提供的凭证后,请使用新值验证资源文件并重启进程。对于容器,请使用新的环境值重新创建容器。只有当资源文件发生变化,且正在运行的进程已经拥有所有被引用的变量及其预期值时,才使用重新加载。
如果验证或重新 加载失败,网关不会应用无效条目;重新加载时会继续提供最后一次有效配置。请参阅 CLI 参考和配置状态。
凭证处理
创建或更新服务器时,AISIX 会根据 auth_type 验证凭证字段。凭证字段无效的服务器会在写入时被拒绝。
如果凭证之后失效(例如机密信息已轮换或撤销),只有该服务器的工具不可用。tools/list 会省略该服务器的工具,而直接且已获许可的调用会返回通用 JSON-RPC 内部错误。其他已注册 MCP 服务器会继续工作。AISIX 会记录详细失败信息,但不会向调用方 Agent 公开凭证详情。
向上游服务器转发调用方请求头
上面配置的凭证属于网关。而按最终用户授权的内网 MCP 服务器需要的是调用方自己的请求头,forward_client_headers 就是它获得该请求头的方式。它是一个请求头名称模式数组,默认为空,两种管理路径都支持,并且对 type: mcp 和 type: openapi 都适用——因此以工具形式暴露的 REST API 在每次工具调用时都会收到这些请求头。
通过 AISIX Cloud Admin API,可以在创建服务器时设置,也可以之后 PATCH。PATCH 会整体替换已存储的列表;发送空数组即可清空:
curl -sS -X PATCH "$AISIX_CP/mcp_servers/$MCP_SERVER_ID" \
-H "Authorization: Bearer $AISIX_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"forward_client_headers": ["authorization", "x-trace-*"]
}'
在控制台中,同一设置是服务器表单里 Advanced 下的 Forward client headers 输入框,每行填一个请求头名称或通配符。
在开源 AISIX 网关加载的资源文件中:
mcp_servers:
- name: runbooks
type: mcp
url: https://runbooks.internal/mcp
auth_type: none
forward_client_headers:
- authorization
- x-trace-*
每个条目是精确的请求头名称,或含一个 * 通配符的名称,匹配不区分大小写。被转发的请求头会到达服务器,无论 AISIX 本会如何处理它。
指定一个凭证槽位后,AISIX 会用调用方凭证取代网关凭证交给服务器,两者不会并存。authorization 是 bearer 和 oauth2 填入的槽位;api_key 填入的则是 api_key_header 指定的请求头——除非 type: openapi 的服务器另行覆盖,否则为 x-api-key。因此在同时配置了 auth_type 的服务器上点名该槽位,就意味着对于发送了该请求头的调用方,调用方的取值会胜出。校验 aud 声明的服务器会拒绝签发给网关的 Token。
oauth_delegate 和 oauth2_token_exchange 自己占用 authorization 槽位,因此在这类服务器上点名它不起作用。尤其是,它无法把携带网关 Key 的 Authorization 请求头重新放回上游请求。
凭证槽位以及链路上下文请求头 traceparent 和 tracestate,只有在模式精确点名时才会转发。凭证槽位里也包括 AWS SigV4 请求头 x-amz-security-token、x-amz-date 和 x-amz-content-sha256。*、x-* 或 x-amz-* 这类通配符永远不会匹配到它们中的任何一个。转发凭证或链路上下文是一个明确的动作,不应由宽泛的模式顺带带走。
在这个面上,上面链接指向的那张表就是全部。改名后的 api_key_header 不在其中:槽位为 x-mcp-token 的 type: openapi 服务器,其名称会被 ["x-*"] 匹配到,因此发送该请求头的调用方提供的就是自己的上游凭证,取代网关的那份。
MCP 会话槽位 mcp-session-id、mcp-protocol-version 和 last-event-id 绝不会被转发。它们标识的是调用方与 AISIX 之间 的会话,而不是 AISIX 向上游打开的会话;上游服务器会拒绝一个并非自己签发的会话 ID。其余任何模式都无法触及的请求头——host、逐跳请求头、x-aisix-* 命名空间,以及描述 AISIX 会重新序列化的请求体的那些请求头——列在 AISIX 绝不转发的调用方请求头中。
委托调用方令牌
当上游服务器用自己的 OAuth 令牌按终端用户授权,并且客户端已经持有这样的令牌时,使用 oauth_delegate。AISIX 不为该服务器保存任何凭证,而是把调用方的 Authorization 请求头原样转发给上游。
因此调用方要发送两份凭证:在 x-aisix-api-key 中发送网关 Key,在 Authorization 中发送访问上游的令牌。只有当网关 Key 通过 x-aisix-api-key 到达时,AISIX 才转发 Authorization;携带网关 Key 本身的 Authorization 请求头永远不会发往上游。调用方没有发送上游令牌时,AISIX 不带凭证调用该服务器,结果由服务器自己的响应决定。AISIX 不会替客户端获取上游令牌,客户端需要自行从上游的授权服务器获取。
oauth_delegate 适用于 type: mcp 和 type: openapi 服务器,不需要配置 forward_client_headers。