qpm 静态 registry v2(local/static,可选签名)
English summary. Static registry v2 layout:
index.json(v2 schema), optionalindex.json.sig,CHECKSUMS,packages/<name>/<version>.tar.gz; static HTTP hosts are read-only, publish/yank run from a local directory. There is no hosted registry service or production signature service; publishing/yanking requires a local writable checkout. Seedocs/ENGLISH_SUMMARIES.mdfor the English index; the Chinese text below is authoritative.
状态:alpha / 候选能力(qpm 0.5-alpha 文档,Q+ 1.4.8-dev 候选;语言树 CLI 版本串
0.3.0-alpha.1)。registry 仍是 纯静态目录/静态主机;本版本新增 v2 index 结构 + detached 签名 + vendor/offline 校验流程。没有中心化 registry 服务,也不声称生产签名基础设施。
1. 目录布局(不变)
<registry>/
├── index.json # 索引(v2 推荐;v1/vendor 样式仍可校验)
├── index.json.sig # 可选:index.json 的 detached 签名(qpm sign 生成)
├── CHECKSUMS # 可选:verify-index --write-checksums 生成
└── packages/<name>/<version>.tar.gz
静态 HTTP 主机只读;publish/yank 仍需本地目录。QPM_REGISTRY / --registry / 清单 [registry].url(s) 的优先级不变。
2. v2 index schema
{
"schema": "qpm-registry-v2",
"registry_version": 2,
"updated_at": "2026-10-30T00:00:00Z",
"entries": [
{
"name": "acme-lib",
"version": "1.0.0",
"url": "packages/acme-lib/1.0.0.tar.gz", // 相对 registry 或绝对 URL
"sha256": "<archive 的 64-hex SHA-256>",
"signature": "<可选:per-entry detached 签名 base64(canonical JSON 去除 signature 字段)>",
"meta": {"description": "...", "dependencies": {"x": "^1.0.0"}}
}
]
}
- 必填:
name、version、url、sha256;signature/meta可选。 - v1 兼容:
{"registry_version": 1, "packages": {name: {versions: {...}}}}仍可被qpm verify-index校验(archive 校验优先用archive_sha256, 缺省回退sha256)。 - vendor 快照由
qpm vendor生成,采用 v1 packages 结构 +VENDOR_MANIFEST_NAME。
3. 校验语义(qpm verify-index)
qpm verify-index index.json # 结构 + 本地可解析 archive 的 checksum
qpm verify-index index.json --vendor . # 以 vendor 目录解析 archive
qpm verify-index index.json --sig index.json.sig --pubkey pub.pem # 校验 index 签名
qpm verify-index index.json --vendor . --pubkey pub.pem --strict --write-checksums
qpm verify-index index.json --json # 机器可读报告
- index 签名:
--pubkey时验证--sig(默认<index>.sig);缺失/无效 loud FAIL; 有--sig但无--pubkey也 loud FAIL(不做“看起来验过”的假象)。 - 包 checksum:对可本地解析的 archive 逐个比对
sha256;不一致 loud FAIL。 - 缺 archive:默认计为
missing(报告);--strict时 loud FAIL。 - per-entry 签名(可选):
signature存在且有--pubkey时校验;失败 loud FAIL。 - CHECKSUMS:
--write-checksums在 vendor 目录写CHECKSUMS(index + 各 archive 的 sha256 行);可用qpm sign CHECKSUMS --key ...进一步签名。 - 输出摘要:
INDEX_VERIFY: OK (... entries; signature: verified)+checksums: ok=/missing=/tampered=/unsigned=。
4. 签名 registry / vendor 流程
# 1) registry index 签名(发布方本地执行)
qpm keygen --out keys --alg ed25519
qpm sign registry/index.json --key keys/key.pem # -> index.json.sig
# 2) 使用方离线校验
qpm verify-index registry/index.json --vendor registry \
--sig registry/index.json.sig --pubkey keys/pub.pem
# 3) vendor 快照(可选签名)+ 离线安装
qpm vendor ./vendor --sign-key keys/key.pem
qpm verify-index vendor/index.json --vendor vendor --pubkey keys/pub.pem
qpm install --vendored vendor
qpm update --registry <本地目录> --sig <sig> --pubkey <pub> 刷新缓存并顺带验签; 远程(http)index 不能按路径验签,会 loud 提示改用下载副本 verify-index。 qpm audit / qpm verify --vendored 仍做 lock/installed/vendor/registry checksum 审计。
5. 错误路径(均非零退出)
| 场景 | 诊断 |
|---|---|
| index 被改 | SIGNATURE_INVALID(index 签名) |
| archive 与 index sha256 不符 | INDEX_VERIFY_FAILED ... checksum mismatch |
| 有签名但无公钥 | VERIFY_KEY_MISSING |
缺 archive + --strict | ... archive not found locally |
| entry 签名被改 | ... entry signature invalid |
| 无 OpenSSL 时签名相关操作 | SIGNING_UNAVAILABLE |
| index 结构非法 | INDEX_INVALID |
6. 边界(明确非目标)
- 不提供中心化 registry/服务端、账号/权限、在线吊销、时间戳或证书体系;
- 不承诺“生产签名基础设施”;仅本地/静态目录 + detached 签名与 checksum 校验;
- 私有路径/主机/密钥不进入仓库;测试使用临时材料(
TMPDIR)并清理; - v2 schema 为 alpha,后续可能演进(会写入 CHANGELOG)。
7. 测试
bash tools/test_qpm_registry_v2.sh:v2 index 签名+checksum PASS、CHECKSUMS、 篡改 archive/index/entry 的 loud FAIL、v1 兼容与 --strict、qpm vendor --sign-key → verify-index 离线验证、篡改 vendor archive loud FAIL;无 OpenSSL 分支显式 SKIP。