mirror of
https://github.com/whyour/qinglong.git
synced 2026-09-20 16:07:11 +08:00
80 lines
5.6 KiB
Markdown
80 lines
5.6 KiB
Markdown
# ADR-0253:私密 Worker 管理证据的镜像发布门
|
||
|
||
- 状态:Accepted(workflow、freshness gate、静态审计与负向测试已实现;生产 JIT runner 成功记录待取得)
|
||
- 日期:2026-08-01
|
||
- 关联 RFC:QL-RFC-0001 D-235、D-236
|
||
- 关联 ADR:ADR-0128、ADR-0196、ADR-0252
|
||
- 后续修订:ADR-0425 已把本 ADR 的私有 Worker evidence gate 收窄到 `cluster|all` 发布族;`local` 发布不得等待该证据,Cluster 的 source/freshness/private-runner 约束继续有效。
|
||
|
||
## 背景
|
||
|
||
D-235 已能用 final report 与四份 source 独立重判 Worker management 的 external ceremony、durable audit、leaf
|
||
revocation 和 client CA rollover,但镜像发布 workflow 尚未消费该结论。直接接入存在四类风险:
|
||
|
||
- 把 source 上传为 GitHub artifact/cache 会复制受限生产证据并扩大 retention 与读取主体;
|
||
- 只上传低敏 final 后检查 `passed=true` 会丢失 D-235 的 source-aware 重判能力;
|
||
- tag push 自动发布会绕过生产证据准备、双人复核和受保护 environment;
|
||
- 在 GitHub-hosted builder 上读取 source,会把生产证据与 registry/OIDC 写 authority 放进同一安全域。
|
||
|
||
## 决策
|
||
|
||
1. `.github/workflows/ql3-image-release.yml` 只接受显式 `workflow_dispatch`。dispatch 必须选择 exact protected
|
||
`v3` tag,输入 version 必须与 tag 名完全一致;普通 branch、自动 tag push、PR 和 schedule 均不能发布。
|
||
2. 发布前增加唯一 `worker-management-release-evidence` job。它固定运行在带
|
||
`ql3-release-evidence-ephemeral` 标签的 Linux self-hosted JIT runner,并受
|
||
`ql3-production-release-evidence` environment reviewer 保护。标签只是调度条件;真正的隔离必须由 runner
|
||
provisioner 保证每个 job 一次注册、一次执行、随后销毁。
|
||
3. 私密文件由 runner provisioner 以当前 runner UID、canonical `0700` 目录和 `0600` regular file 预挂载到
|
||
`/run/qinglong3-release-evidence/$GITHUB_SHA`。文件名固定为 final、ceremony、durable、PKI v2 和 CA rollover
|
||
五个名称;workflow 不接受用户提供的路径、目录扫描、glob、URL 或 artifact download。
|
||
4. gate 重新执行 D-235 source-aware auditor,并额外要求 final `observedAt` 不超过 24 小时、不得比 runner clock
|
||
超前 5 分钟。成功摘要只包含 fixture、commit、version、final SHA-256 和最大年龄,不输出 source 内容。
|
||
5. workflow 顶层和 evidence job 只有 `contents:read`。GHCR、OIDC、attestation 与 artifact-metadata 写权限只授予
|
||
`publish` job,且 `publish` 必须无条件 `needs: worker-management-release-evidence`。证据 job 失败、超时、未获
|
||
environment approval 或 runner 缺失时,三个 image matrix 均不得启动。
|
||
6. 整个 release workflow 禁止 `actions/upload-artifact` 与 `actions/cache`。证据挂载不进入 workspace、job output、
|
||
workflow artifact、BuildKit context、SBOM、provenance 或 OCI attestation。runner 销毁/卸载由外部 provisioner
|
||
执行;workflow 不删除作为审计事实来源的外部归档。
|
||
7. environment reviewer 必须确认 tag protection、tag commit、workflow 与 gate script 均来自已审发布提交。
|
||
自托管 runner 不参与镜像 build、签名或 attestation;实际 publisher 继续使用 GitHub-hosted runner,既有
|
||
`--deny-self-hosted-runners` provenance 验证保持不变。
|
||
8. 本能力是 repository-level 短期发布逻辑,不新增 workspace package、第三方依赖、数据库 migration、Profile
|
||
artifact、daemon、controller、watcher、timer、listener、Pool 或设备常驻资源。
|
||
|
||
## 失败与恢复
|
||
|
||
- 没有匹配 JIT runner 或 environment 未批准:发布保持 pending/失败,不回退到 GitHub-hosted evidence audit;
|
||
- 任一文件缺失、owner/mode/symlink/大小不合法:gate 在 publish 获得写 token 前失败;
|
||
- source 被替换、final claimed gate 被修改或 schema 不兼容:重新采集/聚合,禁止手工修补 final;
|
||
- evidence 超过 24 小时:重新执行生产 ceremony 与必要的证据协议,生成新的 no-replace final;
|
||
- runner clock 超前/落后:修复可信时间源后重跑,不扩大 future skew;
|
||
- tag/version 不一致:以正确受保护 tag 重新 dispatch,不允许 branch fallback;
|
||
- runner 执行后未被 provisioner 销毁:视为基础设施事故,停止后续 dispatch,隔离 runner 并轮换其注册凭据。
|
||
|
||
## 被拒绝的替代方案
|
||
|
||
### 上传五个 JSON 为私有 GitHub artifact
|
||
|
||
拒绝。repo 私有性不等于最小 custody;artifact 会新增复制、下载主体、retention 和误传风险。
|
||
|
||
### 只把 final report 放进 repository secret
|
||
|
||
拒绝。final 不能替代四份 source,且 GitHub secret 的大小/轮换模型不适合有界文件归档。
|
||
|
||
### 在 publisher job 内直接审计
|
||
|
||
拒绝。它会让同一个 job 同时持有生产 source、GHCR write、OIDC signing 和 attestation authority。
|
||
|
||
### 保留 tag push 并异步查询另一 workflow 的成功状态
|
||
|
||
拒绝。跨 workflow run/commit/tag 的竞态和重放关系更复杂;同一 dispatch 内的强 `needs` 提供更直接的失败关闭。
|
||
|
||
## 验证
|
||
|
||
- D-235 + D-236 定向 11/11:source-aware happy path、stale/future、source replacement、exact identity arguments;
|
||
- image release 静态/变异契约 26/26,覆盖自动 tag push、缺失 dependency、persistent runner、artifact upload、
|
||
非 commit-scoped mount、evidence write authority 与 movable action;
|
||
- `audit:image-release:ql3` 返回 `sourceAware=true`、`privateEphemeralRunner=true`、
|
||
`maximumAgeSeconds=86400`、`artifactUpload=false`;
|
||
- workspace 仍为 19 个 QL3 package,未新增第三方依赖或 Profile 稳态资源。
|