基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
AIHT
内容
精选全部 AI 动态热点榜AI 日报收藏
分类
模型行业编程产品技术观点开源
更多
Agent 接入
返回首页开发者导航
AIHT
精选 / 资讯详情
8.0
热点
AI SCORE
技术实践2026-10-30 05:54

A2A 权限设计:发现、身份与授权分开判断

dev.to · AI#Agent#权限控制#安全
Editor brief · 编辑速览

文章用虚构货运集成的 Python 策略示例,将 Agent 发现信息、认证身份和业务授权分别处理,避免用单一可信标记放行操作。示例仅允许报价,不允许订舱,且明确未实现传输、卡片签名验证或 SPIFFE 证明。

文章思维导图
Knowledge map
拖拽缩放
AI deep read

AI 深度解读

Agent 能发现一个服务、通过身份认证,也不代表它有权调用这个服务的所有能力。原文用一个虚构的货运询价场景,拆开了 A2A 服务发现、调用方身份和业务授权三个判断,反对把它们压成一个 trusted_agent 开关。

它的价值在于把权限边界讲得具体:采购 Agent 可以询价,却不能顺手订舱;身份是真的,越权请求也必须被拦住。不过,这只是认证之后的一小段 Python 策略示例,没有实现或验证完整的 A2A、SPIFFE 部署。

Agent Card 写了什么,不等于调用方能做什么

Agent Card 是服务的能力说明。A2A 支持通过约定位置、注册中心或直接配置发现它,但发现结果不能直接变成受信任配置。对于受控的合作方接入,应先明确认可哪家提供方、哪个端点,再读取对应元数据。

这里有三个独立问题:

  • 服务发现回答「这里提供什么能力」。
  • 身份认证回答「对面是谁」。
  • 业务授权回答「这个身份能对哪个客户、哪票货执行什么操作」。

服务发现、对端认证与业务授权需要分别判断

Agent Card 即使签名有效,也不能自动授予业务权限。还要先确认签名密钥与认可的服务提供方之间存在可信关系。攻击者用自己的密钥签一份能力说明,解决不了合作方接入审核的问题。

原文还提醒核对协议版本:它所引用的当前规范使用 v1.0 结构。旧示例的字段形状可能不同,复制前要核对规范和 SDK。示例刻意没有放入线上传输格式的 Agent Card,避免读者把业务策略误认成协议结构。

身份层也有选择。SPIFFE ID 标识信任域中的工作负载,SVID 用于以可验证方式呈现身份;SPIRE 根据配置的节点和工作负载条件签发身份。但一个名称本身不能证明法律主体,也不能证明访问发票的权限。

例如,spiffe://freight.example/agents/quote-service 可以表示远端货运服务,spiffe://cedar.example/agents/purchasing 可以表示采购调用方。两者都是虚构名称。接收端必须从可信认证层取得身份,不能从请求 JSON、工具参数或模型解释里复制。

双方分别认证对端身份,货运服务另外检查询价权限

SPIFFE federation 的信任包负责支持跨已配置域的身份识别,业务系统仍要决定允许哪个工作负载进入哪个租户。A2A 也不要求使用 SPIFFE;已有 OAuth 集成可以保留,只需把已验证身份明确映射到合作方和业务权限。

询价权限怎样才能挡住订舱请求

示例运行在货运服务端:允许 Cedar 的采购 Agent 为客户 cedar 的货物 C-731 询价,只允许 quote,不允许 book。

模型认为下一步有用,不能成为扩大权限的理由。

下面的代码检查身份、授权记录、操作、客户和货物是否同时匹配:

from dataclasses import dataclass

QUOTE_PEER = "spiffe://cedar.example/agents/purchasing"

@dataclass(frozen=True)
class Peer:
    identity: str

@dataclass(frozen=True)
class Mandate:
    customer: str
    consignment: str
    operation: str
    valid: bool

def allow_quote(peer, mandate, customer, consignment, operation):
    if peer.identity != QUOTE_PEER:
        return False, "peer_not_allowed"
    if mandate.valid is not True:
        return False, "mandate_invalid"
    if operation != "quote" or mandate.operation != "quote":
        return False, "operation_not_allowed"
    if customer != mandate.customer:
        return False, "customer_mismatch"
    if consignment != mandate.consignment:
        return False, "consignment_mismatch"
    return True, "allowed"

要盯住 mandate.valid is not True:它要求值严格为布尔值 True,字符串也不能混过去。但这个判断只是示例的有效性入口,不能代替真实授权的有效期检查。

代码成立还依赖一组外部前提。Peer 必须由认证结果构造,Mandate 必须从服务端掌控的授权存储解析,公共接口不能让客户端填写 valid。customer 应来自已认证的合作方关系和可信路由上下文;请求里的货物编号则要先查存储,确认归属。

原文明确说,这段函数不能验证 TLS 证书、执行真实授权到期检查,也不能确定货物所有者。那些检查应在可信输入形成过程中完成。

