# ADR-0254:Digest 固定的跨架构 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 与例外治理继续有效。 - 状态:Accepted(base pin、策略审计器、CI/release 接线与负向测试已实现;联网六矩阵扫描记录待取得) - 日期:2026-08-01 - 关联 RFC:QL-RFC-0001 D-14、D-61、D-128、D-186、D-236、D-237 - 关联 ADR:ADR-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.x` 或 `latest` 引入一个拥有 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.0`,GitHub Action 固定完整 commit `ed142fd0673e97e23eac54620cfb913e5ce36c25`(action `v0.36.0`)。禁止 tag、`master`、`latest`、 `continue-on-error` 和 scanner cache;网络、release asset 或 vulnerability DB 不可用均失败关闭。 3. 只扫描 `vuln-type=os`、`scanners=vuln`、severity `HIGH,CRITICAL`,`ignore-unfixed=false`、exit code 1。 npm/library advisory 继续由既有 production dependency audit 独立负责,不能用 OS 例外隐藏应用依赖漏洞。 4. `.github/workflows/ql3-ci.yml` 复用已经存在的 native build:control/admin 各 amd64+arm64,local 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、20–512 字理由和未来到期日。 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/8:empty、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=0`;workspace 保持 19 个 package,无新增 runtime dependency。 ## 上游依据 - Trivy filtering 与 YAML `id/purls/expired_at/statement`:; - Trivy ecosystem supply-chain advisory:; - Trivy Action v0.36.0: