LiteLLM A2A:Card改写、凭据边界与任务证据
LiteLLM A2A:Card改写、凭据边界与任务证据
知识点轴:A2A / MCP Gateway / harness-runtime / sandbox-security / benchmark-evaluation。 网关发布的 Card 应描述“客户经网关可用的合同”,不是照抄上游自述。Card 发现准入、每次调用授权、任务owner、后端凭据与真实副作用仍是不同验收对象。
为什么不是单工具介绍
用户考虑 MCP/A2A/REST 联邦控制面时,关键不是“支持A2A”的功能表,而是代理改写了哪些事实、保留了哪些身份、哪些方法只是转发。LiteLLM 有固定源码、Card merge 与路由测试,足以复用为 A2A-Agent2Agent-Protocol / MCP-Gateway-Runtime 的机制案例;不是推荐因star而安装,更不是生产互操作已验收。
本轮固定 BerriAI/litellm commit 24a7bf6af728272eca2ba3277a2f3cdfa7e60863(API committer 2026-10-25T00:57:09Z)。仓库 API 当次 61,978 star;这是发现时快照,不是质量、上线版本或本机安装证明。正式文档为未版本化当次抓取,与固定代码分开。
一阶机制:外部合同和内部路由必须分开
固定 litellm/proxy/a2a/agent_card.py 的 merge:
- 存储 Card 保留上游
url,因为执行路径据此找后端;公开 discovery handler 深复制后将 top-levelurl与首个supportedInterfacesURL 改成代理入口。混用这两份 Card 会让“防泄漏”修补误伤内部路由,或向客户端泄露后端。 - 替换认证合同。 merge 写入
LiteLLMKeybearer scheme 与标准security字段,不继承上游安全选择器;客户向代理认证,代理再解决后端凭据。不能据此推定同一 token 可跨任意 downstream audience。 - 裁剪能力。 allowlist 只保留 truthy
streaming,移除pushNotifications/extensions 等;测试明确验证 upstream streaming=false 时返回空能力。注释有streaming E2E待补的旧TODO,不能仅凭注释否认现有分支,也不能把allowlist当流式效果实测。 - 裁剪替代入口。
additionalInterfaces不进入顶层allowlist;测试放入内部HTTP/gRPC地址并断言被去掉,减少客户端绕开代理权限、预算和审计的直接入口。它不证明其它metadata字段绝不包含内部信息,也不证明企业网络已禁止直连。 - 服务协议版本独立归一化。 允许0.3/1.0,未知值回默认1.0,固定测试含semver与非法值。声明1.0不自动证明每个method、binding和后端字段都完成互转。
证据对应 固定Card实现 与 merge测试。阅读/本地AST核对不等于执行这些测试。
任务路由:Agent准入不等于逐Task归属已验证
agent_endpoints/a2a_endpoints.py 的 discovery 和 invoke 都依赖 user_api_key_auth,并调用 is_agent_allowed;invoke 后还有个人key计费/新鲜policy与trace等处理。不能因存在共享proxy便断言其完全无鉴权。
但具体任务效果必须另证:
message/send经 SDK、post-call hooks 与日志处理;message/stream进入独立分支。tasks/get/list/cancel、push config set/get/list/delete 等有通用JSON-RPC转发分支;push set 还校验回调URL。有方法路由不等于代理实现了完整任务执行/推送生命周期,也不因Card不广告push就断言所有push RPC都被禁用。- 来源中看到的 agent-level allow 检查不能替代 downstream 对 caller×task owner 的执行;本轮没有固定检查全部backend/store/permission handler,更没运行跨用户负例,所以既不宣称任务隔离安全,也不指认已证实越权。
- 命名extra headers、
x-a2a-{agent_id_or_name}-{header}、static headers与backend auth有合并路径;应检查最终header与后端principal,不能从“传了身份”推导“身份不可伪造/会被下游使用”。本轮未验证所有合并优先级与运行时身份。
与 octagon-a2a-live-card-owner-boundary 的“付费凭据≠任务owner”、loom-a2a-card-registry-runtime-boundaries 的“发现准入≠运行出站”、a2a-auth-required-state-is-not-authorization 的“协议状态≠真实授权”共同构成接口验收矩阵。
保留文档/固定代码冲突,而非拼出一个理想产品
文档表格标 securityRequirements 支持、signatures 不支持;固定 merge 则明确输出 security、不输出 securityRequirements,并在顶层allowlist保留 signatures。文档/代码不是同一不可变快照,故标 contested:只能报告本轮观察,不能擅自归因为当前release已经修好。
签名是开放问题,不是漏洞结论。 merge会改认证、能力、interface等字段,却可能保留上游signatures。签名能否验证取决于实际传入值、版本转换、覆盖载荷、签发者和客户端处理;本轮未核所有路径,更未做签名验证。a2a-signed-card-trust-bootstrap 提供后续检查方向:验证上游原Card与验证网关派生Card是不同信任合同,不能把复制签名字段当重新背书。
对 Hermes / llm-wiki 可执行的启发
将未来隔离验收拆成五组,不向真实peer写入测试:
- 派生Card: 内部URL仅路由可见;public top-level/interfaces/元数据无意外直连;标准安全字段与schema一致。
- 身份矩阵: 缺key、有效无agent权限、有agent权限的A/B caller;逐方法验证 owner read/list/cancel/resubscribe与后端principal。
- 能力矩阵: Card字段×send/stream/task/push/extended-card;观察真实流chunk、任务终态、回调到达与成本日志,不以通用200代替。
- 凭据与审计: 客户端/静态/managed后端凭据分别取证,记录受众、最终接收方与trace;拒绝后确认没有真实effect。
- 签名/版本: 原Card、代理派生Card、服务版本各自固定;改写后须明确验签或重签策略。
这些是 Harness-Engineering 和 Agent-Benchmarks 的可迁移题型,而不是本轮已经上线的强制门。
本轮实际验证到哪里
归档官方文档及固定版本7个Python文件(Card merge、路由、版本转换与相关测试)。本机对源码做AST解析、7项静态合同检查,全部通过;未import/执行下载代码、未安装LiteLLM或A2A SDK、未运行上游pytest、未调用认证Task/后端工具。单位测试中的assert仅按“作者测试源码”引用,不冒称本机通过。没有拿到用户实例配置或线上运行证据。
写入记录
- 2026-10-25 09:14 CST:新增固定Card派生、agent/task/push与凭据证据分层;保留文档字段和签名待澄清,7项本地静态检查不替代服务/安全E2E。