mirror of
https://github.com/whyour/qinglong.git
synced 2026-09-20 16:07:11 +08:00
104 lines
5.8 KiB
Markdown
104 lines
5.8 KiB
Markdown
# QingLong 3.0 镜像 OS 漏洞门
|
||
|
||
本流程覆盖 `control|control-ai|admin|local|worker × amd64|arm64` 十个 release candidate 的 OS/base image package,不替代 npm
|
||
production dependency audit、CycloneDX、BuildKit SBOM/provenance、Cosign 或 GitHub attestation。
|
||
|
||
## 日常检查
|
||
|
||
```sh
|
||
pnpm audit:image-os-vulnerability-policy:ql3
|
||
pnpm audit:image-release:ql3
|
||
pnpm audit:cluster-deployment:ql3
|
||
```
|
||
|
||
默认 exception policy 位于 `deploy/containers/ql3-os-vulnerability-exceptions.json`,当前必须返回:
|
||
|
||
```json
|
||
{"schemaVersion":1,"fixture":"qinglong/image-os-vulnerability-exceptions@v1","compatible":true,"exceptionCount":0,"imageExceptionCounts":{"admin":0,"control":0,"local":0}}
|
||
```
|
||
|
||
真实 scan 在 QL3 CI 已有十个 native build 后执行;受保护 release 的十个 native job 各自只构建一次 OCI layout tar,
|
||
Trivy 直接扫描该 tar。扫描成功后才解包、审计并上传同一 OCI graph;publisher 只合并 amd64/arm64 graph,不再 build。
|
||
只有六份 artifact 和 D-236 私密 evidence job 全部成功,publisher 才会启动。scanner/DB 网络故障与漏洞命中使用相同
|
||
的失败关闭结果,但日志会区分下载错误和 finding。
|
||
|
||
## Build-once 发布链
|
||
|
||
每个 `control|admin|local × amd64|arm64` native job 固定执行:
|
||
|
||
1. Buildx 用 exact Dockerfile、source revision、SBOM 与 provenance 生成
|
||
`${RUNNER_TEMP}/ql3-native/image.oci.tar`;
|
||
2. Trivy 以 `input` 扫描该 tar,禁止 daemon/candidate tag;
|
||
3. 扫描成功后解包到 `layout/`,repository recorder 复验 platform、source、SBOM/provenance 和全部 digest,写入
|
||
`evidence.json`,随后删除 tar;
|
||
4. 以 `run_id/run_attempt/image/arch` 唯一命名上传 `layout + evidence`,保留 1 天且禁止 overwrite。
|
||
|
||
publisher 的固定顺序是:下载同一 run attempt 的两份 native artifact → 本地重验并确定性 merge → 生成最终 OS
|
||
vulnerability predicate → checksum 验证 regctl → 登录 GHCR → `IMAGE@DIGEST` import → 读取远端 digest 比对 →
|
||
Cosign/SLSA/CycloneDX/OS-vulnerability attest 与 verify → manifest/rollout verify → 最后创建 version 与完整 commit tag。
|
||
publisher 不得安装 Buildx/QEMU、运行 Dockerfile 或在 tag promotion 后追加 step。
|
||
|
||
## 创建短期例外
|
||
|
||
优先升级 digest-pinned Node base。只有当前没有可部署修复且风险被明确接受时,才能在 central JSON 的
|
||
`exceptions` 中增加一项:
|
||
|
||
```json
|
||
{
|
||
"id": "CVE-2026-12345",
|
||
"images": ["admin", "control"],
|
||
"purls": ["pkg:deb/debian/libssl3@3.0.0-1"],
|
||
"owner": "security/platform",
|
||
"ticket": "QLSEC-123",
|
||
"expiresOn": "2026-08-15",
|
||
"rationale": "Temporary exposure accepted while the fixed base image is qualified."
|
||
}
|
||
```
|
||
|
||
约束:
|
||
|
||
- entries 按 `id` 严格升序,ID 唯一;images/purls 各自唯一且升序;
|
||
- 只接受 `CVE-*` 与 `pkg:apk|deb|rpm`,不能屏蔽 npm/library finding;
|
||
- `expiresOn` 必须晚于 UTC 当天且最多 30 天,到期当天自动失败;
|
||
- owner、ticket、rationale 缺一不可;ticket 必须先完成独立安全复核;
|
||
- 不得使用 `ignore-unfixed=true`、裸 `.trivyignore`、skip path、allow-all Rego 或无期限 VEX 代替本策略。
|
||
|
||
提交前执行:
|
||
|
||
```sh
|
||
node --test test/back/ql3ImageOsVulnerabilityPolicy.test.cjs
|
||
node --test test/back/ql3ClusterImageReleaseAudit.test.cjs
|
||
pnpm audit:image-os-vulnerability-policy:ql3
|
||
pnpm audit:image-release:ql3
|
||
```
|
||
|
||
策略生成器会为每个 image 创建临时 `.trivyignore.yaml`;Trivy action 会把该低敏 exception view 显示在 job log。
|
||
不得在 rationale、owner 或 ticket 中写 credential、内部 URL、个人数据或 Secret。
|
||
|
||
## 升级 scanner 或基础镜像
|
||
|
||
1. 阅读 Trivy 官方 release 与 security advisory,确认目标版本不在已知暴露窗口;
|
||
2. 解析 signed/immutable action release 到完整 commit SHA,审查 composite action 的所有 nested action pin;
|
||
3. 固定 scanner exact version,禁止 `latest`;保持 cache false、OS-only、unfixed 不忽略;
|
||
4. 对 Node base 的多架构 manifest digest 执行签名/来源核验;四个 production Dockerfile 的 runtime stage 必须同步更新 exact digest;
|
||
5. 更新 ADR、静态审计 expectation 与 mutation tests;执行十个 native scan 后才能发布;
|
||
6. 修复后删除已不需要的 exceptions,不等待 `expiresOn`。
|
||
|
||
## 失败恢复
|
||
|
||
- native job 失败或 artifact 未生成:重新运行整个 release;不要手工上传 artifact 或把旧 run artifact 改名复用;
|
||
- artifact/evidence/layout digest 不一致:视为供应链完整性失败,从 native build 重新开始,不通过重新打 tar 修复;
|
||
- regctl checksum 或下载失败:禁止回退到未固定 binary、`docker push` 或先推 candidate tag;
|
||
- exact digest 已导入但证明/验证失败:不要创建 tag。保留 digest 用于调查,修复后由新 run 重建;
|
||
- tag promotion 失败:确认目标 tag 没有指向其他 digest;不得覆盖不一致 tag来“完成”发布;
|
||
- 清理 runner 时只删除该 job 的 `${RUNNER_TEMP}/ql3-native`、`${RUNNER_TEMP}/native` 和 merge 输出,不能删除
|
||
workspace、D-236 owner-private source 或共享 Docker/Kind 资源。
|
||
|
||
## 当前证据边界
|
||
|
||
仓库已证明 policy、workflow、base pin、build-once/scanned-digest merge 和 fail-closed mutation contract。本机尝试
|
||
真实 OCI attested build 时,Docker container driver 获取 BuildKit SBOM scanner 遇到网络超时并已中止,临时目录已
|
||
删除,因此没有本地 live CVE clean 结论。首次 GitHub-hosted 六矩阵成功记录和首个 evidence-backed GHCR exact-digest
|
||
publish 仍属于外部 Release Gate。control/admin 的 exact Dockerfile 已在本机 arm64 成功构建并确认 `10001:10001`,
|
||
对应临时 image 随后已删除;这只证明 build/base pin,不替代漏洞数据库扫描。
|