---
type: study
created: 2026-08-11
updated: 2026-08-11
sensitivity: standard
status: verified
tags: [langchain, langsmith, authentication, authorization, mcp, a2a]
topic: Agent Server 认证授权、资源隔离与协议端点
sources:
  - "https://docs.langchain.com/langsmith/add-auth-server"
  - "https://docs.langchain.com/langsmith/agent-auth"
  - "https://docs.langchain.com/langsmith/auth"
  - "https://docs.langchain.com/langsmith/custom-auth"
  - "https://docs.langchain.com/langsmith/openapi-security"
  - "https://docs.langchain.com/langsmith/resource-auth"
  - "https://docs.langchain.com/langsmith/server-a2a"
  - "https://docs.langchain.com/langsmith/server-mcp"
  - "https://docs.langchain.com/langsmith/set-up-custom-auth"
  - "https://docs.langchain.com/langsmith/store-auth"
last_verified: 2026-08-11
---

# Agent 认证授权与 A2A/MCP 协议

## AuthN 与 AuthZ 必须分离

- `@auth.authenticate` 是认证中间件：校验请求并返回至少包含稳定 `identity` 的用户对象。
- `@auth.on` 是授权：按资源与动作创建元数据、增加查询过滤或拒绝操作。
- 更具体的处理器优先，例如 `threads.create` 覆盖 `threads`，后者又覆盖全局 handler。策略评审必须按实际匹配顺序，而不是只看全局规则。

Cloud 默认用 `x-api-key` 验证 LangSmith 身份；自托管 Agent Server 默认可能没有认证，只应位于受保护网络。自定义 Auth 支持 Cloud 与 Self-hosted Deployment，但不自动存在于纯 LangGraph OSS 自建服务器。

## 单租户资源隔离模式

一个可靠的“用户只能看自己的 Thread”策略同时做两件事：

1. 创建时把 `owner_id=identity` 写入 resource metadata。
2. 读取、搜索、更新、删除时返回同一 metadata filter。

只在 UI 隐藏资源不是授权。搜索/list 也必须过滤，且需要覆盖 Thread、Assistant、Cron、Run creation 等关联动作。授权测试至少包含：无 token、伪造 token、用户 A 访问用户 B、搜索泄漏、通过 Run 间接操作他人 Thread。

Store 与 Thread 不同：Store namespace 由应用定义，handler 接收可变 `value`。可选择：

- 显式要求 namespace 第一段等于用户 identity，否则 deny；
- 在服务端自动把 identity 前缀写入 namespace。

第二种更不易被 Agent 忘记，但调试时看到的是重写后的物理 namespace。无论哪种，都应与 Thread owner filter 组合，形成跨 Thread 长期记忆和会话状态的双重隔离。

## 真实 OAuth 身份接入

教程从硬编码 token 逐步升级为 Supabase/OAuth2 JWT；Supabase 只是示例，核心流程适用于 OIDC/OAuth provider：客户端登录拿 token → Agent Server 校验签名/issuer/audience/expiry → 生成稳定 identity → AuthZ 过滤资源。

Agent Auth 用于 Agent 代表用户访问外部系统。先在控制面登记 provider 与 callback，再由 Agent 发起 OAuth。凭据应保存在专用凭据服务/密钥存储，不能放入 Graph state、Prompt、Trace 或普通 Store。Self-hosted API URL 使用 `/api-host`，callback 的公网 origin/base path 必须与 IdP 登记值一致。

## OpenAPI 不是安全实现

`langgraph.json` 的 `auth.openapi` 只修改 `/docs` 中的 security schema，便于调用者和代码生成器理解 header/scheme；它不会校验任何请求。实际 handler、网关策略和端到端负向测试缺一不可。Self-hosted 如果保持默认“无 scheme”，必须在 Ingress/API Gateway 层提供等价保护。

## MCP 端点

Agent Server 通过 `/mcp` 使用 Streamable HTTP，把 Assistant 暴露为 MCP Tool。最低文档版本为 `langgraph-api>=0.2.3`、`langgraph-sdk>=0.1.61`。

- Tool name/description/schema 是对外契约，输入/输出 schema 应稳定、最小化，避免把内部完整 State 暴露给任意 MCP Client。
- MCP session 与用户身份需要显式关联；启用自定义 auth 才能提供用户范围工具。
- MCP Client 仍是外部调用方：必须执行认证、速率限制、审计、Tool allowlist 和输出脱敏。
- 不需要时可禁用 MCP，以减少攻击面。

## A2A 端点

`/a2a/{assistant_id}` 实现 Google A2A，最低文档版本为 `langgraph-api>=0.4.21`，支持 `message/send`、`message/stream` 与 `tasks/get`，并自动提供 Agent Card。

A2A `contextId` 映射到 `thread_id`，因此外部 Agent 提供的 context 不能直接当作已授权 Thread。跨 Agent 分布式追踪要传播 trace context，但不要传播原始用户 token。Agent Card 的 skills、输入输出模式和 URL 属于公开能力描述，不应包含内部地址或敏感配置。

## 生产安全清单

1. 明确 API Key、终端用户 JWT、Agent OAuth token 三种身份，禁止混为一个凭据。
2. 验证 JWT 的签名、算法白名单、issuer、audience、expiry，并缓存 JWKS 时处理轮换。
3. Auth handler 返回稳定且不可由客户端自报的 identity；角色/组织信息来自可信 claim 或后端查询。
4. 对所有资源的 create/read/search/update/delete/create_run 建立矩阵测试。
5. 对 Store namespace、Thread metadata、MCP session、A2A context 分别验证跨用户越权。
6. 不把 token 写入 State、Checkpoint、Store、Trace、异常或日志；下游凭据临用临取。
7. OpenAPI、Studio 能登录、正常请求成功都不能替代负向授权测试。

