Skip to content

A2A(Agent2Agent Protocol)协议机制与安全边界 ​

摘要 ​

A2A 用 Agent Card、任务、消息、Artifact 和流式事件连接独立 Agent。安全边界不只在 HTTP 鉴权,还包括 Agent Card 来源、任务身份绑定、异步状态一致性、扩展协商和跨组织授权传播。实现审查应把协议规范、部署身份和上层编排分别验证。

调研日期:2026-07-29 证据来源:主要为一手来源,直接抓取 github.com/a2aproject/A2A(docs/specification.md、specification/a2a.proto、CHANGELOG.md、docs/whats-new-v1.md、docs/announcing-1.0.md,取自 main 分支,对应已发布 tag v1.0.1),而非二手博客总结。仅治理权移交 Linux Foundation 的具体日期/创始成员名单来自二手信源(Forbes、LF 新闻稿、Google Cloud 博客),已在下文标注。

版本提醒:A2A 在 2026-03-12 发布了破坏性的 v1.0(2026-05-26 发布 v1.0.1),把 JSON-RPC 方法命名和枚举大小写规则都改了。大量教程和旧 SDK 描述的是 v1.0 之前(v0.3.0 及更早)的 message/send、tasks/get 和小写任务状态。这些写法已经废弃,新实现不能继续沿用。

协议定位与核心差异 ​

Spec 附录 B("Relationship to MCP")原文如下:

MCP... Focuses on standardizing how AI models and agents connect to and interact with tools, APIs, data sources, and other external resources... Think of MCP as the "how-to" for an agent to use a specific capability.

A2A... Focuses on standardizing how independent, often opaque, AI agents communicate and collaborate with each other as peers... It's about how agents partner or delegate work.

v1.0 发布公告重申:

MCP is commonly used for tool and context integration at the individual agent level. A2A focuses on communication and coordination between agents... many systems will use both: MCP inside agents, A2A between agents.

一句话总结:MCP 管 agent 怎么用工具/取数据,A2A 管 agent 之间怎么互相通信/委派任务,两者定位互补,不是竞争关系,实际系统里常常同时用(agent 内部用 MCP 接工具,agent 之间用 A2A 通信)。

架构和消息流程 ​

Agent Card 发现机制 ​

服务在 well-known URI 上(RFC 8615 风格):https://{domain}/.well-known/agent-card.json。Spec §8.2 列了三种发现策略:well-known URI、策展型注册表(curated registries)、直接/静态配置。

AgentCard 关键字段(§4.4.1,示例见 §8.5):name、description、provider(AgentProvider)、iconUrl、version、documentationUrl、capabilities(streaming、pushNotifications、extendedAgentCard)、securitySchemes、securityRequirements、defaultInputModes/defaultOutputModes、skills[](AgentSkill:id/name/description/tags/examples/inputModes/outputModes)、supportedInterfaces[](AgentInterface:url + protocolBinding + protocolVersion——这个字段取代了旧版单一的 preferredTransport/additionalInterfaces),以及 v1.0 新增的可选 signatures[](对 Agent Card 做加密签名,JWS + RFC 8785 规范化)。

json
{
  "name": "GeoSpatial Route Planner Agent",
  "description": "Provides route planning, traffic analysis, custom maps.",
  "supportedInterfaces": [
    {"url": "https://georoute-agent.example.com/a2a/v1", "protocolBinding": "JSONRPC", "protocolVersion": "1.0"},
    {"url": "https://georoute-agent.example.com/a2a/grpc", "protocolBinding": "GRPC", "protocolVersion": "1.0"}
  ],
  "provider": {"organization": "Example Geo Services Inc.", "url": "https://www.examplegeoservices.com"},
  "version": "1.2.0",
  "capabilities": {"streaming": true, "pushNotifications": true, "extendedAgentCard": true},
  "securitySchemes": {"google": {"openIdConnectSecurityScheme": {"openIdConnectUrl": "https://accounts.google.com/.well-known/openid-configuration"}}},
  "securityRequirements": [{"schemes": {"google": {"list": ["openid", "profile", "email"]}}}],
  "skills": [{"id": "route-optimizer-traffic", "name": "Traffic-Aware Route Optimizer",
    "tags": ["maps","routing"], "inputModes": ["application/json"], "outputModes": ["application/json"]}]
}

(节选自官方 §8.5 示例卡片)

传输与消息层 ​

确认为 JSON-RPC 2.0 over HTTP(S)(§9.1),同时还有一手支持的 gRPC 绑定(§10)和 HTTP+JSON/REST 绑定(§11)——三者都映射到 §3 里定义的、传输无关的同一套底层操作。v1.0 的方法命名改成了匹配 gRPC 约定的 PascalCase(§9.1 原文:"Method Naming: PascalCase method names matching gRPC conventions"),是相对 v1.0 之前 slash 风格命名的一次不兼容变更。

