mirror of
https://github.com/whyour/qinglong.git
synced 2026-09-22 10:32:40 +08:00
137 lines
6.1 KiB
Markdown
137 lines
6.1 KiB
Markdown
# ADR-0189:Cluster Effective Publisher Trust Material Binding
|
||
|
||
- 状态:Accepted
|
||
- 日期:2026-07-28
|
||
- 关联:RFC D-175、D-177、D-178、D-179;
|
||
ADR-0185、ADR-0187、ADR-0188
|
||
|
||
## 背景
|
||
|
||
ADR-0188 已将 Cluster publisher trust 的有效代际保存在 PostgreSQL,并明确挂载文件只用于
|
||
初始化 base snapshot。但 recovery 进程仍直接用挂载文件中的全部 PEM 构造
|
||
`PluginPackagePublisherTrustRegistry`。这会形成控制面与执行面的 authority 分裂:
|
||
|
||
- operator 为 overlap rotation 预先分发 old+new ConfigMap 时,new key 会在 Approved
|
||
Action 推进 effective head 前被 recovery 信任;
|
||
- 数据库已经撤销或退役 key 后,旧 Pod/旧挂载仍可能继续把该 key 当作 verifier material;
|
||
- 管理面比较 base snapshot 不能约束独立使用 Package-executor credential 的 recovery Job。
|
||
|
||
必须先关闭这个缺口,才能安全实现正常 overlap-add 与 retirement。
|
||
|
||
## 决策
|
||
|
||
### 1. 文件是 material,PostgreSQL head 是 authority
|
||
|
||
publisher trust 文件继续保存公开的 Ed25519 PEM、publisher、key ID 和 lifetime。读取器对
|
||
文件大小、regular-file、只读权限、exact JSON shape 和全部 key 定义执行既有严格验证。
|
||
|
||
运行时新增纯绑定函数:
|
||
|
||
1. 从全部文件定义构造 canonical low-sensitive material snapshot;
|
||
2. 规范化 PostgreSQL 返回的 effective snapshot;
|
||
3. 对每个 effective key 精确匹配 publisher、key ID、public-key digest、not-before 和
|
||
not-after;
|
||
4. 只用匹配成功的定义构造 verifier registry;
|
||
5. effective key 缺材料、PEM 被替换、lifetime 漂移或 effective set 为空时失败关闭。
|
||
|
||
文件可以是 effective set 的真超集,因此允许先分发候选 key;额外 key 不进入 verifier。
|
||
|
||
### 2. stage authority 在数据库就绪后创建
|
||
|
||
`recoverClusterPluginPackages` 支持二选一:
|
||
|
||
- 调用方提供已构造的 `stageAuthority`;
|
||
- 调用方提供 `stageAuthorityFactory(pool)`。
|
||
|
||
两者必须且只能存在一个。factory 只在 Package-executor 数据库资源完成 schema/readiness
|
||
检查后调用;返回值立即执行同一 stage/verify contract 检查,并只在本次 recovery 周期内
|
||
使用。数据库仍由既有 one-shot composition 统一关闭,factory 不建立第二个 pool,也不让
|
||
repository 或 stage authority 逃逸。
|
||
|
||
生产 recovery 使用 factory:
|
||
|
||
1. 读取显式 `QL3_PLUGIN_PACKAGE_TRUST_AUTHORITY_ID`,默认 reviewed `cluster`;
|
||
2. 用现有只读 trust repository 查询 head 与 effective snapshot;
|
||
3. 将挂载 material 绑定为 effective registry;
|
||
4. 再构造 OCI stage authority。
|
||
|
||
因此 trust 查询、provenance recovery、stage 和 activation 共享一个最多 1 连接的
|
||
Package-executor pool,适合低资源单节点,也适合 HA writer endpoint。
|
||
|
||
### 3. 失败边界
|
||
|
||
以下状态必须在 OCI fetch、签名验证、Kubernetes 写入前失败:
|
||
|
||
- authority head 不存在;
|
||
- effective snapshot 在文件中缺少 exact material;
|
||
- public-key digest 或 lifetime 与 durable snapshot 不一致;
|
||
- 文件权限、大小、shape 或 key 类型不合法;
|
||
- database-bound factory 返回不完整 authority。
|
||
|
||
显式测试注入的 registry/stage authority 保留,用于无网络、无数据库的确定性测试;产品
|
||
部署不能通过环境变量选择绕过 durable head 的 registry。
|
||
|
||
### 4. 与 rotation/retirement 的关系
|
||
|
||
本 ADR 不新增 trust transition:
|
||
|
||
- overlap-add 后续采用 `old+new material` 预分发,再由受批 executor 推进 effective
|
||
`old → old+new`;
|
||
- retirement 后续采用 durable impact proof 与 generation fence 推进
|
||
`old+new → new`,随后才允许从文件清理 old material;
|
||
- emergency revoke 继续使用 ADR-0188 的 receipt/impact/quarantine 链。
|
||
|
||
正常 retirement 不能仅靠本次 recovery 启动时的 snapshot;后续 transition 必须在
|
||
provenance 写入和 head 推进处增加并发 fence。
|
||
|
||
## 包与资源边界
|
||
|
||
不新增 workspace package、migration 或生产依赖:
|
||
|
||
- `runtime-core` 保存纯 material/effective 绑定;
|
||
- `cluster-postgres` 复用现有 Package-executor 可读 trust repository;
|
||
- `cluster-admin` 在现有 recovery composition 内延迟构造 stage authority。
|
||
|
||
workspace 保持 22 包。没有新增 listener、timer、watcher、Service 或常驻 Pod;recovery
|
||
仍是显式 one-shot Job,数据库 pool 仍为 1 个连接。
|
||
|
||
## 不采用方案
|
||
|
||
### 文件 digest 必须等于 effective digest
|
||
|
||
这会禁止 old+new 候选材料预分发,并迫使 ConfigMap 更新与数据库审批形成不可实现的跨介质
|
||
原子提交。
|
||
|
||
### management 把 effective registry 推送给 executor
|
||
|
||
会把短生命周期 executor 依赖于管理进程可用性,并增加新的网络协议、身份和缓存一致性问题。
|
||
|
||
### recovery 启动前单独打开第二个数据库 pool
|
||
|
||
会增加低配设备连接开销,并让 trust 读取与实际 recovery 使用不同资源生命周期。
|
||
|
||
### 为 material binding 新拆 package
|
||
|
||
没有独立 Profile、credential、制品或第三方依赖边界,会违反 ADR-0185 的 package
|
||
收敛原则。
|
||
|
||
## 验收
|
||
|
||
- runtime-core 测试证明候选 key 被排除、exact durable key 可用、同 identity 替换 PEM
|
||
失败关闭;
|
||
- recovery composition 测试证明 factory 只在 readiness 后接收同一 pool,且数据库仍精确
|
||
关闭一次;
|
||
- Package recovery 配置与 base/CloudNativePG manifest 显式绑定 authority ID;
|
||
- 两套 Kustomize 渲染、deployment audit 与 dependency audit 无 finding;
|
||
- runtime-core 359/359;cluster-admin 111 pass、1 条真实 Kubernetes 条件 skip;
|
||
- PostgreSQL 18.4 arm64 physical HA 总门重跑 `gates.passed=true`,v38 Approved
|
||
Action、trust generation `1→2`、quarantine exact-once、timeline `1→2`、旧主
|
||
fence、`pg_rewind` 与同步只读重加入均无回归;
|
||
- workspace 仍为 22 包,无 migration、依赖或常驻资源增长。
|
||
|
||
## 后续
|
||
|
||
1. D-180 实现单 key overlap-add 与 safe-retire proposal/action。
|
||
2. retirement 在 signer provenance commit 与 trust-head transition 间增加 generation fence。
|
||
3. HA 门增加 old+new material 预分发、批准前拒绝、批准后接受和旧 key 安全退役证据。
|