还有一个没有通用答案的问题:Agent 是以服务自身身份操作,还是代表另一个主体操作?两种关系需要的授权证据不同,不能因为接上 A2A 和 SPIFFE,就假设已经拥有统一的委托格式。

权限测试要用真身份,也要追到任务结束

只测试陌生攻击者被拒绝,覆盖不了业务边界。更有价值的反例是:合作方身份完全合法,但它请求了错误操作或别人的资源。

原文用以下断言展示预期结果:

from dataclasses import replace

peer = Peer(QUOTE_PEER)
mandate = Mandate("cedar", "C-731", "quote", True)

assert allow_quote(
    peer, mandate, "cedar", "C-731", "quote",
) == (True, "allowed")
assert allow_quote(
    peer, mandate, "cedar", "C-731", "book",
) == (False, "operation_not_allowed")
assert allow_quote(
    Peer("spiffe://cedar.example/agents/other-service"),
    mandate, "cedar", "C-731", "quote",
) == (False, "peer_not_allowed")
assert allow_quote(
    peer, mandate, "another-customer", "C-731", "quote",
) == (False, "customer_mismatch")
assert allow_quote(
    peer, replace(mandate, valid=False), "cedar", "C-731", "quote",
) == (False, "mandate_invalid")
assert allow_quote(
    peer, mandate, "cedar", "C-999", "quote",
) == (False, "consignment_mismatch")
assert allow_quote(
    peer, replace(mandate, valid="false"), "cedar", "C-731", "quote",
) == (False, "mandate_invalid")

最后一个断言尤其关键:valid="false" 是非空字符串,若只检查真假值就可能放行。其他断言分别覆盖订舱、错误工作负载、跨客户、无效授权和错误货物。

这些是合成断言,原文没有提供生产认证或 federation 部署的安全验证结果。集成测试还应覆盖:没有可信信任包的外部凭证、非预期端点,以及请求自报身份与认证身份不一致的情况。

拒绝操作的验收标准是没有产生受保护的外部效果。

接口返回拒绝,但后台仍创建了订舱记录,权限检查就没有守住边界。同时要保留一个应当成功的授权请求,避免把连接故障误判为拦截有效。审计应记录拒绝原因、已验证身份引用及对应外部效果,不能存储秘密凭证。

权限检查也不能止于首次请求。A2A 任务可能持续存在,查询、取消、结果交付和回调都需要检查访问权。任务 ID 应帮助定位授权关系内的记录,不能成为拿到就能通行的凭据。

原文建议将任务绑定到客户和许可操作,并测试跨客户查结果、不拥有任务的 Agent 发起取消。这些只是追加测试建议,短代码没有实现它们。A2A 的 authorisation-required 状态也只是协调补充授权的机制,状态变化本身不会补齐业务许可。

我的判断

我认同它把身份和权限分开处理。对接 Agent 工具时,很容易把「合作方可信」扩大解释为「合作方发来的动作都可信」。示例把权限收窄到具体身份、客户、资源和操作,让这个漏洞变得可检查。

但它更适合用作边界检查样板。固定一个 QUOTE_PEER、一个 valid 标记,表达不了完整的授权生命周期;授权记录如何签发、撤销、过期,真实货物归属怎样解析,原文都没有给出实现。

相比引入 SPIFFE,较小规模的 OAuth 合作方集成可能更容易维护正确。原文提出了这个运维取舍,却没有给出成本或安全性的对照数据,应当把它当作设计经验。已有身份体系能提供可靠认证结果时,优先补齐业务授权映射,通常比为了匹配示例更换身份机制更切题。

能拿来做什么

  • 检查 Node 服务或 Agent 工具接口里的身份来源,确保调用方身份由认证层提供,客户归属和授权记录由服务端解析,不能接受模型参数直接指定。
  • 为已有权限测试补上合法身份的越权用例,至少覆盖错误操作、其他客户和其他资源,并验证数据库或外部服务没有产生对应效果。
  • 检查异步任务的查询、取消和回调接口,让每次访问都回到任务所属客户与授权关系上,避免仅凭任务 ID 返回结果。
  • 接入 A2A 前核对规范版本、SDK 与 Agent Card 字段,把服务发现配置、认证配置和业务授权规则分别记录,方便定位接入失败发生在哪一层。
Original source

本文由 AI 通读原文后重新编写,观点部分为站内判断,细节以原文为准,来源 dev.to · AI,原文版权归原作者所有。

阅读原文
上一篇
10MB JSON 实测:异步读取仍会阻塞解析
下一篇
语音 Agent 如何明确表达未知信息

资讯速览

dev.to · AI · 2026-10-30 05:54

AI 评分 8.0 / 10

相关标签

#Agent#权限控制#安全

继续阅读

  • 用验收测试检查代理令牌能否被盗用
  • 10MB JSON 实测:异步读取仍会阻塞解析
  • 语音 Agent 如何明确表达未知信息
  • 给 AI 代码设置凭证据放行的质量门禁
  • 用原生 JS 与 PHP 搭建站内知识助手