一、EMA 发布的信号:连接层问题被解决,但真正的风险在下游
2026 年 7 月 9 日,MCP 团队将企业托管授权扩展(Enterprise-Managed Authorization, EMA)提升至稳定状态。Anthropic、Microsoft、Okta 以及 Asana、Atlassian、Figma、Linear、Supabase 等厂商已宣布支持。这一扩展的核心目标很明确:用企业身份提供商(IdP)集中控制对 MCP 服务器的访问,取代过去每个服务器单独弹窗授权的模式。
从工程角度看,EMA 的架构设计是合理的。它采用 ID-JAG(Identity Assertion JWT Authorization Grant)机制:用户通过 IdP 登录后,IdP 向 MCP 服务器的授权服务器签发身份断言 JWT,授权服务器将其兑换为访问令牌。企业管理员在 IdP 侧一次性配置权限策略,终端用户继承已审批的服务器访问权限,实现「零接触」接入。
但 MCP 团队在发布文档中明确提示了一点,这一点决定了 EMA 的上限:
「这并非针对单步操作的运行时授权。」
换句话说,EMA 解决的是「谁能连接到哪个 MCP 服务器」,但不解决「连接后 Agent 能调用什么工具、以什么参数、在什么上下文中执行」。令牌颁发后,MCP 流量不再经过 IdP 检查。企业如果认为部署了 EMA 就万事大吉,实际上只是把风险从连接层转移到了运行时层。
这不是对 EMA 的否定。EMA 是企业 MCP 落地的必要基础设施,但它只是第一层控制。本文要讨论的问题是:在 EMA 之后的运行时层,权限治理存在哪些真实断层,以及如何用工程化手段补上这些缺口。
二、运行时权限的三类真实风险与工程边界
2.1 工具投毒:Context Poisoning 的协议层根源
MCP 的设计有一个常被忽视的特性:每个接入的 MCP 服务器,会将其工具描述(tool name、description、input schema)原样注入 Agent 的上下文窗口。Agent 根据这些自然语言描述决定调用哪个工具、传递什么参数。这意味着,工具描述本身成为了攻击面。
2025 年 5 月曝光的 GitHub MCP 服务器漏洞是一个典型案例。攻击者在公共仓库的 Issue 中嵌入隐藏指令,当用户使用集成 GitHub MCP 的 Agent 处理该 Issue 时,Agent 被诱导读取私有仓库数据并写入公共仓库。问题的关键不在于 GitHub API 本身有漏洞,而在于:
- Agent 同时持有对公共仓库和私有仓库的访问令牌
- 工具描述和外部内容在同一上下文窗口中混合
- Agent 的决策逻辑对外部输入没有隔离边界
OWASP 在 2025 年发布的 MCP Top 10 中,将「工具投毒」(Tool Poisoning)列为 MCP03,涵盖 Rug Pull(运行时替换工具实现)、Schema Poisoning(篡改工具描述)和 Tool Shadowing(影子工具覆盖)三种变体。这些攻击的共同点是:它们不需要攻破服务器,只需要在 Agent 的上下文中制造混淆。
从协议层面看,MCP 2026-07-28 RC 规范引入了 Extensions 框架和更严格的授权加固,但没有对「工具描述如何进入上下文」这一机制做根本性改变。只要 Agent 仍然需要读取完整的工具描述来推理,Context Poisoning 的风险就存在。
2.2 跨仓库越权:GitHub MCP 漏洞的启示
GitHub MCP 漏洞的另一个深层问题是跨资源域的权限继承。用户为 GitHub MCP 服务器授权的令牌,通常覆盖其全部仓库(公共 + 私有)。当 Agent 被诱导处理一个公共仓库的 Issue 时,它隐式地持有对该用户所有私有仓库的访问能力。
传统的 OAuth scope 机制在这里显得粗糙。repo scope 授予对全部仓库的读写权限,无法做到「只能访问正在交互的这个仓库」。这导致了一个危险的不对称:连接层授权(EMA)可以精确到「哪个用户能连接 GitHub MCP 服务器」,但运行时授权无法精确到「这个会话只能操作 pacman 仓库」。
Invariant Labs 提出的缓解方案之一是单会话单仓库策略:每个 Agent 会话在启动时绑定一个特定的仓库上下文,会话期间禁止切换或访问其他仓库。这本质上是一种动态权限降级策略——在运行时收缩 Agent 的能力边界,而非依赖连接层的静态 scope。
但这种策略在工程落地时面临挑战。MCP 协议本身没有定义「会话绑定到特定资源」的机制,这需要 Agent 框架或网关层额外实现。更复杂的是,当 Agent 需要跨仓库操作(如比较两个仓库的代码差异)时,单会话单仓库策略又会与业务需求冲突。这是一个典型的安全与功能之间的权衡问题。
2.3 级联委托:Agent 链式调用中的身份丢失
当 Agent 不再是简单的「用户 → Agent」两元结构,而是「用户 → Agent A → Agent B → 下游服务」的链式调用时,传统的身份和权限模型会快速失效。
阿里云 Agent ID Guard 的文档中提出了一个准确的描述:Agent 在调用链中同时扮演两个角色——作为被调用方(callee)时,它是 Resource Server;作为调用方(caller)时,它是 Client。这种「双重身份」是链式委托的基础,也是风险来源。
具体风险点包括:
| 风险点 | 表现 | 后果 |
|---|---|---|
| 令牌透传 | Agent A 将用户的 inbound token 直接传给下游服务 | 下游服务无法区分「用户直接调用」和「Agent 代调用」 |
| 超级权限 | 为让 Agent "能做任何事",开发者授予 Administrator 级下游权限 | Agent 被提示注入攻击后,等同于拥有最高权限的内部人员 |
| 身份丢失 | 在 User → Agent A → Agent B → Database 链中,数据库只看到 Agent B | 审计时无法追溯原始用户,合规要求无法满足 |
| 明文凭证 | API Key、AppSecret 硬编码在 Agent 代码中 | 凭证泄露后难以轮换,跨 Agent 复用造成审计盲区 |
Token Exchange(RFC 8693)是解决级联委托的标准机制:Agent 持用户的 inbound token 向授权服务器申请 outbound token,outbound token 的 scope 和 audience 被限制为「特定的下游服务 + 最小必要权限」。阿里云 Agent ID Guard 和 Microsoft Entra ID 都实现了这一机制。
但 Token Exchange 的普及率仍然有限。大量开源 MCP 服务器和 Agent 框架尚未集成这一机制,开发者往往图方便直接使用长期有效的 Service Account token,或用环境变量注入全局 API Key。这种实践在 PoC 阶段无可厚非,但在生产环境中等同于放弃了运行时权限控制。
三、从「能连接」到「能控制」:三层治理架构
连接层授权(EMA)和运行时授权之间的断层,需要用工程化的三层架构来填补。这一架构不是理论构想,而是已经被多个云厂商和安全项目验证的落地模式。
3.1 网关层:工具调用拦截与策略执行
网关层的核心职责是:在 Agent 的 tool call 到达 MCP 服务器之前,执行实时授权检查。这与 EMA 的职责形成互补——EMA 控制「谁能连」,网关层控制「连上后能做什么」。
AuthzX MCP Gateway 是一个代表性的开源实现。它作为 stdio 代理插入 MCP Client 和 Server 之间,对每个 tool call 执行以下检查:
{
"ts": "2026-05-25T10:03:11.482Z",
"level": "info",
"msg": "mcp_tool_call",
"subject": "agent:ai-assistant",
"tool": "database__query",
"allowed": true,
"latency_ms": 0.8
}其策略引擎基于 Rego(OPA 策略语言),允许细粒度到工具名、参数内容、调用上下文的规则。例如:
package authzx.mcp
default allow := false
# 允许只读查询
allow if { input.resource.name == "database__query" }
# 允许写入,但禁止破坏性 SQL
allow if {
input.resource.name == "database__execute"
not contains(lower(input.resource.attributes.sql), "drop")
not contains(lower(input.resource.attributes.sql), "delete from")
}阿里云 AI Gateway 则采用了 Cedar 策略语言,将每个 tool call 映射为 (Principal, Action, Resource, Context) 四元组进行授权评估。其策略示例:
permit (
principal is AgentIdentity::OAuthUser,
action == AIGateway::Action::"mcp-servers.order-service.create-order",
resource == AIGateway::Gateway::"acs:apig:cn-beijing:{account_id}:gateway/gw-abc..."
)
when {
context.input.amount >= 1000
&& ip(context.sourceIp).isInRange(ip("192.168.1.0/24"))
};网关层的关键设计原则:
- 默认拒绝(Default Deny):未显式允许的工具调用一律拒绝
- 最小权限(Least Privilege):每个 Agent 实例只获得完成当前任务所需的最小工具集
- 实时审计:每次授权决策生成结构化日志,包含 subject、tool、arguments、decision、latency
- 低延迟:授权检查必须在毫秒级完成,不能成为 Agent 响应的瓶颈
3.2 策略层:从静态 RBAC 到动态上下文感知
网关层的策略需要策略层的支撑。传统的 RBAC(基于角色的访问控制)在 Agent 场景下显得过于静态——Agent 的权限需求随任务变化,同一 Agent 在不同会话中可能需要不同的工具集。
动态权限调整的几个维度:
| 维度 | 控制逻辑 | 实现方式 |
|---|---|---|
| LLM 可信度 | 可信度低于阈值时限制敏感工具 | 基于历史行为评分或外部风险评分 |
| 请求来源 | 限制特定 IP 范围或网络区域 | 网关层检查 sourceIp |
| 时间窗口 | 限制非工作时间的敏感操作 | 策略条件中增加 time 约束 |
| 数据敏感度 | 根据资源标签动态调整权限 | 资源元数据 + ABAC 策略 |
| 会话绑定 | 单会话单仓库/单数据库/单系统 | 会话启动时注入上下文约束 |
腾讯云的「Least Agency」原则提供了一个实用的框架:Agent 获得的权限永远是「最小代理权限」,且权限随任务生命周期动态变化。任务开始时授予必要权限,任务结束后立即回收。这与 JIT(Just-in-Time)访问控制的理念一致。
AgentScope 2.0 的权限系统也体现了这一思路:工具调用不再是简单的允许/禁止,而是根据静态规则、工具类型和输入内容判断「允许 / 拒绝 / 用户确认」。对于高风险操作(如文件删除、命令执行),自动进入人工审批流程。
3.3 审计层:不可抵赖的行为追溯
审计层的目标是:当 Agent 执行了敏感操作或发生安全事件时,能够完整追溯「谁在什么上下文中、通过哪个 Agent、调用了什么工具、传了什么参数、得到了什么结果」。
审计层需要记录的关键字段:
| 字段 | 说明 |
|---|---|
| trace_id | 跨服务调用的追踪标识(W3C Trace Context) |
| user_id | 发起请求的原始用户 |
| agent_id | 执行操作的 Agent 实例 |
| session_id | Agent 会话标识 |
| tool_name | 被调用的工具名 |
| arguments | 工具参数(敏感字段脱敏) |
| timestamp | 调用时间(含时区) |
| decision | 授权决策(allow/deny/monitor) |
| policy_id | 匹配的策略标识 |
| downstream_service | 下游服务标识 |
MCP 2026-07-28 RC 规范正式将 W3C Trace Context 纳入标准(SEP-414),规定了 traceparent、tracestate、baggage 在 _meta 中的键名。这意味着,从 Host 应用出发的追踪可以贯穿 Client SDK、MCP Server、以及 Server 调用的下游服务,在 OpenTelemetry 兼容的后端形成完整的调用链。
审计层的另一个关键能力是异常行为检测。360 在《AI Agent 攻防演练指南 2026》中指出,攻击方不再停留于单点漏洞,而是围绕 Agent 的权限、工具和业务系统发起链式攻击。审计层需要能够识别以下异常模式:
- 同一 Agent 在短时间内高频调用敏感工具
- Agent 调用的工具组合偏离历史基线
- 参数中出现异常模式(如路径遍历、SQL 注入特征)
- 跨资源域的异常数据流动(如从私有仓库向公共仓库写入)
四、协议演进与工程落地清单
4.1 MCP 2026-07-28 RC 的安全信号
MCP 协议在 2026-07-28 RC 中做出了几个与安全相关的关键改进:
- 状态化核心:移除
initialize握手和Mcp-Session-Id,请求可通过普通负载均衡路由,不再需要 sticky session。这意味着网关层可以更容易地插入和水平扩展。 - Mcp-Method / Mcp-Name Header:网关可以在不解析请求体的情况下路由和限流,为工具级策略执行提供了协议支撑。
- Authorization Hardening:强制
iss验证(RFC 9207)、改进 DCR(Dynamic Client Registration)、明确 scope 累积规则。这些改进减少了 OAuth 实现中的常见漏洞。 - Multi Round-Trip Requests:用
InputRequiredResult替代 SSE,服务器可以在处理客户端请求时发起交互式确认。这为「用户确认」机制提供了协议原生支持。
但这些改进主要聚焦在连接层和传输层。运行时权限控制仍然需要应用层和网关层的额外实现。
4.2 工程落地检查清单
以下清单适用于计划在企业环境中部署 MCP 的团队。它不是通用安全基线,而是专门针对 MCP 运行时权限治理的增量控制项:
| 控制项 | 优先级 | 实施要点 |
|---|---|---|
| 部署 EMA 或等效 IdP 集成 | P0 | 集中管理连接层授权,禁止个人令牌混用 |
| 部署 MCP 授权网关 | P0 | 拦截所有 tool call,执行基于策略的实时授权 |
| 实施 Token Exchange | P1 | 禁止 Agent 透传用户令牌,使用限定 scope 的 outbound token |
| 单会话资源绑定 | P1 | 敏感场景下限制 Agent 会话只能访问特定资源域 |
| 工具描述校验 | P1 | 部署前扫描工具描述,检测异常注入模式 |
| 高风险操作人工确认 | P1 | 对删除、写入、权限变更等操作强制用户确认 |
| 全链路审计日志 | P1 | 记录每次 tool call 的完整上下文,保留不少于 180 天 |
| 异常行为检测 | P2 | 建立 Agent 行为基线,检测偏离基线的调用模式 |
| 定期权限审查 | P2 | 每月审查 Agent 授权范围,回收过期权限 |
| 供应链安全检查 | P2 | 对第三方 MCP 服务器进行安全扫描和来源验证 |
结论
MCP 企业托管授权扩展的发布是一个重要里程碑,它解决了企业 MCP 部署中最突出的运维痛点——重复授权和权限碎片化。但企业安全团队需要清醒地认识到:EMA 只是第一层控制,它解决的是「谁能连接」,而非「连接后能做什么」。
运行时权限治理才是真正的战场。工具投毒、跨仓库越权、级联委托三类风险,都发生在令牌颁发之后、工具调用之前。补上这一断层需要三层工程化手段:网关层的实时拦截、策略层的动态上下文感知、审计层的全链路追溯。
协议层面,MCP 2026-07-28 RC 提供了更清晰的网关集成点和交互式确认机制,但运行时权限控制仍然依赖应用层实现。对于计划将 MCP 投入生产的企业,建议在部署 EMA 的同时,同步规划和实施网关层授权策略,而不是等到安全事件发生后才补课。
Agent 的自主权越大,其权限边界就必须越清晰。这不是对 Agent 能力的限制,而是对其可靠性的保证。
