The original design spec content lives entirely in the numbered harness docs; the file itself is recoverable from the initial commit. Drop it from agent-context routes and fix all doc references. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
9.6 KiB
9.6 KiB
架构设计
系统结构、职责边界、数据模型与发布流水线。协议字段以 api.md(权威源
soft_quay仓库)为准。
一、信任模型(一切设计的出发点)
客户端 soft_quay 对远端内容的信任仅来自 Ed25519 签名:
soft_quay_web(持私钥) soft_quay 客户端(内置公钥)
───────────────────────── ─────────────────────────
用受限规范 JSON + 私钥签名 ──► 拉取 → 去掉顶层 signature → 同规则规范化
生成 manifest-modern/win7.json → Ed25519 验签 → Schema/channel/架构过滤
上传对象存储 / CDN(HTTPS) → 缓存;验签失败则拒绝、退回上次可信缓存
包 url/size/sha256 写入清单 → 下载 → 同句柄 size→SHA-256→安全解压
由此推出的硬性要求:
- 规范化必须字节级一致:发布端与客户端对同一 JSON 输入必须产出逐字节相同的规范字节与签名;共用
canonical-vectors.jsoncorpus 作为跨实现回归基线,发布端不得自举期望值。 - 私钥保管是最高安全目标:私钥泄露 = 可伪造任意清单 / 包记录 / 许可证 = 客户端全线沦陷。
- 客户端不做在线校验:下架、撤销、版本兼容都必须能"离线表达"在签名文件里(status 字段、签名撤销名单 + 宽限期)。
二、组件与职责
┌─────────────────────────────────────────────┐
子软件 app-* CI │ 构建标准 ZIP 包 + Release 元数据 │
└───────────────┬─────────────────────────────┘
│ 上传候选包
▼
┌──────────────────────────────────────────────────────────────┐
│ soft_quay_web │
│ ┌────────────┐ ┌────────────┐ ┌──────────────────────┐ │
│ │ Ingestion │──►│ Registry │──►│ Manifest Generator │ │
│ │ 包接收校验 │ │ 元数据/发布 │ │ 双通道清单组装 │ │
│ └────────────┘ │ 记录 (DB) │ └──────────┬───────────┘ │
│ │ └────────────┘ │ 待签名规范字节 │
│ │ size/SHA-256 ▼ │
│ │ ┌──────────────────────┐ │
│ │ │ Signing Service │ │
│ │ │ (Ed25519 私钥,隔离/ │ │
│ │ │ KMS/HSM,受限接口) │ │
│ │ └──────────┬───────────┘ │
│ ▼ ▼ │
│ ┌────────────┐ ┌────────────┐ ┌──────────────────────┐ │
│ │ License & │ │ Web 管理端 │ │ Publisher (发布器) │ │
│ │ Revocation │ │ (UI) │ │ 上传对象存储/CDN │ │
│ └────────────┘ └────────────┘ └──────────┬───────────┘ │
│ │ 审计日志 (append-only) │ │
└────────┼──────────────────────────────────────┼──────────────┘
▼ ▼
审计/合规存档 对象存储 / CDN(静态托管)
│ HTTPS
▼
soft_quay 客户端
| 组件 | 职责 | 不含 |
|---|---|---|
| Ingestion | 接收子软件 CI 的 ZIP 候选包;校验包协议结构(app.json/files.json/payload)、计算 size 与 SHA-256、比对声明版本/ID/架构 | 构建子软件、跑子软件业务 |
| Registry | 软件元数据、发布记录、包坐标(url/size/sha256)、status、channel、Catalog 版本 | 子软件源码、客户端状态 |
| Manifest Generator | 从 Registry 按 channel 组装双通道清单,产出待签名规范字节 | 签名(委托签名服务) |
| Signing Service | 唯一持有 Ed25519 私钥;只对清单/许可证/撤销名单三类受控结构签名 | 业务逻辑、任意数据签名 |
| License & Revocation | 绑定 machine_hash + products 签发许可证;维护签名撤销名单 + 宽限期 | 保存原始硬件序列号/MAC |
| Publisher | 签名清单、ZIP 包、图标上传对象存储/CDN;保证原子发布(先包后清单) | 生成未签名/未校验产物 |
| Web 管理端 | 发布者操作界面与编排;签名经受控接口调用 | 直接持有私钥 |
| Audit | append-only 记录每次发布/下架/撤销/签发 | 可被覆盖的可变日志 |
关键边界
- 签名服务是唯一持钥点:其余组件(含 Web 后台)只能提交"受限结构 + 请求签名",拿回签名串,拿不到私钥。
- Web 管理端不等于签名端:私钥不进 Web 进程。
- 协议 Schema / corpus 单一权威源:引用
soft_quay/schemas/与canonical-vectors.json,CI 校验发布端产物能被同一份 corpus 与 Schema 通过。
三、数据模型(建议,W-201 定稿)
首期里程碑(协议对齐)不需要数据库;下面是 Registry 落地时的起点草案,定稿后更新本节并删除"建议"标注。
Software 1 ──── * Release 1 ──── * PackageArtifact
│ │
│ └──── * AuditEvent(所有实体的操作都产生)
└ id 永久稳定
License * ──── RevocationEntry(按 license_id 撤销)
| 实体 | 关键字段 | 说明 |
|---|---|---|
| Software | id(永久稳定)、name、description、category、tags、icon(sha256)、homepage、tutorial、entry_exe、requires_admin、status |
客户端列表页唯一来源;一行对应清单里一个 app |
| Release | software_id、version(SemVer)、channel(modern/win7)、min_os、architectures、created_at、catalog_version | 一次版本发布;同 software 同 channel 只有一个 active release 进清单 |
| PackageArtifact | release_id、arch(386/amd64)、url、size、sha256、signature、ingested_at | 来自 Ingestion 的校验结果;url 为发布后的绝对 HTTPS |
| License | license_id、machine_hash、products[]、issued_at、perpetual、update_policy、rebind_policy | 不保存原始硬件标识 |
| RevocationEntry | license_id、revoked_at、reason 摘要 | 进入签名撤销名单 |
| AuditEvent | actor、action、target、content_digest、signature_fingerprint、at | append-only,不可修改 |
四、发布流水线
子软件 CI 产出标准 ZIP 包 + Release 元数据
→ Ingestion 校验包结构 / app.json 一致性 / 计算 size + SHA-256
→ Registry 登记发布记录(url 坐标、status、channel、Catalog 版本)
→ Schema 校验(manifest/app schema)
→ Manifest Generator 组装 modern/win7 待签名规范字节
→ Signing Service 用 Ed25519 私钥签名
→ CI 用 canonical-vectors corpus + Schema 回归验证产物
→ Publisher 原子上传:先传 ZIP 包/图标到对象存储,再切换签名清单
→ soft_quay 客户端发现新版本
- 一个产品可产出多目标(如
json-parser_1.4.2_windows_amd64.zip、..._win7_amd64.zip);只生成实际支持并测试过的目标。 - 原子性:包必须先于清单可用,避免客户端拿到指向尚未上传包的清单。
五、签名与密钥管理
- 私钥隔离:理想部署为 KMS/HSM 或独立最小权限签名服务;Web 后台与业务进程只经受控接口请求签名,不接触私钥材料(保管方案 W-003 裁定)。
- 只签受控结构:清单 / 许可证 / 撤销名单;不对任意字节签名。
- 公钥分发:客户端内置公钥;测试用公钥见 corpus。正式公钥的内置与更新方式随密钥轮换设计裁定(Backlog,需客户端协议升级)。
- 签名审计:每次签名请求记录操作者、目标结构摘要、时间、密钥指纹。
六、版本 / 协议兼容管理
| 版本类型 | 示例 | 用途 |
|---|---|---|
| 产品版本 | 1.4.2 | 用户看到的软件版本 |
| SDK 版本 | sdk/core v1.2.0 | 公共能力兼容性 |
| 软件包协议 | schema_version 1 | 盒子与包的结构协议 |
| Catalog 版本 | 2026.07.16.1 | 目录发布时间 |
原则:SDK 升级不强迫历史软件立即升级;盒子至少兼容当前与前一个包协议版本;清单顶层 min_box_version 声明所需最低盒子版本。
七、开发顺序
见 任务路线图:Phase 0 裁定与骨架 → Phase 1 协议对齐核心(最高风险先行)→ Phase 2 登记与本地模拟发布闭环 → Phase 3 签名隔离与正式发布 → Phase 4 许可证与撤销 → Phase 5 Web 管理端与审计。