Skip to content
Unstructured Play
Go back

MCP 企业多用户认证:从 Harness 凭证隔离到 OAuth 2.1 动态授权全链路

回路 / The Loop — 提出有价值的问题,比直接获取答案更重要。

这个专题收集和整理我与 Gemini、ChatGPT、Claude 等 AI 的对话记录。每一篇对应一次完整的提问与回答过程。通过留存这些层层追问,还原日常思考的真实轨迹。


交互式图解 — 本文配套两份可交互的可视化资料,帮助理解认证流程:


概要

这是一场围绕企业级 AI Agent 多用户身份认证的深度对话。从”多人共用一个 Agent 时,身份验证和 Token 该放在哪一层”出发,逐步深入到 MCP(Model Context Protocol)协议对工具层认证的标准化定义,最终完整推演了一个远程 MCP 工具从 401 挑战到动态授权再到恢复执行的全链路时序流程。

核心结论:企业多用户场景下,凭证必须与大模型的认知空间(Context Window)彻底解耦——Token 存 KMS 不存 Session,身份注入发生在 Harness 拦截层,工具调用通过 OAuth 2.1 + RFC 8707 资源指示器实现定向锁定。认知空间可共享,但执行空间和数据空间必须绝对隔离。


Q: 企业 Agent 服务多个员工时,每个人的身份验证在哪一层处理?Token 存在哪里?

身份验证不能侵入大模型的推理层(Orchestration),也不能让大模型直接接触敏感 Token。它由三个组件联合完成:

Harness 层(控制核心) — 作为安全网关,负责拦截上游请求、提取用户身份标识(User ID),并在调用工具时动态注入凭证。

Session 层(状态与上下文) — 多用户隔离的天然边界。Session 数据库采用 Tenant_ID + User_ID + Session_ID 复合主键索引。

Tools / MCP 层(执行代理) — 升级为”身份感知型工具网关”。工具定义本身是静态的 Schema,但执行时接受 Harness 传递的动态身份上下文。

Token 存储原则

强烈建议不要将 Token 存在 Session 账本中。 原因很直接:Session 账本会作为历史记录完整喂给大模型(即 messages 数组),如果直接存放明文 Token,一旦被 Prompt Injection 攻击利用就会泄露凭证。

标准的分离存储方案:

存储组件存放内容安全策略
Session 数据库仅存放 User_IDTenant_ID 及脱敏后的对话上下文ACL 隔离,禁止跨用户读取
KMS / Vault各用户对应外部工具的 Access_TokenRefresh_TokenUser_ID + Tool_ID 为联合加密主键;仅对 Harness 进程开放

Q: 凭证在运行时是怎么流转的?

遵循**“前端透传、中枢换取、即用即抛”**原则:

  1. 身份透传 — 员工发起请求时,上游客户端(如企业微信)在 HTTP Header 中携带身份凭证(X-User-JWT 或加密的 User-ID)到达 Harness
  2. Session 绑定 — Harness 校验凭证后,读取或创建该用户的专属 Session
  3. 权限剪枝(SLM 阶段) — 小模型在工具剪枝时,以该用户的 RBAC 角色作为硬过滤条件。无权限的工具直接剔除,不会进入最终 Payload
  4. 动态 Token 注入 — LLM 决定调用工具后,Harness 拦截响应,临时向 KMS 调取该用户专属 Token,封装进工具请求的 Authorization Header

这样做的好处:大模型永远接触不到明文凭证,Token 的生命周期被限定在单次工具调用的 HTTP 请求中。


Q: 多用户之间的隔离具体怎么做?

三个维度的刚性隔离:

上下文隔离(Context Isolation)

Harness 从 Session 数据库拉取历史流水时,查询语句强制绑定当前 User_ID。确保大模型推理员工 A 的请求时,上下文中绝不混入员工 B 的交互历史。

计算沙箱隔离(Compute Isolation)

如果指令触发了代码执行(如在 Sandbox 中运行 Python 生成报表):

审计与阻断隔离(Audit & Policy Enforcement)

Harness 与 Tools/MCP 之间架设独立的审计拦截器:

最终效果:认知空间(LLM)共享,但执行空间(Harness + Sandbox)与数据空间(Session + KMS)绝对隔离。


Q: MCP 协议本身对工具层的身份校验是怎么定义的?

MCP 根据传输模式做了明确的分层处理:

STDIO 模式(本地进程)

当 MCP Server 作为本地子进程运行时,不采用网络认证协议。身份和凭证完全依赖启动进程时注入的环境变量,安全性由操作系统的用户权限和进程隔离保证。

HTTP + SSE 模式(远程服务)

MCP 将自身映射到 OAuth 2.1 框架中:

