mirror of
https://github.com/whyour/qinglong.git
synced 2026-09-20 16:07:11 +08:00
92 lines
4.2 KiB
Markdown
92 lines
4.2 KiB
Markdown
# ADR-0147:PostgreSQL 持久 Plugin Package 身份 keyset ledger
|
||
|
||
- 状态:Accepted
|
||
- 日期:2026-07-25
|
||
- 关联:ADR-0144、ADR-0145、ADR-0146、QL-RFC-0001 D-142/D-143
|
||
|
||
## 背景
|
||
|
||
ADR-0145 的文件式 keyset 已能在单进程生命周期内拒绝 generation 回退、同代
|
||
rewrite、隐式 key 移除和 revocation 撤销。但全部管理 Pod 同时重启后,进程内
|
||
monotonic state 会丢失;若部署投影回退到旧 Secret,旧签名 key 可能重新被接受。
|
||
|
||
不能用 watcher、timer、Redis 或 Pod 本地持久卷补这个缺口:它们分别引入额外常驻
|
||
资源、第二事实源或副本不一致,并不能与现有 PostgreSQL HA 故障域共同收敛。
|
||
|
||
## 决策
|
||
|
||
### 1. 单一持久 trust ledger
|
||
|
||
`pg-0024-plugin-package-identity-keyset-ledger` 新增
|
||
`ql3.plugin_package_identity_keyset_ledger`,固定只有
|
||
`plugin-package-management` 一个 authority。行内保存:
|
||
|
||
- generation 与完整 keyset SHA-256 base64url digest;
|
||
- immutable issuer/audience;
|
||
- 最多 8 个 active key ID;
|
||
- 最多 64 个 append-only revoked key ID;
|
||
- 数据库时钟更新时间。
|
||
|
||
migration stream 推进至 24 条、`control-core` capability v23、37 张表,并新增
|
||
`plugin_package_identity_keyset_ledger:1`。
|
||
|
||
### 2. 原子单调推进
|
||
|
||
`PostgresPluginPackageIdentityKeysetLedgerRepository.observe()` 使用同一
|
||
package-manager 连接池的短事务:
|
||
|
||
1. `INSERT ... ON CONFLICT DO NOTHING` 竞争首次建账;
|
||
2. `SELECT ... FOR UPDATE` 串行化同一 authority;
|
||
3. 同 generation 只接受 digest、trust domain、active/revoked 集合完全一致的重放;
|
||
4. 新 generation 必须保持 issuer/audience 不变;
|
||
5. 历史 revoked key 必须全部保留;
|
||
6. 历史 active key 必须仍 active,或显式进入 revoked;
|
||
7. 通过后才以数据库时钟更新并提交。
|
||
|
||
COMMIT 响应丢失统一返回 unavailable;调用方以同一 snapshot 重试会读取已提交行并
|
||
精确收敛,不产生新 generation。
|
||
|
||
### 3. 认证路径复核
|
||
|
||
生产 management process 先完成 package-manager schema/role readiness,再创建带
|
||
PostgreSQL ledger 的 keyset file provider。首次启动、文件发生变化和文件 digest
|
||
未变化的每次认证 reload 都必须调用 ledger:
|
||
|
||
- 新副本拿到旧文件时在监听前失败关闭;
|
||
- 已运行副本在 ledger 被另一副本推进后,不得继续把旧进程内 verifier 当持久事实;
|
||
- 文件损坏、数据库不可用、ledger conflict 均映射为 keyset unavailable,不使用
|
||
stale fallback。
|
||
|
||
基础 file provider 保留可选 ledger port,供纯单元测试或非生产组合使用;正式
|
||
cluster process 永远注入 PostgreSQL 实现。
|
||
|
||
### 4. 权限和资源边界
|
||
|
||
- 只有 `ql3_package_manager` 可 `SELECT/INSERT/UPDATE` ledger;
|
||
- runtime、admin、package-executor、worker-ingress 与 PUBLIC 均无权限;
|
||
- 不新增 workspace package、第三方依赖、Redis、timer、watcher 或后台清理;
|
||
- edge/standalone 不导入该 repository,仍保持零额外常驻成本;
|
||
- 表恒定一行,revocation 列表与 JSON 字节数均有硬上限。
|
||
|
||
## 验证
|
||
|
||
- cluster-postgres 全量 141/141;
|
||
- cluster-admin 全量 97 通过、1 个真实 Kubernetes API 条件跳过;
|
||
- PostgreSQL 18.4 arm64 physical HA 报告新增
|
||
`durableIdentityKeysetLedgerSurvivesReplicaRestart`:
|
||
- 两个独立 package-manager 实例并发观察同一 generation;
|
||
- 新 repository 实例模拟全副本重启,旧 generation 被拒绝;
|
||
- 同代 rewrite、隐式移除和 trust-domain 漂移被拒绝;
|
||
- driver 已确认 COMMIT 后注入响应丢失,再次观察精确收敛到 generation 3;
|
||
- ledger 与既有 quota、physical promotion、`remote_apply`、旧主 fencing/rewind
|
||
一起通过 24 个具体 gate 和总 `passed`。
|
||
|
||
## 后续非本 ADR 范围
|
||
|
||
本 ADR 关闭“全副本重启后的 durable keyset anti-rollback”阻断项,但不自动开放公网
|
||
管理入口。真实 IdP 两名 User 四眼、双 Pod live NetworkPolicy/ingress、Secret 投影
|
||
传播窗口、TLS/keyset 自动轮换和真实 Kubernetes control-plane HA 证据仍是生产前置。
|
||
|
||
ADR-0148 已冻结这些真实环境事实的低敏 evidence schema,并默认拒绝 management
|
||
公网 egress;它不把“审计器存在”当作真实报告已经取得。
|