← 返回文章列表

一个 Agent 产品如何安全接入 Foundation:从 Product Recipe 到 Registration

拆解一个采用方如何声明能力、编译依赖、接受 Provider Claims、装配 Runtime,并通过 Registration 打开最小权限句柄。

让一个产品“接入 Agent Foundation”,最容易写成几行配置:打开 Memory、打开 Evidence、打开 Graph,再给调用方一把 credential。这个方案看起来快,却会留下一个根本问题:这些布尔值到底是在表达产品愿望,还是在证明运行时真的具备能力?

如果产品能靠自己的配置声称“我有 ReviewDecision”“我有 Graph executor”,Registration 就不再是权威,只是一张自填表格。如果不同入口各自创建身份、能力和 scope,同一个产品还会出现两套互相矛盾的 Registration。

Agent Foundation 最终收敛成一条唯一链路:

Product Recipe 表达需求;Compiler 解析需求;accepted Provider Claims 证明 provider 保证;Runtime assembler 找到唯一真实 component owner;Registration Authority 重新校验并持久化 receipt;actual principal 最后打开受限句柄。

Product Recipe 到 Registration 的唯一权威链

技术解释图:Recipe、compiled plan、Provider Claims、Runtime owner 与 Registration 必须连续成立;任何一环缺失都会 fail closed。

查看 Agent Foundation 项目总览 · 打开本文交互图

Recipe 只能说“我需要什么”

一个 Product Recipe 可以声明:

  • 需要 Context read;
  • 需要 Memory governance;
  • 需要 Evidence authority;
  • Graph Proposal 采用 proposal_only 还是 review_required
  • dependency profile、operation budget、failure semantics 和目标范围。

但 Recipe 不能声明“这些能力已经存在”。这是第一条关键不变量:需求声明不是授权证明。

这个区别看似语义化,实际防止了 adopter 通过自定义 boolean 或伪造 service claim 绕过 Foundation。产品可以选择能力,却不能成为 Foundation 能力的证明者。

编译阶段不是拼 JSON,而是验证依赖闭包

Compiler 会把 Recipe 变成 capability plan。它检查的不只是能力名称,还包括依赖、边界和组合是否合法。

例如,review_required 的 Graph Proposal 不只是“多一个审核按钮”。它要求至少存在:

  1. Graph data plane;
  2. Evidence authority;
  3. Graph Proposal authority;
  4. ReviewDecision execution;
  5. 能够承担这些能力的真实 Runtime component。

任何一项 unresolved,编译结果就不能被包装成一个可用 Registration。普通 Recipe 也不会因为系统里存在高级 provider,就自动继承 Graph 或 Review 权限。

Provider Claims 与 Runtime ownership 必须同时成立

Provider Claim 回答“这个 provider 承诺什么”,Runtime component ownership 回答“运行时究竟由哪个组件承担”。两者缺一不可。

只接受 claim 而不检查 component,会出现纸面能力:编译结果说支持 Graph,真正打开 Runtime 时却没有组件负责。只检查 component 而不验证 accepted claim,则会让一个对象因为恰好实现了某个接口,就获得未经合同接受的权威。

Foundation 因此要求三项一致:

层次回答的问题不能替代什么
Compiled plan这份 Recipe 需要哪些能力和依赖不能证明 provider 已被接受
Accepted Provider Claimsprovider 对能力、限制和失败语义作出什么保证不能证明 Runtime 已装配
Runtime component owner哪个唯一组件真正承担能力不能自行扩大 Recipe 需求

当 adopter 尝试注入 Foundation service claims 时,公共链路会以稳定错误拒绝,而不是“尽量继续”。

Register V2 为什么还要重新校验

编译成功不代表可以永远注册。编译到注册之间,Provider identity、Registration lineage、policy fingerprint 或 component binding 都可能漂移。

V2 Registration 因此不是简单保存 compiler 输出,而是在权威边界重新检查完整 binding set,然后原子持久化:

  • Registration identity 与 lineage;
  • exact compiled capability plan;
  • accepted Provider Claims;
  • selected Runtime components;
  • scopes、role ceilings 与 policy fingerprints;
  • 可供后续 open 验证的 receipt。