核心 JSON-RPC 方法(§9.4,已对照 a2a.proto 里的 A2AService 确认):SendMessage、SendStreamingMessage、GetTask、ListTasks、CancelTask、SubscribeToTask、CreateTaskPushNotificationConfig、GetTaskPushNotificationConfig、ListTaskPushNotificationConfigs、DeleteTaskPushNotificationConfig、GetExtendedAgentCard。

v1.0 之前的旧命名(仍会在旧文档/SDK 里看到,按 docs/whats-new-v1.md 的迁移表对照):message/send→SendMessage,tasks/get→GetTask,tasks/cancel→CancelTask,agent/getAuthenticatedExtendedCard→GetExtendedAgentCard,等等。

REST 绑定用动词风格路径:POST /message:send、POST /message:stream、GET /tasks/{id}、GET /tasks、POST /tasks/{id}:cancel、GET/POST/DELETE /tasks/{id}/pushNotificationConfigs[/{configId}]、GET /extendedAgentCard(v1.0 里去掉了 /v1 这个 URL 前缀)。SubscribeToTask 在 v1.0.1 发布物中有未解决的不一致:docs/specification.md 的操作映射和 §11.3.2 写 POST /tasks/{id}:subscribe,同一 tag 的 a2a.proto HTTP annotation 却写 GET。实现不能把其中一个说成无争议的唯一映射;生成式 client/server 往往跟随 proto,手写 REST 实现需确认对端,并关注上游勘误。

JSON-RPC binding 的 request/response Content-Type 是 application/json;HTTP+JSON/REST binding 应使用 application/a2a+json;SSE 都使用 text/event-stream。v1.0 client 每次请求都必须声明 A2A-Version: 1.0(patch 版本不参与协商),扩展通过 A2A-Extensions 协商。这里的规范文本存在一处张力:通用版本章节 §3.6.1 允许 client 用 request parameter 代替 header,但 JSON-RPC/REST binding 的 §§9.2/11.2 又要求 service parameter 通过 HTTP header 传输;为保证互操作性,HTTP client 应始终发送 A2A-Version header。JSON-RPC、REST、gRPC 是等价 binding,但 wire format 并不相同:gRPC 流式使用 server-streaming RPC,不是 SSE。

任务生命周期 ​

Task 对象:id、contextId、status(TaskStatus = 状态 + 可选 message/时间戳)、artifacts[]、history[]、metadata,并新增 createdAt、lastModified。ListTasks 支持 contextId、status、更新时间等过滤与 pageToken/nextPageToken 游标分页;无论是否显式传过滤条件,server 都必须按调用者授权边界限制结果。

TaskState 枚举(已对照 a2a.proto 确认,SCREAMING_SNAKE_CASE 加 TASK_STATE_ 前缀——相对 v1.0 之前小写的 "submitted"/"working",这是一次为了符合 ProtoJSON 规范而做的变更,见 ADR-001):

TASK_STATE_UNSPECIFIED、TASK_STATE_SUBMITTED、TASK_STATE_WORKING、TASK_STATE_COMPLETED、TASK_STATE_FAILED、TASK_STATE_CANCELED、TASK_STATE_INPUT_REQUIRED、TASK_STATE_REJECTED、TASK_STATE_AUTH_REQUIRED。

其中 COMPLETED/FAILED/CANCELED/REJECTED 实质是终态;INPUT_REQUIRED/AUTH_REQUIRED 是被打断、等待 client 补充输入的中间态。长时间运行的任务可以靠 GetTask/ListTasks 轮询,也可以用下面的流式/推送方式消费。

流式与异步 ​

在 JSON-RPC/REST over HTTP binding 中,SendStreamingMessage 和 SubscribeToTask 返回 SSE 流(text/event-stream);gRPC binding 使用 server streaming。事件统一映射为 StreamResponse,可包含初始 Task/Message、TaskStatusUpdateEvent 或 TaskArtifactUpdateEvent。task lifecycle stream 必须先返回当前 Task,并在终态关闭;message-only stream 恰好返回一个 Message 后关闭。这个能力受 AgentCard.capabilities.streaming 开关控制。如果任务已经是终态,SubscribeToTask 会报 UnsupportedOperationError。

SSE 断线重连没有类似 Last-Event-ID 的可靠补发保证;spec 明确提醒重连后可能漏掉 status message,关键结果应从 Task/artifacts 重新读取,不能只依赖瞬时 stream message。

