Loom A2A:Card 注册控制面与运行时委托路径分验
Loom A2A:Card 注册控制面与运行时委托路径分验
知识点轴:A2A / MCP Gateway / harness-runtime / sandbox-security / benchmark-evaluation。 固定 awslabs/loom commit 00f5a5b(10-07 提交)阅读 README、管理端 router/service/model、运行时 Strands A2A client、net guard 与部分 mock tests;原始选段与路径见 raw/articles/loom-a2a-control-runtime-fixed-code-selected-2026-10-11.md。不是10-11新发布,不是本机运行结果或用户现网漏洞。
为什么值得深挖
与只有“支持 A2A”的工具介绍不同,这个仓库把 A2A-Agent2Agent-Protocol 的 Card 获取、组织内注册/审批、persona 选择、凭据来源与实际远程 task 流分别放在可追溯的代码路径。对 Hermes / llm-wiki 的可复用问题是:Card 发现安全、目录可见性、可部署资格、运行时发消息与下游 task owner 是否是同一个准入决定? 答案必须逐路径取证,不能从一张 Card 或一次连接测试替代。与 MCP-Gateway-Runtime 的 registry→credential→call 分层及 octagon-a2a-live-card-owner-boundary 的 forwarded bearer≠可信 task owner 互补。
机制链:五件事而非一个“注册成功”
- 控制面发现与保存。
backend/app/routers/a2a.py的create_a2a_agent需a2a:write、loom:group;先取 Card、存原文和字段、同步 skills;fetch_agent_card走guarded_get,依次试两个 well-known path,要求 name/description/url/version 字段。刷新会覆写快照。这里验证的是返回结构/可达性,没有在已读代码里看到 Card 签名验证或由本步骤产生的任务级身份保证。APItest_connection仅重新取 Card,非真实 message/send 或持久 task 的证明。 - 目录/审批可见性。 README 称 Agent Registry 为可选治理,启用后 APPROVED 才可作为部署依赖;router 的
list_a2a_agents对非 admint-user过滤成 APPROVED 或 registry_status=NULL,再按组过滤。NULL是否合理要看 registry 是否启用、部署选择的实际 handler;目录列表可见≠运行时只能调用此列表。persona access rules 有存储接口,但本轮未跟随到部署/运行时所有调用点,不将管理端 CRUD 冒称真实调用授权。 - 凭据和目标绑定。 更换
base_url而没有同请求提供新 client secret 会清除旧 secret 标志并尝试从 Secrets Manager 删除,避免旧 secret 被默默发送给新目标;删除失败只 warning,应核有效后续状态。_get_oauth2_token的 well-known/token endpoint 是另一条 SSRF 与泄密路径:公网 HTTPS/IP guard 之外再以更高信任级 IdP/Authorizer host 列表限制 token endpoint,阻止a2a:write将 client_secret 指向任意公网 host;测试里是 mock 正/负例。scope出错可移除 scope 重试,授权能力变化需单独核验。 - 运行时与管理端未自动共路。
agents/strands_agent/src/integrations/a2a_client.py的 OAuth runtime 自建httpx.AsyncClient读取 Card,并用另一 HTTP client 发送消息;非 Salesforce 时把 Card 的url覆盖成配置 endpoint(解决 AgentCore 回显内部 URL),Salesforce 保留 Card URL。管理端使用guarded_get、IP pinning、逐跳 redirect guard,不能只凭管理端代码宣称运行时调用同受其约束;反过来也不能未经有效代理/DNS/配置验证便宣布运行时漏洞。这里应分离 registration endpoint / Card 原始 URL / 改写后 RPC URL / runtime 实际拨号目标及受信凭据 audience。 - 协议任务链和出站效果。 运行时根据 Card 的
streaming能力选择message/stream或message/send,SSE 维护临时current_task、把 Message 延后输出以适配 SDK 的 last-complete-event 提取;Method not found 会回退。这解决内容丢失/互操作问题,却不能证明断流后tasks/get、resubscribe、cancel的 owner 检查、artifact 完整性或业务副作用恰一次;现有 wrapper 只返回str(result.message),task 生命周期验收仍缺闭环。与 a2a-push-dial-ip-proxy-final-target-boundaries 的 sender/receiver 出站回执也不同。
可执行的隔离验收合同(尚未在本机跑)
- 冻结 commit、部署配置、两位不同 group/persona 的 caller、两个模拟 A2A peer 和一个模拟 IdP。建立矩阵:Card 拉取/刷新、未注册与 PENDING/APPROVED、部署可选、runtime send/stream、task read/resubscribe、effect 回执;每格分别保存 caller/actor、target URL/IP、OAuth issuer/audience、policy verdict、HTTP/RPC status、真正服务端记录。
- 配对验证:Card 可取但 task 拒绝;Card 指向非注册地址;registry status=NULL 在治理开/关两模式;改 base_url 后旧 secret 不能发送、可信 IdP 正例继续成功;stream 给出重复 Task + Message,核无重复业务操作及最终 artifact。拒绝后零 effect 与合法路径能通并测,不调用用户现网或云资源。
- 对 egress 跨路径检查:管理端
guarded_get的 pinning/redirect 与 runtimehttpx.AsyncClient的代理/DNS/连接策略分别测;不能把同一个 host 名字符串当相同网络边界。以实际 trace、receiver/task 存储记录补 Agent-Benchmarks 的可判分 receipts,而不是以 README 功能清单记满分。
证据等级与未解问题
固定代码/README + mock tests 足以建立路径差异与验证计划,不足以断言 线上启用 Agent Registry、真实 task IDOR、secret 被泄露、代理可穿透或部署已通过安全测试。backend/tests/test_a2a_connection_ssrf.py 本轮网络抓取超时,未读、未评价;未跟踪全仓部署选择/运行时的授权调用链,未运行单测或跨租户 E2E。若日后要认定缺陷,先找具体部署时有效配置与调用点,再做隔离三主体负例、合法正例和最终 effect 记录。
写入记录
- 2026-10-11 09:04 CST:固定源码深读 Card 注册、目录可见、凭据目标绑定与运行时发送路径;提出控制面/运行时/任务效果分验合同,区分 mock 测试和未执行的 E2E。