这使 Registration 成为可以被重读和核对的权威事实,而不是进程内临时对象。

一个 Registration,不等于一把超级凭据

同一个产品可以有 Agent、reviewer、revalidator、executor 等不同角色,但它们不应该共享 memory:admin 或万能 token。

Foundation 在 Registration 上冻结角色上限,再根据实际认证 principal 打开最小权限句柄:

  • Agent 可以读取 Context 或提交候选,但不能审批自己;
  • reviewer 可以读取被授权的治理状态并形成 ReviewDecision,但不能直接执行 Graph mutation;
  • revalidator 可以消费 Evidence lifecycle 任务并更新支持投影,不能改变业务提案;
  • executor 可以消费 durable outbox 并写真实副作用,但不能伪装成业务 owner。

实际 actor 与 represented business owner 被明确分开。请求体自报的 actor 不会覆盖认证 principal。

为什么要消除多条 Registration 接线

平台演进时,最危险的兼容方式是保留两套都能产生权威身份的入口。它会带来重复 identity、不同 scope 推导和无法判断哪个 Registration 才是真的。

Foundation 的处理不是给每个旧入口继续打补丁,而是保留兼容 facade,同时让所有入口最终投影到同一条 compose → assemble → register → open 权威链。V1 兼容只允许在语义完全一致时做精确投影,不能静默升级为 V2 高级能力。

AF-RA01 进一步移除了 Registration 建立过程对旧 Memory-shaped credential handoff 的依赖。Registration 使用自己的 read/write scopes,角色上限从 sealed binding set 推导,不再借用 memory:admin 代表跨域管理权。

一个采用方的实际接入顺序

对高级采用方,推荐的工程顺序是:

  1. 用业务语言列出需要的 Foundation 能力和明确非目标;
  2. 选择官方 Recipe fragment 或构造 capability-neutral Recipe;
  3. 提交 compiler,检查每项 requirement 是否被真实 accepted claim 满足;
  4. 检查每项 enabled capability 是否只有一个 Runtime owner;
  5. 创建并持久化 V2 Registration;
  6. 用实际 principal 打开最小权限 handle;
  7. 分别验证正常路径、缺 capability、伪造 claim、scope 不足和 lineage 漂移;
  8. 最后才运行产品工作流。

这里最重要的不是 SDK 调用顺序,而是不要在 Registration 尚未成立时,用产品私有 adapter、伪造 provider ownership 或直接数据库写入绕过去。

真实反例如何暴露了接线缺陷

TraceWise 的高级 Graph 接入曾经出现过一个有价值的失败:官方 capability helper 可以描述四项需求,但 compiler 找不到 accepted Provider Claims;使用产品自定义 requirement 后,assembler 又报告 enabled capability 没有 Runtime component owner。

这个反例说明 Graph Proposal 的底层实现本身存在,却还不能被一个外部高级 adopter 通过公共 Recipe 接线使用。修复没有发生在 TraceWise 的私有代码里,而是回到 Foundation 的 Provider Claim 和 Runtime ownership 根因层。修复后,fresh installed wheel 才真正完成 Registration、Evidence admission、Graph binding、review、outbox、独立执行和 receipt。

这也是 Registration 设计的价值:它让“内部测试能跑”和“外部产品能安全接入”成为两个必须分别证明的问题。

当前证据与边界

当前正式基线已经验证 capability-neutral Registration authority、公共 Recipe compiler、真实 Runtime ownership、principal-scoped handles、installed-package 工作流和限定 PostgreSQL/Neo4j 路径。完整源码回归记录为 305 passed、9 skipped。

仍然不能把这些结果描述成生产 IAM、TLS、Secret rotation、HA/DR 或多租户部署证明。Registration 解决的是能力、身份与权限合同,不会自动解决基础设施运维,也不会证明 adopter 的模型质量或业务效果。

最后的判断

一个安全接入模型的关键,不是“配置项够不够多”,而是系统能否证明:产品请求的能力、provider 承诺的能力、Runtime 真正承担的能力和 principal 最终获得的权限,是同一件事。

Product Recipe 到 Registration 的唯一链路,就是把这个证明变成可执行、可持久化、可复核的产品合同。

← 返回文章列表