OAuth 2.1 角色架构组件映射职责
Resource Owner企业员工拥有数据访问决策权
ClientHarness 控制层代表员工发起工具调用
Resource ServerMCP Server / 工具层校验 Token、执行业务逻辑
Authorization Server企业 IAM / IDaaS统一验证身份、发放凭证

协议遵循**“网络传输层负责鉴权,协议消息层保持纯净”**的原则:JSON-RPC 消息本身不包含明文凭证,而由底层 HTTP Header(Bearer Token)或操作系统进程环境来承载。


Q: RFC 8707 资源指示器在这里起什么作用?

解决一个关键的安全威胁:令牌挪用(Token Substitution)

假设一个恶意或已被攻破的低权限 MCP Server 获取了员工的 Access Token,它可能拿着这个 Token 去请求另一个高权限 MCP Server(比如财务系统)。RFC 8707 资源指示器阻断了这种横向移动:

  1. 定向范围申请 — Harness 向认证中心请求 Token 时,必须携带 resource 参数指定目标 MCP Server 的规范化 URI(如 resource=https://api.wecom.internal/mcp/v1/crm
  2. 受限受众绑定 — 生成的 JWT Token 内部 aud(Audience)字段只指向该特定 MCP Server
  3. 工具端硬阻断 — MCP Server 收到 Token 后,即使签名合法且未过期,如果 aud 不匹配自身,必须拒绝执行

效果:每个 Token 被锁定在单一的工具服务器上,无法跨服务横向滥用。


Q: 当 LLM 要调用一个尚未授权的远程 MCP 工具时,完整的动态授权流程是什么样的?

这是一个 21 步的全链路流程,分为四个阶段:

阶段一:意图推理与凭据缺失发现(步骤 1-7)

  1. 员工发起业务指令(如”修改 CRM 中的客户状态”)
  2. Harness 组装 Payload 发起推理
  3. LLM 决定调用工具(Tool Call: crm_update
  4. Harness 根据 User_ID + Tool_ID 向 KMS 检索 Access Token
  5. KMS 返回为空(未授权或已过期)
  6. Harness 向 MCP Server 发起匿名探测调用
  7. MCP Server 返回 HTTP 401 Unauthorized,Header 携带 WWW-Authenticate 及受保护资源元数据(PRM)地址

阶段二:推理挂起与用户授权(步骤 8-11)

  1. Harness 挂起大模型推理循环,向前端推送 OAuth 授权卡片
  2. 员工点击卡片,跳转企业 IAM 完成登录和授权确认
  3. IAM 发放单次临时授权码(Authorization Code)
  4. 前端自动回传 Authorization Code 给 Harness

关键设计:Harness 不会将 401 错误直接丢给大模型,避免模型产生幻觉或反复重试。认知与执行解耦。

阶段三:限域令牌换取与解耦存储(步骤 12-14)

  1. Harness 携带 Code + resource 参数向 IAM 申请令牌(RFC 8707 限制)
  2. IAM 返回专属 Access Token(内部绑定特定 audscope
  3. Token 写入 KMS 高安全隔离区,建立 User_ID 与该工具的绑定关系

即便该员工在企业 IAM 中拥有全系统管理员权限,发放的 Token 也仅在 CRM 资源范围内生效。

阶段四:流程恢复与物理动作执行(步骤 15-21)

  1. Harness 携带 Bearer Access Token 重新发起工具调用
  2. MCP Server 校验 Token 签名、有效期及 aud 匹配,执行业务逻辑
  3. 返回工具执行结果 JSON
  4. Harness 将结果作为追加流水写入 Session 数据库
  5. 工具结果送回大模型,恢复下一轮推理
  6. LLM 生成最终文本回复
  7. Harness 向前端输出最终话术

后续调用优化:只要 Token 未过期,系统在步骤 4 就会命中 KMS 缓存,直接跳转至步骤 15 执行,实现无感的秒级工具调用。


Q: 受保护资源元数据(PRM)具体长什么样?

每个远程 MCP Server 必须通过标准路径(.well-known/oauth-protected-resource)或认证挑战中暴露 PRM JSON 描述:

{
  "resource": "https://api.wecom.internal/mcp/v1/crm",
  "authorization_servers": [
    "https://iam.wecom.work/oauth/v2"
  ],
  "scopes_supported": ["crm.read", "crm.write"],
  "bearer_methods_supported": ["header"],
  "auth_flows_supported": ["authorization_code", "token_exchange"]
}

这个文档告诉 Harness:要调用这个工具,你需要去哪个认证中心、申请什么范围的权限、用什么授权流程。整个过程是自动发现的,不需要硬编码配置。


参考资料


Share this post on:

Previous Post
智能体记忆系统解剖:当下 Agent '记忆库'与认知科学的差距
Next Post
Managed Agents 架构拆解:Harness、动态工具路由与 Prompt Cache 的工程博弈