认证、授权与安全考量
A2A 把智能体当作标准的企业应用,依赖成熟的 Web 安全实践:身份信息在协议层(HTTP 头或 gRPC metadata)处理,而不属于 A2A 消息语义。内容对应官方规范第 7 章与第 13 章;企业视角的概览见A2A 企业级特性 。文中的 MUST / SHOULD / MAY 沿用 RFC 2119 的含义(必须 / 应当 / 可以)。
传输安全与服务器身份
- 生产环境必须使用加密通信:基于 HTTP 的绑定使用 HTTPS,gRPC 使用 TLS;
- 实现应当使用现代 TLS 配置(推荐 TLS 1.3 及以上)和强加密套件,基于 HTTP 的绑定应当启用 HSTS,并应当禁用 SSLv3、TLS 1.0 与 TLS 1.1;
- 客户端应当在 TLS 握手期间,用受信任的证书颁发机构(CA)校验服务端证书,以验证服务器身份。
认证
客户端分三步完成认证:
- 发现要求:从 Agent Card 的
securitySchemes读取服务端要求的认证方案(方案类型见数据结构 ); - 带外获取凭据:通过与方案相关的流程(例如 OAuth 2.0 流程)取得凭据;
- 传输凭据:在每一个 A2A 请求中,通过协议对应的请求头或 metadata 携带凭据。
服务端:
- 必须根据请求提供的凭据及其声明的认证要求,对每个收到的请求进行认证;
- 应当用对应绑定的错误码表示认证挑战或拒绝,并应当在错误响应中给出相关的挑战信息。
授权
认证通过后,服务端根据调用方身份和自身策略对请求授权。协议不规定授权模型,逻辑由实现自行决定,可以综合考虑所请求的技能、任务内尝试的操作、数据访问策略和 OAuth scope。
无论采用哪种模型(基于用户、角色、项目、多租户或自定义),下列要求都适用:
- 服务端必须对每个请求执行授权检查;
- 即使请求没有指定
contextId或其他过滤条件,返回结果也必须限定在调用方被授权的访问边界内; - 授权检查必须发生在任何可能泄露“调用方范围之外资源是否存在”的数据库查询或操作之前;
- 智能体应当公开说明自己的授权模型和访问控制策略。
| 操作 | 要求 |
|---|---|
ListTasks | 必须只返回已认证客户端可见的任务 |
GetTask | 必须校验客户端是否有权访问所请求的任务 |
CancelTask、SubscribeToTask、推送通知配置相关操作 | 必须校验客户端具有相应的访问权限 |
任务内授权
执行任务的过程中,智能体可能需要得到某项操作的授权,例如调用 API 或其他智能体所需的 OAuth 访问令牌,或者在执行破坏性操作之前需要人工批准。这里把代表“已批准授权”的对象称为凭据。当智能体无法自行获取(例如直接向人发消息)时,A2A 允许它通过 TASK_STATE_AUTH_REQUIRED 任务状态,把这项授权的完成交给客户端,作为兜底路径。
智能体的职责
要请求客户端完成授权,智能体:
- 必须用一个
Task来跟踪所执行的操作; - 必须把任务状态转换为
TASK_STATE_AUTH_REQUIRED; - 必须在
TaskStatus的消息中说明所需的授权,除非授权细节已通过带外方式或扩展协商。
智能体必须安排通过带外方式接收凭据,除非已通过带外方式或扩展协商了带内机制。若凭据通过带外方式到达,智能体在进入 TASK_STATE_AUTH_REQUIRED 后应当保持现有的响应流不断开,并且可以在收到凭据后立即继续处理,无需客户端再发送后续消息。任务停留在 TASK_STATE_AUTH_REQUIRED 期间,智能体应当支持接收发给该任务的消息,使客户端可以协商、更正或拒绝这项授权请求。
客户端的职责
收到处于 TASK_STATE_AUTH_REQUIRED 的任务后,客户端需要采取行动处理这项请求。它可以:
- 向该任务发送消息,协商、更正或拒绝授权请求;
- 联系其他的人、智能体或服务来完成授权;
- 通过带外方式或扩展协商的方式直接完成授权。
如果客户端本身就是正在处理任务的 A2A 智能体,它可以把授权请求继续向上委托:把自己的任务转为 TASK_STATE_AUTH_REQUIRED(并遵循上面的智能体职责),这样就形成一条处于该状态的任务链。
由于客户端可能不知道智能体何时通过带外方式收到凭据并恢复处理,没有活动响应流的客户端有错过任务更新的风险。为避免这一点,客户端应当采取下列做法之一:
- 用
SubscribeToTask订阅该任务的事件流; - 若智能体支持,用
CreateTaskPushNotificationConfig注册 webhook; - 用
GetTask轮询该任务。
安全考量
- 智能体应当通过 HTTPS 等安全通道以带外方式接收凭据,确保凭据直接交给智能体;
- 如果通过带外方式或扩展协商了带内交换,凭据可能沿 A2A 智能体链传递,暴露给链上的每个智能体。此时:
- 凭据应当绑定到发起请求的智能体,只有它能使用;
- 含敏感信息的凭据应当只有发起请求的智能体能读取,例如对凭据加密。
授权的范围
TASK_STATE_AUTH_REQUIRED 只表示“继续处理还需要更多授权”。协议没有定义为响应该状态而得到的授权决定或凭据的范围、表示形式、有效期与撤销语义。
- 智能体不得把进入
TASK_STATE_AUTH_REQUIRED这一状态转换本身当作对任何特定操作的授权; - 所得授权决定或凭据的含义与范围,必须由智能体的实现、凭据签发方或 A2A 扩展来定义。要求对特定操作授权的实现,须自行定义如何标识被授权的操作,以及在执行前如何检查授权;
- 任务处于
TASK_STATE_AUTH_REQUIRED期间得到的凭据或授权决定,不得被假定为可授权该任务上的后续消息,除非实现、签发方或扩展明确定义了这种行为。
推送通知安全
智能体(webhook 调用方)与客户端(webhook 接收方)都有各自的责任。推送通知的工作方式见流式传输与异步操作 。
智能体(webhook 调用方)
- 必须在 webhook 请求中带上
TaskPushNotificationConfig.authentication指定的凭据; - 应当设置合理的请求超时(推荐 10–30 秒),并对失败的投递按指数退避重试;可以在连续失败达到配置的次数后停止投递;
- 应当校验 webhook URL 以防范 SSRF(服务端请求伪造):拒绝私有 IP 段(
127.0.0.0/8、10.0.0.0/8、172.16.0.0/12、192.168.0.0/16)、localhost 与链路本地地址,并在适当时使用 URL 允许列表。
客户端(webhook 接收方)
- 必须用所提供的凭据校验每条通知的真实性,并必须以 HTTP 2xx 状态码确认已收到;
- 应当核对载荷中的任务 ID 是否为自己创建的任务、幂等地处理通知(可能出现重复投递)、对收到的通知限流,并使用 HTTPS 的 webhook URL。
配置
TaskPushNotificationConfig中的令牌应当视为机密并定期轮换;客户端应当为每份配置使用唯一、单一用途的令牌;- 智能体应当安全地存储推送通知配置与凭据。
扩展 Agent Card 的访问控制
扩展 Agent Card 向已认证客户端提供比公开卡片更多的信息(见智能体发现与 Agent Card )。
GetExtendedAgentCard必须要求认证,并使用公开卡片securitySchemes与security中声明的方案之一;- 智能体可以依据调用方的身份或授权级别返回不同的扩展卡片内容(额外的技能、限流与配额等更细的能力信息、组织或用户专属配置),并应当说明各认证级别能看到什么;
- 返回特权信息之前,智能体必须校验权限;扩展卡片不应包含一旦泄露就有风险的信息,如内部服务 URL、未脱敏的凭据;
- 智能体应当为扩展卡片做好版本管理、响应客户端的缓存失效,并通过缓存头控制客户端缓存;客户端应当在已认证会话期间用扩展卡片替换缓存的公开卡片;
capabilities.extendedAgentCard为false或缺失时,该操作必须返回UnsupportedOperationError;声明支持但未配置扩展卡片时,必须返回ExtendedAgentCardNotConfiguredError。
通用最佳实践
| 方面 | 建议 |
|---|---|
| 输入校验 | 必须校验所有输入参数;应当限制消息大小、文件大小与请求复杂度;应当校验文件内容类型并拒绝意外的媒体类型 |
| 凭据管理 | API 密钥、令牌等必须视为机密;应当定期轮换、仅通过加密连接传输,并支持吊销;应当记录认证失败并限流,以抵御暴力破解 |
| 审计与监控 | 应当记录与安全相关的事件(认证失败、授权拒绝、可疑请求),监控异常模式(如任务被快速大量创建、取消过多),并为敏感操作保留审计轨迹;日志不得包含敏感信息,除非确有必要且已妥善保护 |
| 限流 | 应当对所有操作限流,超限时返回恰当的错误;可以按操作或用户等级设置不同限额 |
| 数据隐私 | 必须遵守适用的数据保护法规;应当支持用户的数据删除请求与数据保留策略,并尽量减少对敏感或个人信息的日志记录 |
| 自定义绑定 | 必须说明其安全考量,并写明认证集成与凭据传输方式;应当遵循与标准绑定相同的原则(见自定义协议绑定 ) |
相关页面
来源:A2A 官方规范