对于断线/长时间运行的场景,推送通知(webhook)通过 TaskPushNotificationConfig 系列方法配置,受 capabilities.pushNotifications 开关控制。§13.2 强制要求:webhook 调用方必须对自己的回调做鉴权、用超时(建议 10–30s)加退避重试、并对目标 URL 做 SSRF 校验(拒绝内网/回环地址段);接收方必须校验鉴权信息和 task ID,并以幂等方式响应 2xx。

身份认证与授权 ​

按 scheme 声明在 AgentCard.securitySchemes 里(§4.5):APIKeySecurityScheme、HTTPAuthSecurityScheme、OAuth2SecurityScheme、OpenIdConnectSecurityScheme、MutualTlsSecurityScheme。v1.0 里的 OAuth2 flow 只保留 AuthorizationCodeOAuthFlow、ClientCredentialsOAuthFlow、DeviceCodeOAuthFlow;implicit 和 password(ROPC)flow 被移除,authorization code flow 可声明 PKCE。Agent Card 只描述“如何取得凭证”,不替应用执行认证授权;server 仍必须在每个 operation 上校验身份、tenant、task/context 所有权和 scope。

安全风险 ​

  • Agent Card 伪造或中间人攻击:签名校验目前是可选要求,在强制校验落地前存在 Agent 冒充风险。
  • ListTasks 或 GetTask 授权范围错误,可能泄露跨租户任务数据。
  • 推送通知地址校验不足会引入服务器端请求伪造(Server-Side Request Forgery, SSRF)风险。
  • Extended Agent Card 访问控制绕过可能向未认证调用方暴露受限技能或端点。
  • 委派链会放大跨 Agent 信任,下游异常行为对上游委派方可能不可见。
  • 任务 ID 猜测、上下文混用、租户路径或 scope 校验错误都可能造成任务劫持或数据泄露。
  • AgentSkill 中的误导性描述可能影响由大模型驱动的规划器,形成工具或技能投毒。
  • 多版本接口声明可能被用于降级攻击,使客户端退回安全约束更弱的旧版行为。

实现与验证建议 ​

  • HTTP 客户端应始终发送 A2A-Version,并对 supportedInterfaces 的 binding、版本和服务端实际响应做一致性检查。
  • Agent Card 应通过受信来源获取并验证签名;不要仅凭卡片中的 URL、技能说明或安全方案授予权限。
  • 每个操作都要重新校验身份、租户、task/context 所有权和 scope,不能把通过 HTTP 鉴权等同于拥有任务访问权。
  • SSE 断线后以 Task 和 Artifact 的持久状态恢复,不依赖瞬时流消息完整到达。
  • webhook 必须限制目标网段、验证接收方身份、采用幂等处理,并测试重试是否产生重复副作用。
  • 互操作测试需覆盖 JSON-RPC、REST 和 gRPC 的等价语义,以及 v0.3 到 v1.0 的降级和迁移失败。

结论适用范围 ​

治理与版本历史 ​

  • Google 在大约 2025 年 4 月公开发布 A2A。
  • Google Cloud 在 2025-06-23 于 Open Source Summit North America 上把协议治理权移交给 Linux Foundation,成立了包含 AWS、Cisco、Google、IBM Research、Microsoft、Salesforce、SAP、ServiceNow 的技术指导委员会(TSC)。[secondary:这个具体日期和创始成员名单来自 Forbes/LF 新闻稿/Google Cloud 博客交叉印证,官方 spec 仓库本身没有找到带日期的移交公告原文,仅有 TSC 相关描述]
  • 仓库内版本历史:0.1.0 → 0.2.6 → 0.3.0 → 1.0.0(2026-03-12 发布,第一个稳定/破坏性版本) → 1.0.1(2026-05-26,bugfix:HTTP media type 和错误码修正)。截至 2026-07-29,最新已发布版本是 1.0.1。

本文以 A2A v1.0.1 规范和同 tag 的 a2a.proto 为协议基线。规范与 proto 对 SubscribeToTask 的 REST 方法仍存在不一致,实现者需要跟踪上游勘误。Linux Foundation 治理移交日期和创始成员名单来自交叉核对的二手来源,不作为协议字段的证据。

关联研究 ​

  • 与 MCP 的定位区分见 mcp-protocol.md。两者都可在 HTTP 响应中使用 SSE,但都不能简化为“协议基于 SSE”:A2A 还有 gRPC/REST binding,MCP 的普通调用也可直接返回 JSON。可与 vendor-streaming-comparison.md 对照事件与断线语义。
  • 安全风险应与 agent-security 下的多 Agent 信任和工具调用研究交叉分析,不在协议机制文章中推导具体产品漏洞。

参考链接 ​