9. 根平台验证与可信发布
本章说明根平台如何把注册服务节点提交的资源材料转换为可验证的网络级发布事实。内容覆盖上游请求认证、资源 DID 和控制证明验证、节点授权、资源包完整性、发布策略、根平台可信发布证明、版本选择、分发任务和失败恢复,并持续区分“已验证并排队”“已形成发布事实”“内容已分发”和“发现服务节点已索引”等不同状态。
9.1 根平台发布职责
sequenceDiagram
participant Registrar as 注册服务节点
participant Root as 根平台
participant CDN as 内容分发平台
participant Discovery as 发现服务节点
participant Client as 调用方
Registrar->>Root: POST /root/resources/verify-and-publish
Root->>Root: 验证节点授权与 SignedRequestEnvelope
Root->>Root: 验证 DID、控制证明、资源包、版本和发布条件
alt 验证失败
Root-->>Registrar: 拒绝及稳定错误代码
else 验证通过
Root->>Root: 持久化发布事实并创建分发任务
Root-->>Registrar: resource-verified-and-queued
Root->>CDN: 发布资源包与根平台可信发布证明
CDN-->>Discovery: 提供可获取的发布材料
Discovery->>Discovery: 校验材料并建立索引
Discovery-->>Client: 返回资源及新鲜度、状态信息
end
该流程中的“验证并排队”、内容分发和发现索引分别对应不同完成条件。根平台的成功响应只说明资源已通过根平台处理并进入分发任务链路;内容分发平台和发现服务节点仍需完成各自的校验、发布或索引,调用方也应独立验证 DID、注册 VC、根平台可信发布证明和状态信息。
根平台是资源进入网络级发布链路前的独立验证边界。它接收授权注册服务节点提交的登记材料,重新验证资源 DID、DID文档、资源控制证明、资源包(ResourcePackage)、节点授权、版本和发布条件,并将通过验证的资源版本写入发布记录。注册服务节点的前置校验属于接入层检查,不能替代根平台对发布事实的独立确认。
从运行结果看,根平台的“接受”包含两个连续但可区分的事实:一是资源材料通过根平台验证并被持久化,二是面向内容分发平台的发布任务被建立。当前实现的成功响应为 resource-verified-and-queued,因此注册服务节点或客户端应把它解释为“已验证并排队”,不能直接显示为“已完成全网发布”。
9.2 注册节点的上游提交
注册服务节点向根平台提交的是带有上游认证的资源登记请求,而不是一个无来源的资源包上传。请求应关联注册服务节点 DID、请求标识、协议版本、目标路径、时间、随机数、请求体哈希和签名,并携带资源登记提交及其控制证明。根平台应先验证提交来源和请求完整性,再处理资源内容;请求重复、过期或受众不匹配时不得进入发布状态。
当前入口为 POST /root/resources/verify-and-publish。根平台收到请求后,先依据注册服务节点 DID加载授权材料,再验证 SignedRequestEnvelope 的签名、方法、路径、受众、时间、随机数和请求体哈希,随后才执行资源提交的结构和内容验证。上游请求的签名证明“哪个注册服务节点提交了这份材料”,不等同于资源控制证明,也不等同于根平台可信发布证明。
该入口的请求类型是 ResourceVerifyAndPublishRequest,其最小关系可以表示为:
{
"registrarDid": "did:oan:...",
"submission": {
"resourceDid": "did:oan:SKDM:...",
"resourceType": "skill",
"didDocument": {},
"metadata": {},
"packageVersion": "1.0.0",
"didDocumentHash": "sha256:...",
"metadataHash": "sha256:...",
"packageHash": "sha256:...",
"hashAlgorithm": "sha256",
"subjectControlProof": {}
},
"upstreamAuth": {}
}
成功响应当前是动态 JSON,核心结果为 status: resource-verified-and-queued,并带有资源 DID、资源类型、包版本、三类哈希、生命周期状态和 cdnDispatchStatus: queued。这表示根平台已完成当前验证并建立内容分发任务;内容分发平台的接收以及发现服务节点的索引需要通过各自状态或同步记录确认。
9.3 资源 DID 与控制证明验证
根平台应先解析资源 DID 并确认资源类型与 DID 语义编码相符,再确认 DID文档 id、资源类型、验证方法和服务声明满足方法规则,最后使用文档中声明的公钥验证控制证明。控制证明必须绑定本次挑战、目标资源 DID、DID文档哈希、用途和有效时间;验证失败应阻止该版本进入发布记录,且不得覆盖已有有效版本。
可复现的负向测试是:先准备一个能通过验证的提交,记录根平台当前资源版本和发布任务数量;然后仅修改 resourceDid、didDocument.id、didDocumentHash 或控制挑战的 subjectDid 其中一项。根平台应返回对应错误,资源接受记录和内容分发任务不应因该失败请求新增或覆盖;这能验证根平台没有把“请求可达”误当成“资源控制已证明”。
9.4 注册节点授权验证
注册服务节点授权检查的对象是基础设施节点资格,不是资源控制权。根平台应根据节点 DID、目标角色、授权 VC、授权域、DID文档稳定哈希、签发者和当前治理状态判断该节点是否有权提交相应资源。授权过期、撤销、角色不匹配或授权域不覆盖目标资源时,提交应被拒绝或进入隔离,不得因请求来自已知地址而放宽检查。
根平台的判断至少包含“节点是否仍处于可用治理状态”和“节点授权范围是否覆盖资源授权域”两步。前者处理节点被撤销、暂停或授权过期,后者处理注册服务节点只能代为接入部分资源域的情况。即使注册服务节点已经成功签发注册 VC,根平台仍应以当前授权状态重新判断是否接受发布;注册 VC 不能替代根平台的节点授权检查。
9.5 ResourcePackage 与哈希验证
根平台应按统一规范化规则重算 DID文档哈希、元数据哈希和资源包哈希,并检查哈希算法前缀、资源 DID、资源类型、包版本和嵌套字段之间的一致性。任一哈希不匹配、循环字段处理不一致或包内容与声明不一致,都属于完整性失败;失败材料可以保存为诊断记录,但不得进入可分发资源集合。
根平台成功重算后,会把资源 DID、资源类型、版本、三个哈希、生命周期和授权域组织为 packageClaims,并将根平台 proof 写入资源包的 rootProof。验证方应以这些声明与资源包实际字段的一致性作为判断依据;仅看到客户端提交的 packageHash,或者只比较字符串格式,都不足以证明资源包完整。
9.6 元数据与端点策略检查
策略检查用于判断已通过身份和完整性检查的材料是否适合进入网络发布链路。根平台应检查资源类型、能力标签、授权域、协议绑定、服务端点、生命周期和版本声明是否一致,并阻止私钥、访问令牌和不应公开的内部凭据进入公开资源材料。策略检查通过不代表端点业务质量已经得到保证,端点调用仍由调用方和资源服务共同完成授权。
策略检查的结果应与后续传播阶段分开记录。通过检查的材料可以进入根平台接受记录和内容分发任务;端点是否在线、内容分发平台是否完成托管、发现服务节点是否完成索引,则由后续服务分别确认。资源中若含有私钥、访问令牌或不应公开的内部地址,应在形成公开分发材料前拒绝或隔离,而不能依赖发现服务节点在索引阶段补救。
9.7 根平台可信发布证明签发
9.7.1 签发前提
根平台可信发布证明只能在提交来源、注册服务节点授权、资源控制证明、DID文档、三类哈希、资源版本和发布策略均通过检查后签发。证明签发前还应确认当前治理状态没有阻止该节点或该资源版本进入发布链路;待验证、待复核或分发失败不能直接转化为已发布。
9.7.2 证明内容
证明内容应至少绑定根平台 DID、资源 DID、资源类型、资源包版本、DID文档哈希、元数据哈希、资源包哈希、哈希算法、生命周期状态和签发时间。若证明包含授权域、发布游标或公告引用,也必须明确这些字段覆盖的是发布事实还是传播事实,不能混入资源控制方未声明的业务结论。
9.7.3 证明签名
根平台应使用自身受保护的签名密钥对规定的证明内容进行签名,并明确密码套件、签名覆盖范围和验证方法引用。签名验证方应先确认签发者属于信任的根平台,再核对签名输入是否与当前 ResourcePackage 完全一致;仅能解析 JSON 或看到根平台 DID 不足以证明签名有效。
9.7.4 证明获取与验证
资源提供方、内容分发平台和发现服务节点可以通过根平台发布接口、发布材料或关联地址取得证明。验证方应检查证明状态、目标资源 DID、版本、哈希、签发时间和根平台授权状态,并保留验证结果;证明取得成功不表示发现服务节点已经完成索引。
根平台可信发布证明应与一个确定的资源版本绑定使用。验证方至少应关联根平台 DID、资源 DID、包版本、DID文档哈希、元数据哈希、资源包哈希、proof 和验证时间;再次取得同一资源时仍需重新核对哈希和证明状态。注册服务节点签发的注册 VC、根平台可信发布证明和发现服务节点的索引记录分别证明不同阶段,不能互相替代。
9.8 发布序列与版本选择
9.8.1 发布序列
发布序列由根平台用于标识资源发布事实在分发链路中的先后位置。序列应保持单调推进并与资源 DID、资源版本、包哈希绑定;重复读取或重试同一发布任务不得产生新的逻辑发布事实,发现服务节点同步游标也不得被当作根平台发布序列。
9.8.2 同 DID 版本选择
同一资源 DID 的版本选择应结合资源包版本、前序版本关系、包哈希、控制证明和根平台发布序列判断。内容相同的重复材料可以幂等确认;内容不同但缺少有效控制证明或版本关系的材料应拒绝或隔离,不能按请求到达时间覆盖已有发布版本。
9.8.3 重复提交处理
根平台收到与既有资源 DID、包版本和包哈希完全相同的提交时,可以返回已有发布结果或重复提交状态,并保持原发布游标和证明不变。重复提交的处理记录仍应关联新的请求标识,便于审计和区分网络重试与真实版本更新。
9.8.4 冲突版本处理
同一 DID 下出现同版本不同哈希、同发布序列不同内容、前序版本不匹配或证明覆盖范围不一致时,应进入冲突或隔离处理,不得自动选择先到版本。根平台应保留冲突摘要和拒绝原因;只有控制方提交满足版本与控制条件的新材料后,才可重新验证。
排查版本问题时,应同时查看资源 DID、包版本、三个哈希、前序关系和发布游标,不能只按请求到达时间选择版本。发布游标是根平台发布记录在分发链路中的顺序证据,不是资源控制权,也不是发现服务节点的同步游标;发现服务节点即使看到游标推进,仍需校验具体资源包和根平台证明。
9.9 发布状态与拒绝原因
当前根平台成功响应的状态为 resource-verified-and-queued,表示资源已通过根平台处理并进入内容分发任务链路,不表示内容分发平台已完成发布。对外处理时至少应区分以下状态:
| 状态 | 语义 | 是否允许进入分发 | 失败或后续动作 |
|---|---|---|---|
| 待验证 | 已接收但必要检查尚未完成 | 否 | 查询处理结果 |
| 已验证并排队 | 资源验证完成,发布任务已建立 | 是 | 等待内容分发平台处理 |
| 已发布 | 发布事实已持久化且证明可验证 | 是 | 继续确认传播和索引 |
| 重复提交 | 相同 DID、版本和哈希再次到达 | 复用已有事实 | 返回既有结果 |
| 已拒绝 | 控制、授权、哈希或策略检查失败 | 否 | 修正材料后重新提交 |
| 待重试 | 外部发布链路暂时失败 | 使用已有任务 | 保留任务并按策略重试 |
拒绝原因应优先使用稳定代码,例如 registrar_not_authorized、did_document_hash_mismatch、metadata_hash_mismatch 和 package_hash_mismatch。控制证明无效、节点未授权和哈希不一致属于阻止发布的验证失败;事件投递失败或内容分发平台暂时不可用属于可恢复的后续失败,两者不能都只显示为“发布失败”。
9.10 内容分发准备
根平台接受资源后,会持久化资源包、发布任务和事件发布意图,并通过内容分发事件把任务交给内容分发平台。事件可以只携带资源 DID、包版本、发布游标、根平台 DID和哈希等可重放引用,由内容分发平台再向根平台取得资源包。当前设计通过事务性 outbox 使资源接受记录、发布任务和事件意图保持一致,事件发送失败时由 outbox relay 重试。
{
"jobKey": "did:oan:SKDM:example-resource:1.0.0",
"resourceDid": "did:oan:SKDM:example-resource",
"packageVersion": "1.0.0",
"publicationCursor": 123,
"rootDid": "did:oan:ROOT:example-root",
"packageHash": "sha256:<example-package-hash>",
"didDocumentHash": "sha256:<example-did-document-hash>",
"metadataHash": "sha256:<example-metadata-hash>"
}
事件被消息系统接受不等于资源已经完成内容发布。内容分发平台应在取得资源包、验证根平台 proof 和哈希、完成自身发布后确认任务;发现服务节点收到传播材料后,也应独立校验资源包和证明。
9.11 根平台发布审计轨迹
审计链应能从请求标识或任务键追溯到完整发布决定:注册服务节点提交了什么,根平台验证了哪些字段,资源包和哈希是什么,生成了哪个发布游标,是否创建内容分发任务,事件是否投递,以及任务最终如何处理。建议至少保留以下字段组:
| 字段组 | 典型字段 | 追溯用途 |
|---|---|---|
| 请求关联 | requestId、注册服务节点 DID、接收时间 |
定位一次上游提交 |
| 资源版本 | 资源 DID、packageVersion、三个哈希 |
固定被处理的材料 |
| 验证结果 | 控制证明、节点授权、策略检查结果 | 解释接受或拒绝 |
| 发布证据 | 根平台 DID、proof、publicationCursor |
证明根平台发布事实 |
| 分发状态 | jobKey、事件状态、重试次数、最后错误 |
追踪后续传播 |
审计记录可以保存摘要和引用,不应写入主体私钥、资源控制私钥、身份备份或访问令牌。公开资源字段和内部诊断字段应分开授权读取,避免审计接口成为敏感材料的旁路出口。
9.12 重新发布、回滚与恢复
分发失败时,优先重试同一资源 DID、包版本、哈希和任务键的发布任务,不要为重新发送而生成新的资源身份或把传输重试解释为新版本。数据恢复后,应先恢复根平台接受记录、发布任务和 outbox 状态,再重建未完成的事件投递。回滚到历史版本时,历史版本的 DID、版本、哈希和根平台证明仍对应原事实;如果资源内容发生变化,则必须重新生成控制证明、重算哈希并重新执行根平台验证。
分发失败
-> 保留原 jobKey、资源 DID、版本和哈希
-> 检查任务租约、重试次数和最后错误
-> 重新取得同一资源包并验证根平台证明
-> 内容分发平台成功后确认任务
-> 发现服务节点按发布游标继续同步
9.13 同 DID 更新授权与版本接受
同 DID 更新不能只比较版本字符串。根平台应确认新材料仍由当前控制关系授权,DID文档、资源元数据和资源包的哈希分别对应新材料,并能与已有版本建立前序关系。相同版本相同哈希应作为幂等重试处理;相同版本不同哈希应作为冲突处理;新版本若控制证明仍绑定旧文档哈希,应在接受记录写入前拒绝。
可复现的验收可以固定一个已接受的 v1,分别提交完全相同的 v1、哈希不同的 v1、带有效控制证明的 v2 和缺少前序关系的 v2。合格判据是:第一种不产生第二个逻辑发布事实,第二种不覆盖 v1,第三种进入新版本处理,第四种被拒绝或隔离,并且每种结果均能从请求、版本和哈希字段解释。
9.14 发布拒绝、隔离与重新处理
明确验证失败应直接拒绝并返回原因;材料暂时无法判定、依赖外部治理状态或需要复核时,才适合进入隔离。隔离记录应保留原始提交摘要、资源 DID、版本、哈希、注册服务节点、失败阶段和重新处理条件,但不得出现在内容分发清单或发现索引中。重新处理必须重新检查当前授权、控制证明有效期、哈希和治理状态,不能只把原状态改成“已发布”。
9.15 根平台发布状态机
9.15.1 待验证
待验证表示根平台已接收提交或发布任务,但尚未完成所有必要检查。该状态可以允许查询处理状态和诊断信息,不得进入可信分发清单,也不得被对外解释为注册成功、根平台已发布或发现可见。
9.15.2 验证通过
验证通过表示资源材料、控制证明、节点授权和发布条件已经通过根平台检查,但如果根平台证明尚未签发或发布记录尚未持久化,仍不能等同于已发布。该状态的转换应具有明确的提交标识、验证时间和证据引用。
9.15.3 已发布
已发布表示根平台已经形成与具体资源版本绑定的发布事实和根平台可信发布证明,并允许相关材料进入内容分发链路。该状态不表示内容分发平台已完成托管、发现服务节点已完成索引,或调用方已经获得业务调用许可。
9.15.4 已拒绝、隔离与恢复
已拒绝表示当前提交不满足必要条件;已隔离表示材料需要复核、补齐或等待外部状态变化;恢复处理必须重新检查当前授权、签名、哈希和治理状态。分发失败可以触发待重试,不应篡改原有资源版本或伪造新的根平台证明。 恢复时应以原提交的资源 DID、版本和材料摘要为关联依据,重新执行当前授权、控制证明、哈希和治理状态检查。只有重新验证通过,隔离材料才能回到发布流程;网络重试不得改变资源版本或生成新的根平台可信发布证明。根平台的“已发布”状态仍只表示已形成发布事实,不表示所有发现服务节点已经索引。
参考来源
| 来源 | 类型 | 链接 |
|---|---|---|
oan-root-services |
代码仓:根平台资源验证、发布证明和分发任务 | https://github.com/OpenAgenet/oan-root-services |
oan-registrar-node |
代码仓:注册服务节点上游提交和登记结果 | https://github.com/OpenAgenet/oan-registrar-node |
oan-protocol-common |
代码仓:资源包、证明和发布事件共享类型 | https://github.com/wolfbrother/oan-protocol-common |
| OAN Yellow Paper | arXiv 黄皮书:根平台、可信发布和安全边界 | https://arxiv.org/abs/2606.03163 |
| OAN Resource Identity and Discovery | IETF 草案:资源身份、发布和发现关联 | https://datatracker.ietf.org/doc/draft-xu-oan-resource-identity-discovery/ |