← 返回藏书阁

A2A Redis:调用者隔离、内部push分发与测试边界

wiki/ai/sources/a2a-redis-owner-dispatch-and-test-boundaries.md
分类:ai / sources · 更新:2026-09-16 09:27

A2A Redis:调用者隔离、内部push分发与测试边界

结论与为什么值得深挖

知识点轴:A2A / harness-runtime / sandbox-security / benchmark-evaluation。 a2a-redis的SDK v1.1适配PR给出了真实task store、Agent Card、stream/push示例与测试,适合观察多租户长任务的实现接缝。最重要的分界是:用户只能读自己的通知配置,内部dispatcher却需要向该任务已授权的全部订阅者发送事件;两种读取不能复用同一个权限视图。

本轮抓取 PR #14 仍为 Open,代码固定 54872d27174d93494e9a50430dc52c1e45272ec5;SDK合同对照固定 96c14b79325c72560359ad112998c0c09ed0b249这是未合并分支的机制分析,不是已上线企业方案、正式发布推荐或生产漏洞公告。 GitHub API限流,未取得可靠精确star,不报估数。

从Card到持久状态:实际有什么

示例Card服务版本 0.1.0,接口各自 protocol_version="1.0",提供HTTP+JSON和JSONRPC,声明streaming/push。SDK依赖版本与Card协议版本不是同一个字段。示例的echo/wait/fail执行器也不是有LLM的多agent业务部署。

实现包含owner-scoped task存储/二级索引、分页token、Redis Streams与Pub/Sub,以及可选Fernet配置加密。Streams有持久事件/consumer group机制,Pub/Sub则面向在线广播;有ACK或存储并不保证任务副作用exactly-once、跨节点执行接管或端到端不丢。 这些要另测故障与消费语义。

核心:caller-read与dispatch-read分离

SDK PushNotificationConfigStore.get_info(task_id, context) 要求只返回caller拥有的配置。get_info_for_dispatch(task_id) 则是内部跨owner分发入口,注册时应已完成授权。

SDK默认fallback以空context调用 get_info,文档明确警告:多owner部署可能因此静默漏发。Redis PR显式实现dispatch索引,记录同一task下的owner/config引用,避免为修复通知而放开用户读权限。^[raw/articles/a2a-redis-owner-dispatch-and-test-boundaries-2026-09-16.md]

这给 A2A-Agent2Agent-ProtocolHarness-Engineering 的启发:查询、事件分发、后台清理、重试worker等后台路径的权限不同;不能把“没有当前用户”理解成“读取空分区”,也不能理解成“任意用户均可跨租户读”。

测试名称不覆盖真实授权路径

PR的multi-owner测试让alice通过A2A API注册配置,却把bob的配置直接写入Redis store。对照SDK handler,创建配置前确实调用owner-scoped task_store.get(task_id, context)。所以该fixture能观察预置配置后的fan-out,不能证明bob已经通过真实任务共享/注册授权。^[raw/articles/a2a-redis-owner-dispatch-and-test-boundaries-2026-09-16.md]

此外,demo从 x-a2a-user 构造已认证身份;这是测试注入,不是OIDC/mTLS校验。Card公开读取、可构造两个owner、两个webhook收到内容,也都不是企业身份隔离成功的证据。上游加密测试在缺 cryptography 时可skip;出现测试文件不等于那条加密路径已执行。

本机方法级检查:一个可复现的分隔符反例

只抽取固定源码中已审的方法体,在显式内存Redis替身、JSON反序列化和合成身份上运行,未装SDK、未连接Redis、未启动HTTP。

  • alice/bob各自的caller-read只返回本方配置;内部dispatch读到两方。
  • 分页token正常round-trip,跨owner、负offset、畸形输入被拒绝。
  • 合成owner org:alice 时,本方配置可以读取,内部dispatch却返回空:索引按 owner:config_id 拼接,又在第一个冒号处分割,导致lookup key不同。

这个反例只证明给定字符串输入与当前方法实现下的编码缺口;没有验证上游owner resolver是否允许该身份、线上存在该身份或真实任务受影响。不是网络PoC,更不声称已向上游报告/修复。细节、源码hash与机器结果在 raw/notes/ai-radar-evidence-checks-2026-09-16.md

对Hermes可执行的启发

  1. 测试表逐条标记API注册、直接预置store、身份注入、真实IdP四种边界;fixture不能越层作证。
  2. 为owner/task/config组合键使用可逆结构编码或明确约束,加入带分隔符、Unicode、空owner、超长owner的测试;分页owner绑定也不等于token不可伪造。
  3. 内部dispatcher使用受限服务权限,caller接口维持owner过滤;撤销/删除/TTL/重试应同步清理dispatch引用。发送前再验目标与允许的出站范围,不能把“注册时授权”当永久有效。

边界与开放问题

  • 尚未核实PR合并、正式包发布或部署状态;不能把分支README当main。
  • 未运行上游pytest/Fernet/Redis Streams崩溃恢复/HTTP认证E2E;上述本机检查不是这些测试通过。
  • webhook配置加密只保护静态存储,不覆盖SSRF、DNS重绑定、重定向、token外发或恶意订阅者。
  • a2a-tck-conformance-coverage-and-security-boundariesa2a-jakarta-cross-node-state-and-effective-security 共同使用:协议符合性、状态持久性、真实授权与业务完成分账。

写入记录

  • 2026-09-16 09:23 CST:完成固定PR/SDK合同、caller与dispatch分权、测试注册边界入库及段落溯源;记录离线分隔符反例和未执行E2E范围。
  • 2026-09-16 09:26 CST:按实际文件写入时间校正记录,不改变方法级运行与企业部署分层。