feat(ql3): establish 3.0 incubation baseline

This commit is contained in:
whyour
2026-08-12 00:25:26 +08:00
parent 4bf92dcfeb
commit c699c32461
2817 changed files with 779642 additions and 653 deletions
@@ -0,0 +1,94 @@
# ADR-0245Worker 管理外部 OIDC 双用户 Ceremony 证据
- 状态:Accepted(证据协议、runner 与离线审计器已实现;真实外部报告待采集)
- 日期:2026-08-01
- 关联 RFCQL-RFC-0001 D-58、D-226、D-228、D-229
- 关联 ADRADR-0148、ADR-0242、ADR-0244
## 背景
ADR-0244 已让 Worker Credential management 使用独立 JWT type/purpose,并由进程级、
PostgreSQL HA 和三节点 K3s fixture 证明生产装配。但 K3s fixture 的两名强 User assertion 由仓库内
确定性密钥签发,不能证明真实外部 IdP、真实不同人员或生产身份策略。
直接把原始 assertion、subject、session ID 或管理响应存为“证据”会扩大凭据与个人身份数据暴露;
直接执行 credential delivery 又会把身份验证与 Secret mutation 混成一个不可独立复核的门。
## 决策
1. 新增 caller-driven `ql3-worker-credential-management-live-ceremony.cjs`。它只允许固定顺序:
requester `plan` → requester `propose` → requester `decide` 必须 403 → reviewer `decide`
reviewer `inspect`。runner 不接受 operation 参数,也没有 `execute`、TokenRequest 或 delivery 路径。
2. requester/reviewer assertion 必须来自同一个 canonical 外部 HTTPS issuer、拥有不同 User subject
并精确绑定:
- `aud=qinglong3-worker-credential-management`
- `typ=ql3-worker-credential-management+jwt`
- `ql3_purpose=worker-credential-management`
- 有界 lifetime/authentication age、非 `none` algorithm、canonical compact encoding。
3. runner 在任何管理 mutation 前读取 OIDC discovery/JWKS,并复用生产 Worker management client 的
TLS 1.3、CA/servername、canonical file、body/response/timeout 与 exact result validation。manager
对两枚 assertion 的真实签名、keyset、assurance 和 Policy 验证仍是最终认证 authorityrunner
的 envelope 检查不是签名验证替代品。
4. ceremony 输入是 mode 0600 的 exact-shape 文件。所有 identifier 与 plan request 在首个网络请求前
通过 production transport normalizerrequester/reviewer decision identity 必须不同。只接受新建
`pending@1` approval,避免把已有决定误写为本次现场证据。
5. 输出使用 `qinglong/worker-credential-management-live-ceremony@v1`,写入 unused canonical mode
0600 文件。只保留外部 issuer、discovery/JWKS SHA-256、domain-separated subject/key/request/project/
action 摘要、plan/preview digest、五步状态和 `dispatchCreated=false`
`approvalConsumed=false`;禁止 assertion、JWT、Authorization、Secret、token、DSN、password 或私钥。
6. 独立 audit CLI 只读验证 exact report shape、外部 issuer、Worker profile、不同 subject digest、
五步状态、未 dispatch/consume、全 true gate 与敏感材料扫描。runner 自审通过后才原子 no-replace
写报告;没有真实报告时发布门仍未完成。
7. 该能力只增加两个短生命周期脚本和一个根级命令,不新增 workspace package、第三方依赖、
migration、数据库角色、镜像、listener、timer、watcher、controller 或 sidecar。Edge/Standalone/
Worker 常驻闭包不导入它。
## 失败与恢复
- OIDC discovery/JWKS、TLS、认证、self-deny、reviewer decision 或 inspect 任一步失败都不生成报告;
- `plan/propose` 已 durable 后失败时,operator 必须先 inspect。若 approval 仍为 `pending@1`,可用同一
immutable ceremony 继续;若已决定,则本 runner 拒绝把它包装为新现场证据,应创建新的无执行
ceremony identity
- 主请求不做业务自动重试。生产 client 的无响应语义仍要求 durable inspection;缺少响应不能解释为
rollback
- 输出路径不可覆盖,防止把两次不同现场证据混为一份报告。
## 被拒绝的替代方案
### 把 K3s 自签 token 标为外部 IdP
拒绝。它只能证明协议与部署 wiring,不能证明外部 issuer、人员分离或生产 IdP policy。
### 接受一个 assertion 并在客户端改 subject
拒绝。subject 是 issuer 签名事实;客户端改写既不能通过签名,也不能证明两名人员。
### Ceremony 顺便 consume approval 或执行 delivery
拒绝。身份/职责分离证据不应产生 Worker credential、Kubernetes token 或 Secret mutation。执行证据由
ADR-0242 的独立 caller-driven executor gate 负责。
### 将原始 subject、JTI、request ID 或 assertion 写入报告
拒绝。这些值对离线合规判断没有必要,且会扩大个人信息、会话关联和 credential 泄漏面。域分离
摘要足以证明同份报告内部的不同身份与请求链。
## 验证
- runner/audit 7/7:外部双 User happy path、自批被错误接受时失败关闭、same-user、错误 purpose、
`.test` issuer、过期/Plugin-type assertion、宽权限/symlink/已存在输出文件、widened/false-gate/敏感
报告、五个 path-only CLI 参数;私有读取使用 `O_NOFOLLOW` 与 descriptor 前后 stat
- happy path 明确观测五个 operation,零 `worker-credential.execute`,输出 mode 0600,并由独立 audit
子进程再次判定 `compatible=true`
- production client/transport 的 Cluster Admin 全量回归为 177 pass、0 fail、1 条真实 Kubernetes API
条件 skip,继续覆盖 TLS 1.3、远端错误、exact response 和四个公开 operation
- 根 back/legacy 全量回归为 881 pass、0 fail、2 条平台条件 skipdependency、deployment、Edge
audit 均 `compatible=true``findings=[]`workspace importer 保持 19。
## 尚未完成
- 在真实外部 IdP 与生产等价 manager endpoint 上采集一份 mode 0600 report,并由 audit CLI 通过;
- 按 ADR-0246 用部署侧短期、exact SELECT-only PostgreSQL evidence role 采集 proposal/decision durable
security auditcollector/audit 协议已实现,真实报告仍待采集;
- 外部 client certificate 的运行时/客户端/Kubernetes 协议已由 ADR-0247 补齐;生产 PKI、生产 ingress、
证书或 IdP 身份撤销后的新请求失败关闭仍需现场证据,不能由本报告推导。