客户端身份认证
MCP 客户端可以通过两类入口访问 AISIX:聚合入口 /mcp 以 <server>__<tool> 形式提供所有已注册服务器的工具,/mcp/{server} 则以工具的原始名称提供单个服务器的工具。本文介绍调用方如何在这些入口上证明自己的身份。
客户端身份认证与上游身份认证相互独立:客户端发送给 AISIX 的凭证用于向 AISIX 标识调用方,而 AISIX 发送给上游 MCP 服务器的凭证默认由网关侧持有。配置为代表调用方访问的服务器会收到调用方自己的令牌或用它换得的令牌,但绝不会收到网关 Key。
共有四种模式,同一个环境可以组合使用:
| 模式 | 客户端发送 | 适用场景 |
|---|---|---|
| 网关 API Key | Authorization: Bearer <API Key> | 默认方式。机器对机器的调用方,以及由你签发 Key 的 Agent。 |
| OAuth 登录 | 身份提供商签发的 Access Token | 能够自行发现登录流程的标准 MCP 客户端。 |
| 交互式登录 | 网关在浏览器登录后签发的会话令牌 | 只配置了 URL 的客户端,访问每个用户都有自己上游账号的服务器。 |
| 匿名 | 不发送任何凭证 | 可信网络中无法携带凭证的客户端。 |
无论采用哪种模式,调用方都会解析为一个 API Key 主体。它的工具授权决定了可以列出和调用哪些工具;已配置的限流和安全护栏可以治理工具调用,而用量仍归属于该主体。在 AISIX Enterprise 和 AISIX Cloud 中,匹配的预算也会生效。因此,匿名调用方与认证调用方受到相同的控制。
前置条件
开始前,请准备以下内容:
- 完成 AISIX Enterprise、AISIX Cloud 或开源 AISIX 网关的设置 MCP 网关,并保留该指南末尾使用的
AISIX_PROXY和AISIX_MCP_KEY值。 - 对于 AISIX Enterprise,还需保留 AISIX Enterprise 入门中的
AISIX_CP、AISIX_TOKEN和ENV_ID。对于 AISIX Cloud,请从所属组织获取这些值;若要申请访问权限,请联系 API7。 - 用于运行请求示例的 cURL。
网关 API Key
这是默认方式,无需任何配置。客户端在每个请求上发送自己的 Key:
curl -sS -X POST "$AISIX_PROXY/mcp" \
-H "Authorization: Bearer $AISIX_MCP_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'
该 Key 的授权决定了调用方能看到和调用哪些工具。将 Key 限定到特定工具、整个服务器或全部工具,参见控制工具访问;在环境或团队级别授权,参见 MCP 访问策略。
也可以使用 x-api-key: <API Key> 作为替代请求头。
如果客户端还需要在 Authorization 中携带自己访问上游服务器的令牌(auth_type: oauth_delegate 的服务器就要求这样做),则改为在 x-aisix-api-key 中发送网关 Key:
curl -sS -X POST "$AISIX_PROXY/mcp" \
-H "x-aisix-api-key: $AISIX_MCP_KEY" \
-H "Authorization: Bearer $UPSTREAM_TOKEN" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'
请求带有 x-aisix-api-key 时,AISIX 只用它认证调用方,不读取 Authorization 或 x-api-key。完整的优先级规则参见在 x-aisix-api-key 中发送网关 Key。
OAuth 登录
桌面助手等标准 MCP 客户端可以让用户登录,而不必粘贴一个 Key。它们的做法是:读取 401 响应上的 WWW-Authenticate 响应头,获取其中指向的受保护资源元数据,然后针对元数据中声明的授权服务器执行 OAuth 流程。
当环境同时具备以下两项时,AISIX 会 发布该元数据:
- 一个规范的 MCP 资源 URL——客户端访问该环境
/mcp入口所使用的公开 URL;以及 - 至少一个已启用、使用 JWKS 模式的 OIDC 信任提供商,即 Token 必须来自的授权服务器。共享密钥(HMAC)提供商不发布 OAuth 发现元数据,但仍可用于 JWT 身份认证。
两者都配置后,GET /.well-known/oauth-protected-resource(以及 /.well-known/oauth-protected-resource/mcp)会返回资源标识、Token 可以来自的 issuer,以及 Token 必须携带的 scope。若未配置,这些路由返回 404,401 响应也不携带 challenge,与该能力不存在时完全一致。
网关按签发 Token 的信任提供商的 audiences 校验 Token 的 aud,没有任何匹配值时拒绝该 Token,即使登录已经成功。网关不会将 aud 与资源 URL 比较,资源 URL 只用于发现元数据。因此,请按身份提供商实际签发的值设置 audiences:
- 执行 OAuth 流程的 MCP 客户端会把资源 URL 作为
resource参数发送。如果身份提供商遵循该参数,Token 的 audience 就是该 URL(包括其中的路径前缀),此时audiences必须按原样列出它。 - 如果身份提供商签发其他 audience,则应在
audiences中设置该值。对于使用 OBO 令牌交换的 Microsoft Entra ID,该值是 Token 的aud声明,v2.0 访问令牌中即网关的客户端 ID。
如果提供商还接受其他 audience,匹配其中任一值的 Token 也可能通过 audience 检查,因此需要按预期的资源隔离范围收窄该列表。Token 仍须满足签名、issuer、有效期、scope 等其余验证要求。
还需通过调用方 API Key 的 jwt_provider 和 jwt_subject 直接绑定身份,或通过 JWT Claim 映射,将已验证的身份解析到一把有效的调用方 API Key。该 Key 必须具备所需的 MCP 工具授权。仅完成身份提供商登录或设置发现元数据,不会创建身份绑定或授予工具访问权限。
AISIX Enterprise 或 AISIX Cloud
在环境上设置资源 URL:
curl -sS -X PATCH "$AISIX_CP/environments/$ENV_ID" \
-H "Authorization: Bearer $AISIX_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"mcp_resource_url": "https://gateway.example.com/mcp"
}'
托管控制面要求该 URL 是绝对的 http 或 https URL,路径以 /mcp 结尾,不带查询参数或片段。路径必须经过百分号编码,不能包含空段、. 或 ..。每个环境只有一个资源 URL。如果 AISIX 前面的网关按路径前缀路由,请带上该前缀,例如 /team-a/mcp,参见在按路径前缀路由的网关后运行。该 URL 会按原样发布在一个无需认证的端点上,其中的用户信息(user:password@)也不例外,因此不要在其中写入凭证。传入 null 可清除该值并关闭 OAuth 发现。
对于文件定义的设置,只有当该 URL 能解析为绝对 HTTP(S) URL、不带查询参数或片段、路径以 /mcp 结尾时,OAuth 发现才会启用。请使用经过百分号编码且不含空段、. 或 .. 的路径,这也是托管控制面的要求。资源文件路径接受一些托管 API 会拒绝的非规范写法,但前方网关对它们的规范化可能与 AISIX 发布的公开资源 URL 不一致。
在控制台中,同样的设置位于环境的 MCP 访问 页面;当已启用的提供商的 audiences 不包含该 URL 时,该页面还会给出警告。这只是警告,不会阻止保存,因此签发其他 audience 的身份提供商(例如 Microsoft Entra ID)出现该警告属于预期情况。
开源 AISIX 网关
在单例 mcp_auth_settings 条目上设置 resource_url;如果该条目不存在,则创建它,并保持所有 anonymous 设置不变。将 corp-sso 添加到 oidc_providers:
mcp_auth_settings:
- resource_url: https://gateway.example.com/mcp
oidc_providers:
- name: corp-sso
issuer: https://sso.example.com/realms/agents
audiences:
- https://gateway.example.com/mcp
required_scopes:
- mcp:tools
mcp_auth_settings 最多只能有一条。第二条会在加载时被拒绝;若重复条目以其他方式进入了运行中的网关,发现面会保持关闭,而不是从中挑选一条。
在按路径前缀路由的网关后运行
如果 AISIX 前面的网关共用一个域名并按路径前缀路由,请将公开 URL(例如 https://gateway.example.com/team-a/mcp)配置为资源 URL。
/mcp 之前的部分都是前缀,由前置网关在转发前剥离。AISIX 自身的路由不变,因此前置网关必须按如下方式转发:
| 公开路径 | AISIX 收到的路径 |
|---|---|
/team-a/mcp | /mcp |
/team-a/mcp/{server} | /mcp/{server} |
/team-a/.well-known/oauth-protected-resource/mcp | /.well-known/oauth-protected-resource/mcp |
前置网关还必须原样返回 401 响应上的 WWW-Authenticate 响应头。该质询中的 resource_metadata 会变为 https://gateway.example.com/team-a/.well-known/oauth-protected-resource/mcp,元数据中的 resource 则是按原样配置的 URL。
如果没有负责剥离前缀的前置网关,访问该路径的请求会收到 AISIX 返回的 404,因此这种情况下不要配置前缀。
客户端必须遵循 401 中的 resource_metadata。如果客户端改为根据源站(origin)拼接 well-known URL,在共用域名时将无法访问到该网关。
带前缀的路径需要 1.8.0 之后发布的网关。普通的 /mcp URL 没有版本要求。只要环境中注册了运行 1.8.0 或更早版本、不低于最低支持版本且在最近 5 分钟内发送过心跳的网关,AISIX Cloud Admin API 和控制台就会拒绝任何写入该值的保存(包括修改 mcp_anonymous),返回 422 和错误码 DP_INCOMPATIBLE。要继续操作,请升级该网关,或在同一个 PATCH 中清除该 URL。保存之后才加入的 1.8.0 或更早版本网关会保持 OAuth 发现关闭,只在该网关的日志中输出一条警告。
交互式登录
对于 auth_type: oauth2_authorization_code 的服务器,网关可以自行完成整 个登录。客户端只配置 /mcp/{server},用户在浏览器中登录身份提供商并授权一次上游,之后客户端持有网关签发的会话令牌。参见 MCP 交互式登录。
匿名访问
匿名访问允许不携带任何凭证的客户端访问你为其开放的入口。它面向的场景是:客户端集群原本对接的网关从不要求凭证,如今逐个改造客户端并不现实。
匿名请求仍然会解析为你指定的 API Key 主体。它的工具授权决定了可以列出和调用哪些工具;已配置的限流和安全护栏可以治理工具调用,而用量仍归属于该主体。在 AISIX Enterprise 和 AISIX Cloud 中,匹配的预算也会生效。只有凭证检查发生变化。
任何能从允许网段访问该网关的人,都可以在没有凭证的情况下调用被允许的工具,相关用量会计入该环境。请把来源网段白名单当作真正的访问控制来对待,并把主体的工具授权收窄到客户端实际需要的范围。
匿名访问不是什么
无效凭证不会降级为匿名。 只要请求带有 x-aisix-api-key、Authorization 或 x-api-key 中的任一请求头,无论其值是什么,都视为调用方提供了凭据,请求会按正常流程认证。凭证无效、过期、被禁用,或请求头的值为空、纯空白、认证方案错误、Bearer 后没有 token 时,返回 401,不会改用匿名身份。只有三个请求头都没有出现的请求才视为未提供凭据;只有同时满足下述匿名访问配置、来源网段、入口及主体授权条件,才可能走匿名路径。
它对不被允许的调用方不可见。 所有拒绝——来源不在白名单、该服务器未对匿名开放、主体被删除或禁用、匿名访问未开启——返回的都是与“未配置匿名访问”时完全相同的 401。调用方无法区分这些情况,也无法区分某个 MCP 服务器是已注册还是根本不存在。运维可以在网关的 aisix_auth_decisions_total 指标上看到具体原因。
配置项
匿名访问按环境配置:
| 字段 | 含义 |
|---|---|
api_key_id | 匿名流量运行时使用的 API Key。 |
source_cidrs | 允许进入的客户端来源网段。必填且不能为空。 |
servers | 匿名调用方可以访问的 MCP 服务器。必填且不能为空。 |
aggregate_entry | 聚合入口 /mcp 是否也对匿名调用方开放。默认关闭。 |
enabled | 设为 false 可在保留配置的情况下关闭匿名访问。默认为 true。 |
其中两项需要展开说明。
服务器列表是能力上界
servers 不仅是要开放的 /mcp/{server} 入口列表,它同时限定了该主体在任何入口上能触达的范围,聚合入口也不例外。否则,当主体自身的工具授权比该列表更宽时,匿名调用方就能在聚合入口上直接指定 <server>__<tool>,从而访问到按服务器入口已经关闭的服务器。
因此匿名调用方的有效授权 = 列表中服务器的工具 ∩ 主体自身的授权。tools/list 和 tools/call 都遵循这一结果,所以匿名调用方绝不会看到自己无法调用的工具。
新注册的 MCP 服务器默认不对匿名开放。要让匿名调用方访问它,必须把它的名称加入该列表。
每个条目都标识一台已注册的服务器,而不是模式。AISIX 会拒绝包含 * 的服务器名称,因此该能力上界不会扩展到其他服务器。重命名服务器后,它仍留在允许列表中,读回时会显示新名称;删除服务器则会留下一个未生效的条目。有关重新创建和清理行为,请参阅重命名或删除 MCP 服务器。
主体必须拥有自己的授权
在 AISIX Enterprise 和 AISIX Cloud 中,主体必须携带自己的 mcp_access 配置块。没有该配置块的 Key 会被拒绝:它会取得环境层和团队层留下的全部权限,因此一旦这些策略被放宽,匿名访问就可能在无人重新审视此设置的情况下扩大。带有自己配置块的 Key 则始终受自身 allow 列表约束,无论其他层如何变化。
在使用资源文件配置的开源网关中,同一个配置块是该主体唯一的权限层,因为资源文件没有策略集合。servers 列表仍然是额外的能力上界。
在 AISIX Enterprise 或 AISIX Cloud 中配置
导出匿名流量所使用的 API Key ID。该 Key 必须属于当前环境,并携带上述 MCP 授权:
export ANON_KEY_ID="YOUR_ANONYMOUS_PRINCIPAL_API_KEY_ID"
在环 境上设置该配置块:
curl -sS -X PATCH "$AISIX_CP/environments/$ENV_ID" \
-H "Authorization: Bearer $AISIX_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"mcp_anonymous": {
"api_key_id": "'"$ANON_KEY_ID"'",
"source_cidrs": ["10.0.0.0/8"],
"servers": ["everything"],
"aggregate_entry": false
}
}'
❶ 匿名流量以其身份运行的 API Key 主体。它必须属于该环境,并且携带自己的 mcp_access 配置块。
❷ 与 AISIX 通过 Real-IP 配置解析出的来源地址比对,而不是客户端提交的请求头。单个地址请写成 10.0.0.1/32。
❸ 已批准且对该环境开放的服务器。匿名调用方只能访问 /mcp/everything,其他一概不能。
❹ 聚合入口继续要求网关凭证。开启前请阅读匿名访问与 OAuth 登录。
传入 "mcp_anonymous": null 可关闭匿名访问。该变更无需重启即可应用到运行中的网关。
在控制台中,同样的设置位于环境的 MCP 访问 页面,开启匿名访问需要显式确认风险提示。
在开源网关中配置
将 anonymous-mcp 添加到 api_keys。在单例 mcp_auth_settings 条目中添加 anonymous;如果该条目不存在,则创建它。保持 resource_url、everything 服务器及其他资源不变。下方 ID 派生自 anonymous-mcp:
api_keys:
- display_name: anonymous-mcp
key_env: ANONYMOUS_MCP_KEY
allowed_models: []
mcp_access:
allow:
- everything__*
mcp_auth_settings:
- anonymous:
api_key_id: d6869ae7-741a-598e-8213-16672e922546
source_cidrs:
- 10.0.0.0/8
servers:
- everything
aggregate_entry: false
加载该文件前,请在网关进程环境中设置 ANONYMOUS_MCP_KEY。如果使用其他 API Key 显示名称,请把 api_key_id 替换为该条目的确定性派生 ID。用于 OAuth 发现的 resource_url 字段位于同一条 mcp_auth_settings 条目上;两项设置相互独立,可以只配置其中一项。