当你第一次将 MCP 服务器接入真实的生产系统时,你会发现教程中轻描淡写的一点:该协议赋予了智能体(Agent)能力,但并没有给工具服务器一个每个审计日志都要求的答案——这是代表哪个人执行的操作? 你可以在不解决这个问题的情况下交付一个可运行的演示 demo,但如果不解决它,你无法向受监管的企业交付产品。而这两种状态之间的鸿沟,几乎完全是一个伪装成 OAuth 问题的分布式系统问题。
团队在这个鸿沟中寻求的解决方案,大致按尝试顺序排列,就像是把 OAuth 工作组十五年来一直警告的每一种反模式都游览了一遍。在 MCP 服务器环境中共享服务账号;将长期有效的个人令牌粘贴到配置中;或是乐观地认为“我们只需转发用户的会话 Cookie,让下游服务去处理就好”。每种方案在预发环境中都有效。但在安全审查第一次真正介入时,每种方案都会以不同的方式崩盘。
到 2026 年定稿的 MCP 授权规范高度依赖 OAuth 2.1 及其 PKCE、RFC 8707 资源指示器、RFC 7591 动态客户端注册以及 RFC 9728 受保护资源元数据。这一套组合拳告诉你智能体如何为 MCP 服务器获取令牌。它刻意没有告诉你 MCP 服务器随后如何调用它执行任务所需的其他五个系统。这第二次跳转——智能体 → MCP 服务器 → 下游 API——正是身份透传(Identity Threading)存在的地方,也是大多数生产部署仍在即兴发挥的地方。
你会在实际应用中见到的三种失败模式
共享服务账号是最常见的,因为它是最简单的。MCP 服务器持有单个 GitHub PAT、单个 Jira API 密钥或单个内部服务令牌,所有的工具调用都以该身份发出。系统可以运行。但随后有人通过智能体删除了生产资源,审计日志显示操作者是 [email protected],应急响应团队无法确定是哪个自然人触发了它。更糟糕的是,下游服务通常会做出的每一个基于用户的授权决策——Alice 能看到这个 PR 吗?Bob 能删除这个 Issue 吗?——现在都需要 MCP 服务器根据一个它并不拥有的权限模型来重新实现,而且往往实现得很拙劣。这就是多了一道手续的混淆代理(Confused Deputy)问题,也是 OWASP 的 MCP Top 10 中明确指出的 MCP01:令牌管理不当和密钥泄露。
长期有效的每用户令牌是第二招。每个用户生成一个个人访问令牌(PAT),MCP 服务器根据用户 ID 进行存储,每次工具调用都使用正确的令牌。审计追踪是正确的,但你刚刚构建了一个没有任何真实凭证库所具备的轮换、撤销或范围收窄特性的凭证库。这些令牌没有你的安全团队能够接受的过期时间,授予的权限范围往往远超智能体所需,并且存储在 MCP 服务器碰巧使用的任何存储介质中——通常是 Postgres 的一个字段,偶尔是环境变量,有时甚至是磁盘上的文件。第一次钓鱼事件会很快让其中的风险暴露无遗。
会话 Cookie 转发是第三招,也是失败得最令人意外的一招。理由听起来很合理:用户已经登录了,智能体运行在他们的浏览器上下文中,只需转发会话,让下游服务看到它一贯看到的已认证用户即可。只要智能体和所有工具服务器都位于同一个 SSO 域内,这种方案就有效。一旦工具服务器位于不同的 Cookie 作用域——不同的子域名配置、不同的 OIDC 提供商或合作伙伴 SaaS——Cookie 要么无法到达,要么在到达时被剥离了使其有效的跨站标志。出于类似原因,MCP 规范明确禁止令牌转发(Token Passthrough):为受众 A 签发的令牌永远不应呈现给受众 B,因为受众声明(Audience Claim)是防止一个服务被欺骗去冒充另一个服务的核心机制。
协议真正解决了什么,又给你留下了什么
2026 版 MCP 授权规范是一次真正的改进,准确了解它涵盖的内容非常重要。MCP 服务器被建模为 OAuth 2.1 资源服务器。MCP 客户端是一个 OAuth 2.1 客户端。PKCE 是强制性的。通过 RFC 7591 进行的动态客户端注册意味着 Claude Desktop 或 Cursor 可以在一个它们从未见过的 MCP 服务器上出现,完成注册并完成授权码流程,而无需任何带外协调。通过 RFC 8707 实现的资源指示器要求客户端指明它打算调用的特定 MCP 服务器,这让授权服务器能够将生成的令牌受众声明限制得足够窄,从而无法被静默重放到另一个服务器。通过 RFC 9728 实现的受保护资源元数据让 MCP 服务器可以发布其授权服务器的位置,以便客户端可以发现认证流程而非硬编码。
这是对“智能体如何为 MCP 服务器获取令牌”的一个完整且可信的回答。但这并不是“MCP 服务器如何代表用户调用其他服务”的答案。规范明确指出禁止令牌转发——MCP 服务器不能简单地转发智能体呈现的任何令牌——但它将实际的委派模式留给了实现者。MCP 仓库中有一个未解决的 Issue #214,请求明确的代行令牌交换(On-behalf-of Token Exchange)支持,正是因为这个接缝处是目前每个企业集成都在即兴发挥的地方。
令牌交换是经得起审计考验的模式
在审计中站得住脚的机制是 RFC 8693 定义的 OAuth 2.0 令牌交换 (token exchange),这种机制在 Microsoft Entra、Auth0 和 Okta 已经悄悄推行多年的“代表 (on-behalf-of)”模式中得到了应用。其形态非常直接:MCP 服务器接收到一个其 audience 是该 MCP 服务器自身的令牌。当它需要调用下游服务时,它将该令牌连同请求一起提交给授权服务器,并请求一个其 audience 为下游服务的全新令牌。授权服务器验证原始令牌,应用配置好的任何委托策略,并签发一个全新的、权限范围窄、生命周期短且绑定到新 audience 的令牌。MCP 服务器随后使用这个新令牌调用下游 API。下游 API 看到的令牌将原始用户标注为 subject(主体),将 Agent 标注为 delegated actor(委托参与者),并将自身标注为 audience(受众),从而可以进行相应的授权。
对审计故事至关重要的属性几乎可以从这种形态中免费获得。用户身份贯穿每一个跳转 (hop),因为 subject 声明在令牌交换过程中得以保留。下游服务根据其自身的策略做出自己的授权决策,因为令牌命名的是用户,而不是 MCP 服务器。每个令牌都有严格的过期时间——以分钟计,而非以天计——因为交换成本很低,如果需要,可以在每次调用时进行。撤销机制也有效,因为在授权服务器端终止用户的会话会使整个链条失效。而且 Agent 本身在 actor 声明中被命名,因此当审计日志显示“Alice 的会话通过 Agent X,在 14:32 调用了服务 Z 上的工具 Y”时,是 OAuth 令牌本身承载了溯源信息,而不是你事后必须去关联的日志行。
成本是真实存在的。你需要一个支持令牌交换的授权服务器——大多数企业级 IdP 都支持,但配置过程很少是一帆风顺的。你需要每一个下游服务都验证 audience 并接受由你的 IdP 签发的令牌,当下游是具有自身认证模型的第三方 SaaS 时,这是一个非同小可的集成工作。你还需要 MCP 服务器本身围绕“永远不持有任何人的长期凭证”这一假设进行设计——每一次出站调用都要执行交换,每一个令牌都是瞬时的,链条中的每一个失败模式都必须得到处理。这比将 PAT 放入环境变量中要多做很多工作。但正是这些工作,才使得系统能够交付给受监管行业的客户。
审计头是大多数团队投入不足的地方
即使有了令牌交换,还有一个大多数团队都将其视为事后才考虑的层:审计头 (audit header)。OAuth 令牌承载了安全模型所需的溯源信息,但运维日志需要以人类可读的形式重构相同的链条。一条仅显示 tool: list_repos, status: 200 的工具调用日志行对于事件响应毫无用处。而一条显示 user: [email protected], agent: claude-3.7-sonnet (session: abc123), mcp_server: github-mcp, tool: list_repos, downstream: github_api, status: 200, latency: 412ms 的日志行,才是 SOC 分析师在凌晨 3 点出故障时真正可以利用的东西。
务实的模式是在链条的每一次跳转中传播一组小巧、结构化的身份标头 (identity headers)——用户 ID、Agent 标识符及版本、Agent 会话 ID 和请求关联 ID——并在每一层进行记录。OAuth 令牌是安全边界;标头是可观测性层。它们在设计上是重叠的,因为当它们不一致时,你就发现了一个 Bug。将此视为基础架构级工作并在第一天就交付的团队,比那些在第一次审计发现问题后才补救的团队更容易通过 SOC 2 认证。
架构上的觉悟
这一切之所以比看起来更难,是因为 Agent 系统中的用户身份识别是一个分布式系统问题,而协议层并没有为你解决这个问题。MCP 为你提供了一种 Agent 与工具服务器通信的简洁方式。它并没有为你提供一种简洁的方式,让该工具服务器将用户的身份穿透到它必须进行的后续五个跳转中,因为这不是任何单一协议能够解决的问题——它取决于你的 IdP、你的下游服务、你的审计需求以及你的信任边界。规范标准化的 OAuth 2.1 技术栈是正确的基础。令牌交换是正确的委托模式。单次调用短效令牌是正确的凭证生命周期。结构化审计头是正确的可观测性层。这些都不是什么奇技淫巧。但它们全都是工作量。
能够正确处理这些问题的团队,往往会在其 MCP 服务器前构建一个小的身份感知中间件层——有时被称为 MCP 网关 (MCP gateway),有时只是一个边车 (sidecar)——它拥有令牌交换逻辑,执行 audience 验证,并在一个地方输出审计日志。随着 MCP 服务器数量的增加,这种形态是可以扩展的,因为它意味着每个单独的 MCP 服务器不再负责认证的繁琐过程,而是回归到负责其自身的工具。协议赋予了 Agent 能力。架构则必须赋予用户问责性。这是两个不同的问题,将它们混为一谈会导致你最终将持有者令牌 (bearer token) 放在环境变量中,并得到一个无法通过的安全审查。
会员专享
余下内容仅对会员开放。
会员可读完整内容 —— 每一个公开发布的观点背后,那些框架、决策与推理的全貌。
- —完整文章,包含未公开存档的部分
- —可落地的工作框架,附带权衡与决策依据
- —新文章抢先看,先于公开发布
随时取消 · 一次订阅,畅读全部