附录 B:协议与 API 参考
本附录提供接口阅读和实现对照规则。路径、字段和状态以各节点服务入口、oan-protocol-common/schemas/agent-contract/openapi.yaml、官网前后端 API 封装及实际部署配置共同核对;当前只在通用契约中声明的能力不能被写成已由所有节点暴露。接口变更必须关联协议版本、错误模式、认证方式、幂等规则和第24章变更记录。
B.1 端点目录
端点目录按服务角色列出健康、DID、资源注册、根平台发布、内容分发、发现、治理状态和统计接口,并区分公网入口、节点间入口、仅限内部入口和部署前缀。当前官网通过同源后端转发部分注册和发现请求;节点本身还暴露独立服务端点,因此官网路径不能自动推导为所有节点的协议路径。示例基础 URL 使用占位符,不把官网当前域名或某台服务器地址固化为协议要求;每行至少记录调用方向、HTTP 方法、认证、请求/响应模式、失败和版本。下表只列出当前代码中可以核对的代表性入口,未列出的管理、统计和调试接口仍以对应节点路由为准。
| 服务角色 | 调用方向、方法与路径 | 认证边界 | 主要返回 |
|---|---|---|---|
| 注册服务节点 | 客户端 -> 注册服务节点:POST /resources/register;客户端 -> 注册服务节点:GET /registrar/status、GET /registrar/did |
注册入口接收资源控制证明;向根平台转发时使用节点间签名 | 注册 VC、受理状态、根平台响应 |
| 根平台 | 注册服务节点 -> 根平台:POST /root/resources/verify-and-publish;客户端或节点 -> 根平台:GET /root/resources/{did}、GET /root/status |
发布写入仅限授权节点或管理调用;公开读取取决于部署 | 根平台可信发布证明、资源版本、状态和游标 |
| 内容分发平台 | 根平台或发布器 -> 内容分发平台:POST /cdn/resources、POST /cdn/resources/batch;客户端或节点 -> 内容分发平台:GET /cdn/resources/{did}、GET /cdn/resources/index |
发布使用节点间认证;资源读取和索引读取取决于部署 | 资源包、索引条目、同步状态 |
| 发现服务节点 | 客户端 -> 发现服务节点:POST /discovery/resources/query;节点或运维方 -> 发现服务节点:GET /discovery/index/resources/{did}、GET /discovery/status |
查询可公开,管理和同步接口受限 | 资源结果、来源和证明引用 |
| 运维接口 | 运维方 -> 节点:GET /health 及节点状态、指标和审计接口 |
运维认证和网络边界 | 状态摘要,不含秘密 |
核心载荷类型与端点的对应关系如下。共享类型来自 oan-protocol 或 oan-package 时,字段名称以 serde 的 JSON 映射为准;Value 表示当前实现的动态响应,不能据此推导不存在的固定 schema。
| 端点 | 请求 JSON 类型 | 响应类型或主要字段 | 备注 |
|---|---|---|---|
POST /resources/register |
ResourceRegistrationSubmission |
动态 JSON:登记状态、资源 DID、注册 VC、根平台响应 | /resources/submit 绑定同一处理函数 |
POST /root/resources/verify-and-publish |
ResourceVerifyAndPublishRequest |
动态 JSON:resource-verified-and-queued、版本、三类哈希和 CDN 队列状态 |
仅限授权注册服务节点的节点间调用 |
POST /cdn/resources |
ResourceCdnPublishRequest |
动态 JSON:published、版本和发布游标 |
资源包必须通过根平台来源和哈希校验 |
POST /discovery/resources/query |
ResourceDiscoveryQuery |
ResourceDiscoveryResponse |
limit 默认 10,versionMode 默认 latest |
POST /discovery/query/explain |
ResourceDiscoveryQuery |
动态解释 JSON | 不等同于普通发现响应 |
GET /cdn/resources/{did} |
路径参数 did |
ResourcePackage |
直接读取资源包 |
POST /cdn/resources/batch-get |
本地 ResourceBatchGetRequest |
requestedCount、foundCount、items |
请求体包含 resourceDids 数组 |
B.2 请求头字段与签名
请求头和签名材料按接口 profile 定义。当前节点间 SignedRequestEnvelope 使用 requestId、protocolVersion、purpose、method、path、aud、requestTimestamp、requestNonce、bodyHash 和 proof 等 JSON 字段承载签名语义;官网面向浏览器的公开注册和发现入口不应凭空增加一组未在服务入口定义的 X-OAN-* 必需头。若接口使用协议信封承载这些信息,应以 JSON 字段为准;若部署层额外使用 HTTP 头,只能作为部署 profile 说明。服务端需校验签名覆盖的规范化请求、目标 DID、时间窗和 nonce;缺失、过期、重放或目标不符时拒绝。
节点间协议信封字段的作用可按下表对照。method 和 path 绑定被保护的 HTTP 请求,aud 绑定接收方,bodyHash 绑定请求体;这些字段共同避免把一个节点发出的有效证明挪用于另一条请求。浏览器提交资源时,资源控制证明位于请求体的 subjectControlProof,不应把它误写成节点间 HTTP 头。
| 字段 | 作用 | 校验重点 |
|---|---|---|
requestId |
标识一次节点间请求 | 用于日志关联,不能替代防重放机制 |
protocolVersion、purpose |
标识协议版本和调用目的 | 与接收接口允许的 profile 匹配 |
method、path、aud |
绑定 HTTP 方法、路径和接收方 | 不能与实际请求或目标节点不一致 |
requestTimestamp、requestNonce |
限制时间范围并阻止重复使用 | 检查时钟窗口和 nonce 重放缓存 |
bodyHash、proof |
绑定请求体并提供完整性证明 | 重新计算请求体摘要并验证证明 |
POST /resources/register
Host: registrar.example
Content-Type: application/json
节点间请求的 upstreamAuth.proof 应覆盖方法、规范化路径、目标、时间/nonce、内容摘要和实际请求体;服务器完成时间窗、重放缓存、签名者授权和资源控制权检查后才执行写入。浏览器注册请求的资源控制证明位于请求体的 subjectControlProof,它与节点间的 upstreamAuth 不是同一种凭证。
B.3 响应头字段与缓存指令
响应可以在适用时提供来源、协议/模式版本、数据时间、新鲜度、ETag、缓存控制、关联标识和必要安全头;这些字段不是当前所有节点接口都统一保证的公共响应头,下面的 X-* 项仅可作为部署层或接口 profile 的扩展约定。ETag 或缓存命中只说明内容版本未变,不证明资源状态或治理授权仍有效;返回旧快照时,响应或正文应有可识别的时间和降级标识,不能用缓存掩盖上游失败。
| 字段或指令(适用时) | 作用 | 使用注意 |
|---|---|---|
ETag |
标识响应内容版本 | 不等同于治理状态有效 |
Cache-Control |
指定缓存和重新验证策略 | 旧快照须同时标识新鲜度 |
X-Request-Id |
关联客户端、节点和日志 | 不得包含私密信息 |
X-OAN-Data-Time |
表示数据生成或采集时间 | 与服务器响应时间区分 |
X-OAN-Freshness |
表示 current、stale 等状态 |
不能掩盖上游失败 |
B.4 状态码与错误码
HTTP 状态码表达传输层和通用处理结果,OpenAgenet (OAN) 错误码表达字段错误、签名无效、未授权、未找到、重复、版本冲突、依赖失败、同步滞后和内部错误等具体语义。当前公共错误码词汇以 oan-protocol-common/docs/error-codes.md 为准,例如 invalid_did_document_structure、invalid_registration_credential、invalid_request_signature、unauthorized_domains、invalid_root_proof 和 package_decode_failed;该文件定义错误语义,但没有把每个错误码固定绑定到唯一 HTTP 状态,不同节点可能通过 HTTP 状态或响应体映射这些错误。客户端按实际错误结构决定重试;不能把所有 2xx 都当作发布成功,也不能把 404、空结果和同步未完成混为一谈。
| HTTP 状态 | OAN 错误码示例 | 客户端动作 |
|---|---|---|
400 |
invalid_did_document_structure、invalid_authorized_domains、package_decode_failed |
修正输入或资源包后重试;具体状态以接口实现为准 |
401/403 |
invalid_request_signature、unauthorized_domains |
重新认证、改用授权节点或停止请求 |
404 |
节点返回的资源未找到错误 | 区分未找到和索引未同步 |
409 |
节点返回的重复或版本冲突错误 | 获取当前版本并按更新规则处理 |
429 |
部署层限流错误 | 遵循重试提示并退避 |
5xx |
依赖不可用或内部错误 | 只有在接口标明可重试时才退避重试 |
B.5 分页与游标规则
列表接口使用明确的 limit、游标和排序规则,游标只能由服务端生成和解释,客户端不得假设其可读或可修改。当前 ResourceDiscoveryQuery 公共类型固定提供 limit,默认值为10,但 POST /discovery/resources/query 的请求模型没有游标字段;发现服务会按 limit 截取候选结果。实际提供 afterCursor、nextCursor 和 hasMore 的是内容分发平台 GET /cdn/resources/index,其游标与发现查询的 limit 不是同一类型。页大小应有部署上限,排序键在分页期间保持稳定;过期、非法或与过滤条件不匹配的游标应返回错误。发布游标、同步游标、事件游标和分页游标不能交叉使用。
GET /cdn/resources/index?limit=20&afterCursor=1800
Accept: application/json
{
"items": [],
"count": 0,
"afterCursor": 1800,
"nextCursor": 1800,
"hasMore": false
}
分页游标只表示内容分发平台列表的读取位置;发现查询的 limit 只控制本次候选结果数量,不产生可续接的发现分页游标。发布序列、分发同步游标和治理事件游标必须使用各自接口定义的字段和校验规则。
B.6 版本与兼容性头字段
协议版本、资源模式版本、能力声明和兼容策略通过已定义的协议信封字段、请求体字段或部署 profile 表达,并在请求和响应中保持可追溯。当前公共协议常量包括 oan-resource-2026,而 ResourceDiscoveryQuery.versionMode 默认值为 latest;这类协议字段不能直接改写成未经代码支持的统一 HTTP 头。服务端遇到不支持的版本应返回明确不兼容结果;兼容扩展不得改变 DID、签名、状态或发布序列语义,版本选择规则参见第24章。
{
"query": "a tool that can search code repositories and summarize project structure",
"capabilityTags": ["code-search", "project-structure-summary"],
"versionMode": "latest",
"limit": 10
}
上例是 POST /discovery/resources/query 的发现查询请求示例,字段均对应当前 ResourceDiscoveryQuery;protocolVersion 则属于节点间 SignedRequestEnvelope,不应混入该查询对象。当前查询模型没有统一的 capabilities 字段;能力条件应通过 capabilityTags 或目标接口明确支持的扩展表达。服务端不支持请求版本时,应返回明确的版本不兼容错误及可接受版本范围;客户端不得仅因收到 HTTP 2xx 就忽略响应模式版本。
B.7 健康、就绪与存活响应格式
当前各节点公开 /health 响应的公共最小结构是 HealthResponse:status、nodeType 和可选的节点 DID;节点状态接口可以另外提供数据库、上游、同步游标或错误摘要。运维系统可以据此区分进程存活、依赖就绪、业务可用和数据同步状态,但不能把所有字段都当作每个节点都存在的统一 schema。liveness 通过不等于 readiness,通过 readiness 也不等于注册或发现烟测通过;敏感配置和令牌不得出现在响应。
{
"status": "ok",
"nodeType": "discovery",
"did": "did:oan:INDS:7YpQm9Kx2VnRb6Ts3WfHa4Cd5Ej8LgNz"
}
若部署提供扩展状态接口,可以在上述最小响应之外增加检查时间、依赖状态和同步游标;扩展字段应标明来源和版本,不能把该扩展响应反向当作所有节点 /health 的强制返回结构。
| 检查类型 | 证明内容 | 不代表的内容 |
|---|---|---|
| liveness | 进程仍能响应 | 依赖和业务可用 |
| readiness | 服务具备接收请求的条件 | 注册或发现烟测成功 |
| dependency | 数据库、上游或索引器状态 | 所有业务路径正常 |
| smoke test | 关键业务流程可完成 | 长期性能和全量正确性 |
B.8 公开、认证与仅限运维 API 矩阵
接口矩阵至少区分公开只读接口、发布/注册认证接口、节点间接口和仅限运维接口。公开发现、DID、状态和必要统计可以供互联网访问;写入、管理、数据库、完整日志、访问统计和密钥相关接口必须受认证、网络边界和审计保护。官网后端的中转接口不能扩大下游服务权限,普通用户不可通过公开接口取得后台统计或秘密。
| 访问级别 | 示例 | 允许的数据 | 保护要求 |
|---|---|---|---|
| 公开只读 | DID、发现、必要状态 | 已发布资源和公开证明 | 限流、输入校验、审计 |
| 已认证写入 | 注册、更新、节点间同步 | 授权范围内对象 | 签名、nonce、幂等和授权检查 |
| 仅运维 | 指标、完整日志、管理操作 | 内部运行数据 | 强认证、网络隔离和最小权限 |
| 禁止公开 | 数据库、私钥、访问统计明细 | 不对互联网用户开放 | 不得通过官网中转泄露 |
参考来源
| 来源 | 类型 | 链接 |
|---|---|---|
oan-protocol-common |
代码仓:协议类型、OpenAPI 契约和错误码 | https://github.com/wolfbrother/oan-protocol-common |
oan-root-services |
代码仓:根平台 API | https://github.com/OpenAgenet/oan-root-services |
oan-registrar-node |
代码仓:注册 API | https://github.com/OpenAgenet/oan-registrar-node |
oan-discovery-node |
代码仓:发现 API | https://github.com/OpenAgenet/oan-discovery-node |
oan-sdk-ts |
代码仓:客户端 API 封装 | https://github.com/OpenAgenet/oan-sdk-ts |
| OAN Resource Identity and Discovery | IETF 草案:资源身份和发现 API | https://datatracker.ietf.org/doc/draft-xu-oan-resource-identity-discovery/ |
| Efficient Agent Discovery Profile | IETF 草案:发现 API profile | https://datatracker.ietf.org/doc/draft-xu-efficient-agent-discovery-profile/ |