Files
qinglong/docs/adr/ADR-0254-digest-pinned-cross-architecture-os-vulnerability-release-gate.md
T

6.8 KiB
Raw Blame History

ADR-0254Digest 固定的跨架构 OS 漏洞发布门

ADR-0255 supersedes 本 ADR 决策 5 中 release candidate 到 publisher 的传输方式:release 现在 build once、扫描 exact OCI layout tar,并按同一 audited digest 发布。本 ADR 的 base pin、Trivy pin、OS-only gate 与例外治理继续有效。

  • 状态:Acceptedbase pin、策略审计器、CI/release 接线与负向测试已实现;联网六矩阵扫描记录待取得)
  • 日期:2026-08-01
  • 关联 RFCQL-RFC-0001 D-14、D-61、D-128、D-186、D-236、D-237
  • 关联 ADRADR-0128、ADR-0195、ADR-0196、ADR-0253

背景

QingLong 3.0 已对 npm production graph 执行 high/critical advisory gate,但这不覆盖 Debian/base image OS package。 同时 control/admin Dockerfile 仍通过可覆盖的 ARG NODE_IMAGE 引用 tag,而 local image 已固定多架构 digest;即使 对某次本地 build 扫描通过,后续 build 也可能解析到另一份基础镜像。

Trivy 官方在 2026-03 披露过 action/tag 与部分二进制发布渠道被篡改的供应链事件,并明确要求 action 使用完整 commit SHA。D-237 不能用 movable @v0.xlatest 引入一个拥有 workflow 执行能力的 scanner。

决策

  1. control、admin、local 的 build/runtime stage 统一固定 node:24.18.0-bookworm-slim@sha256:6f7b03f7c2c8e2e784dcf9295400527b9b1270fd37b7e9a7285cf83b6951452d。 control/admin 删除 ARG NODE_IMAGE,不得允许 build arg 覆盖 base;三个镜像继续拥有独立 Dockerfile、应用闭包和 最终 image digest。
  2. scanner 固定为 Trivy v0.70.0GitHub Action 固定完整 commit ed142fd0673e97e23eac54620cfb913e5ce36c25action v0.36.0)。禁止 tag、masterlatestcontinue-on-error 和 scanner cache;网络、release asset 或 vulnerability DB 不可用均失败关闭。
  3. 只扫描 vuln-type=osscanners=vuln、severity HIGH,CRITICALignore-unfixed=false、exit code 1。 npm/library advisory 继续由既有 production dependency audit 独立负责,不能用 OS 例外隐藏应用依赖漏洞。
  4. .github/workflows/ql3-ci.yml 复用已经存在的 native buildcontrol/admin 各 amd64+arm64local amd64+arm64,共六个真实本地 image。每个 build 后生成 image-scoped ignore view 并执行 Trivy。
  5. release workflow 增加独立只读 os-vulnerability 六矩阵 job,在发布前用 exact Dockerfile、base digest、lock 和 source revision 构建 native candidate。publish 必须同时依赖 D-236 private evidence 与全部 OS scan 成功, 才能获得 GHCR/OIDC/attestation 写权限。scan job 不读取 D-236 私密 source,不参与签名或 publish。
  6. 唯一例外事实源为 deploy/containers/ql3-os-vulnerability-exceptions.json。顶层和每条 entry 都是 exact shape 每条必须包含唯一且排序的 CVE、非空且排序的 admin|control|local image 集合、非空且排序的 pkg:apk|deb|rpm purl、owner、ticket、20512 字理由和未来到期日。
  7. 例外最多 128 条,单条例外最长 30 天;到期当天即无效。策略审计器为每个 image 生成临时 0600、no-replace .trivyignore.yaml,映射为 Trivy 官方 id+purls+expired_at+statement。不得直接维护 .trivyignore、全局 CVE ID、 path skip、Rego allow-all、VEX bypass 或无期限 exception。
  8. 当前 production policy 为 exceptions=[]。新增例外必须先关联安全 ticket、指定责任 owner、确认 package purl 与 受影响 image、设置最短到期日,并通过变异测试;修复 base 后立即删除,不等待到期。
  9. scanner、生成器、策略和 workflow 都是 repository/release-time 工具,不新增 workspace package、第三方 runtime dependency、migration、daemon、controller、timer、watcher、listener、Pool 或 Profile 常驻资源。

失败与恢复

  • base digest/tag/action/version 漂移:静态审计失败,先审查上游 release 与签名,再显式更新 ADR/测试;
  • scanner 或 DB 下载失败:CI/release 失败,不回退到旧 DB、不跳过扫描;
  • HIGH/CRITICAL 命中且无例外:升级基础镜像/OS package;只有短期无法修复时才按本 ADR 添加 exception
  • exception 到期、超过 30 天、缺 owner/ticket/rationale、使用 library purl 或 image scope 为空:policy gate 失败;
  • 一个架构构建/扫描失败:整个 os-vulnerability matrix 不满足,三个 publisher 都不得启动;
  • 本地临时 scanner 下载超时:只能记录“未取得本地 live scan”,不能把静态契约或 checksum 预检记为漏洞通过。

被拒绝的替代方案

发布后扫描 GHCR digest

拒绝。HIGH/CRITICAL 被发现前 tag/manifest 已进入 registry;发布前 native candidate scan 才能阻止写入。

只扫描 amd64

拒绝。多架构 base 的 OS package/config 可能不同,amd64 结果不能证明 arm64 路由器/节点镜像。

ignore-unfixed=true

拒绝。它把所有无修复漏洞变成隐式永久例外;D-237 要求每个例外有 scope、owner、ticket、理由和到期日。

直接提交 .trivyignore.yaml

拒绝。Trivy 的 statement 不参与过滤,且原生 schema 不要求 owner、ticket、最长周期或 image scope;仓库级严格 策略生成 image-specific view 可以补足这些治理约束。

用 action tag 或 scanner latest

拒绝。上游供应链事故已证明 tag 可被重写;完整 action commit 与 exact scanner version 是最低可接受边界。

验证

  • OS exception policy 8/8empty、image scope、purl、owner/ticket/rationale、expired/same-day/>30 天、排序/重复、 0600 no-replace 与 exact CLI
  • image release contract 34/34:新增覆盖 CI/release action pin、六矩阵、publish dependency、unfixed、OS-only、 cache 与既有签名/SBOM/provenance 门;
  • Cluster deployment 31/31,包含 control/admin mutable/overridable base 负向测试;
  • 本机 arm64 exact Dockerfile build 已通过:control sha256:58ca2905c6489d3051663804f07adb0ea24dce734cc96863f882c8e5cb73579c、 admin sha256:79f8eda7194cf63669ba144917eabecd11faa0546858ac1feb7ee52ccffc5f27,均为 arm64、 10001:10001;验证 image 已删除;
  • audit:image-release:ql3 返回 Trivy 0.70.0、exact action commit、amd64/arm64、OS-only、HIGH/CRITICAL、 ignoreUnfixed=false、maximum exception 30 days
  • 当前 policy exceptionCount=0workspace 保持 19 个 package,无新增 runtime dependency。

上游依据