Skip to content

XHIM 商业发布供应链证据

本文说明 XHIM 的离线 SBOM、依赖许可证策略、法务批准和制品 Hash 绑定流程。 它是发布工程说明,不是法律意见,也不会替任何版本预先批准依赖。

默认结论

仓库模板永远不是正式证据:

  • compliance/legal-approval.template.json 保持 not_reviewed
  • server/load/capacity-evidence.template.json 保持 not_run
  • 许可证策略中的 manual_review 必须由该版本的真实法务记录逐项批准;
  • denied 依赖不能通过人工批准绕过;
  • SBOM 只描述传入的不可变制品目录,不会把源码树冒充发布制品。

可以随时执行模板防误报检查:

bash
python3 scripts/release/validate_commercial_templates.py .
cmake -P cmake/ValidateCommercialEvidence.cmake

1. 离线收集许可证证据

先在受控构建机上准备与 server/go.sum 完全一致的 Go Module Cache。正式收集 时脚本强制 GOPROXY=offGOSUMDB=offGOWORK=off,不会从网络补下载; 缺少任一 Module 时会直接失败。

输出目录必须不存在,避免新旧版本证据混合:

bash
evidence_root=/absolute/path/to/xhim-release-evidence

python3 scripts/compliance/collect_licenses.py \
  . "${evidence_root}/licenses" \
  --policy compliance/license-policy.json

输出包括:

  • third-party-inventory.json:统一的 Go、Native 和 UI Asset 清单;
  • third-party-licenses/:实际发现并复制的许可证或 NOTICE 原文;
  • XHIM-LICENSE.txtXHIM-NOTICE.txtnative-dependencies.json
  • 每份原文、策略文件和来源文档的 SHA-256。

每个依赖都有稳定 ID、实际版本、许可证表达式、证据文件 Hash 和以下状态之一:

  • allowed:表达式中的每个许可证都在允许列表;
  • manual_review:未知、弱 Copyleft、平台选择版本、缺少原文或被明确要求复核;
  • denied:商业发布策略禁止,发布门禁无条件失败。

轻量文本识别只是 fail-closed 的清单辅助,不替代法务判断。无法可靠识别时会 生成 NOASSERTION 并进入人工复核,不会猜测成允许。

2. 填写该版本的法务批准

复制 compliance/legal-approval.template.json 到证据目录,并填写真实版本、 完整 40 位 Commit、法务主体、时区明确的复核时间和工单编号。以下 Hash 必须 来自本次生成的证据,不能沿用旧版本:

bash
shasum -a 256 \
  "${evidence_root}/licenses/third-party-inventory.json" \
  compliance/license-policy.json \
  "${evidence_root}/licenses/XHIM-NOTICE.txt" \
  "${evidence_root}/licenses/XHIM-LICENSE.txt"

对清单里每个 manual_review 条目,在 dependency_reviews 中使用相同依赖 ID 记录 approvedrejected,并提供非占位的外部法务证据编号。验证命令:

bash
python3 scripts/compliance/verify_legal_gate.py \
  "${evidence_root}/licenses/third-party-inventory.json" \
  "${evidence_root}/legal-approval.json" \
  --version 1.2.3 \
  --commit 0123456789abcdef0123456789abcdef01234567 \
  --policy compliance/license-policy.json

验证器会重新读取许可证证据、来源文档和策略文件,逐个复算 Hash。清单被改动、 证据缺失、未知复核项、占位审批、无时区时间、拒绝项或禁用许可证都会失败。

3. 为发布制品生成可重复 SBOM

artifact_root 必须是已经签名、打包完成且不再改动的五端发布制品目录;SBOM 输出必须位于该目录之外。生成时间固定使用 Git Commit 时间,保证相同输入得到 逐字节相同输出:

bash
artifact_root=/absolute/path/to/xhim-artifacts
commit=0123456789abcdef0123456789abcdef01234567
version=1.2.3
created_epoch="$(git show -s --format=%ct "${commit}")"

scripts/release/generate_sbom.sh \
  "${artifact_root}" "${evidence_root}/sbom" \
  --inventory \
  "${evidence_root}/licenses/third-party-inventory.json" \
  --version "${version}" \
  --commit "${commit}" \
  --created-epoch "${created_epoch}"

脚本完全离线并生成:

  • xhimsdk.spdx.json:SPDX 2.3;
  • xhimsdk.cdx.json:CycloneDX 1.5;
  • xhimsdk.sbom-link.json:源码、制品文件集、许可证清单和两份 SBOM 的 Hash 链接。

制品目录中的每个普通文件都会记录安全相对路径、大小和 SHA-256。符号链接、 特殊文件、空制品目录或生成期间发生变化的文件都会失败。独立验证:

bash
python3 scripts/release/verify_sbom.py \
  "${evidence_root}/sbom/xhimsdk.spdx.json" \
  "${evidence_root}/sbom/xhimsdk.cdx.json" \
  "${evidence_root}/sbom/xhimsdk.sbom-link.json" \
  --artifact-root "${artifact_root}" \
  --inventory \
  "${evidence_root}/licenses/third-party-inventory.json" \
  --version "${version}" \
  --commit "${commit}"

验证器要求三份文档使用规范化、确定性 JSON,并重新计算制品文件集、依赖集合、 清单和文档 Hash。生成后改动任一制品、许可证清单或 SBOM 都会让验证失败。

4. 正式商业门禁

正式稳定版使用 scripts/release/commercial_gate.sh。它要求干净且经过版本身份 校验的 Git Checkout、外部五端制品、设备证据、真实法务批准、真实容量证据和 配置好的 GPG 发布密钥。脚本从同一只读制品快照完成签名校验、许可证、SBOM、 安全扫描、真机矩阵、容量回执、总证据清单和最终复核。

正式门禁有意拒绝复用已有输出目录。失败后保留原始输入用于分析,但应使用新的 空证据目录重新发布,不能删除单个失败文件后拼接结果。

离线回归测试:

bash
python3 -m unittest \
  scripts.release.tests.test_supply_chain_gates \
  scripts.release.tests.test_commercial_evidence_gates

这些测试使用本地 Fixture 验证确定性和负例,不会产生法务意见、容量分数或可 销售声明。

XHIM 客户端 SDK 与服务端文档