制品管理与供应链溯源:从仓库到 Provenance

制品管理与软件供应链溯源:镜像仓库与包仓库的选型、制品晋升与不可变标签、SBOM 软件物料清单的生成与消费、Sigstore 签名与 SLSA 来源溯源、供应链安全门禁,以及制品保留策略与端到端可追溯性审计。

一次构建、多次部署的前提是制品被可靠地存放、标识与追溯。制品管理不只是「找个地方存镜像」,而是覆盖仓库选型、制品晋升、SBOM 生成、签名溯源到供应链门禁的一整条链路。本文沿着「构建出什么 → 存在哪里 → 怎么晋升 → 如何证明来源 → 怎么放行」的顺序,讲清一套可落地的制品与供应链治理方案。


目录


1. 制品与制品仓库

1.1 什么是制品

制品(artifact)是构建流水线产出的、被部署到运行环境的不可变产物:容器镜像、JAR/WAR 包、npm/PyPI 包、二进制、Helm Chart 等。制品的核心属性是「一旦生成就不再修改」,任何修改都意味着产生一个新制品。

1.2 制品仓库的职责

制品仓库不只是存储,它承担四件事:存储与分发、版本与元数据管理、访问控制、以及与安全扫描的集成。

职责说明
存储分发就近拉取、断点续传、缓存代理
版本元数据标签、摘要、构建信息、依赖关系
访问控制仓库级与路径级权限、令牌管理
安全集成漏洞扫描、签名校验、准入拦截

1.3 本地缓存与代理

制品仓库通常还承担上游代理:缓存 Maven Central、npm registry、Docker Hub 的拉取结果。这既加速构建,又能在上游不可用时提供可用性保障,也是供应链攻击的拦截点。

2. 镜像仓库与包仓库

2.1 镜像仓库

镜像仓库管理 OCI 制品。主流选择有 Harbor(自建、功能全)、JFrog Artifactory(商业、多类型统一)、以及云厂商的 ECR、GAR、ACR。镜像用标签(tag)与摘要(digest)双重标识。

镜像标识
  tag    : 可变的友好名,如 order-service:v1.2.3
  digest : 内容寻址的哈希,如 sha256:9f2a...
  规则   :部署用 digest,人读用 tag
  陷阱   :tag 可被覆盖,digest 不会

2.2 包仓库

包仓库管理语言生态的依赖包与自研包:Nexus 与 Artifactory 支持 Maven、npm、PyPI、NuGet、Go module 等多种格式。私有包仓库是内网构建的前提,也是依赖治理的抓手。

2.3 关键差异

维度镜像仓库包仓库
制品形态OCI 层叠镜像语言生态包
标识tag + digest坐标 + 校验和
典型工具Harbor、ECRNexus、Artifactory
扫描重点OS 包与基础镜像依赖漏洞与许可证
部署关联直接部署单元构建输入

3. 制品晋升模型

3.1 一次构建,多次晋升

核心原则是「同一个制品从开发一路晋升到生产,绝不重新构建」。重新构建会产生不同制品,破坏了「测试过的就是上线的」这一保证。

晋升链路
  build  →  dev  →  staging  →  prod
  同一个 digest 在环境中移动,不重新构建
  每个环境有独立的准入策略与审批

3.2 用不可变标签

环境标签用不可变方式管理:order-service:dev 指向的 digest 确定后不再改变,晋升时通过重新打标签指向同一 digest 实现。这样「晋升」是元数据操作,不是内容复制。

3.3 环境晋级门禁

每跨一个环境都要过门禁:单元测试、集成测试、安全扫描、性能基线、人工审批。门禁在流水线里实现,不依赖人的自觉。

4. SBOM 软件物料清单

4.1 SBOM 是什么

SBOM(Software Bill of Materials)是制品的成分清单,列出它包含的所有组件及其版本、许可证、依赖关系。相当于食品的营养成分表,让「这个制品里有什么」可被机器查询。

4.2 生成格式与工具

主流格式有 SPDX 与 CycloneDX 两种,工具链上 Syft、Trivy、cdxgen 都能生成,且多数能直接集成进构建流水线。

# 用 Syft 为镜像生成 CycloneDX 格式的 SBOM
syft order-service:v1.2.3 -o cyclonedx-json > sbom.json

# 用 Trivy 扫描镜像漏洞并输出 SBOM
trivy image --format cyclonedx --output sbom.json order-service:v1.2.3

# SBOM 作为制品附件一起入库,与镜像同 digest 关联
cosign attach sbom --sbom sbom.json registry.example.com/order-service@sha256:9f2a...

4.3 SBOM 的消费场景

生成只是第一步,价值在消费:出漏洞时快速定位哪些制品受影响、审计时回答许可证合规、采购时评估上游依赖风险。

场景输入输出
漏洞响应CVE + 全量 SBOM受影响制品清单
许可证审计SBOM 依赖树违规许可证报告
依赖治理跨制品 SBOM组件使用分布
合规交付制品 SBOM交付物成分证明

5. 来源溯源与签名

5.1 签名证明制品未被篡改

签名解决「这个制品是不是我以为的那个」。Sigstore 的 cosign 提供无密钥签名(keyless),用 OIDC 身份与透明日志(Rekor)记录签名,无需自建 PKI。

# 用 cosign 对镜像签名(keyless,绑定 CI 身份)
cosign sign registry.example.com/order-service@sha256:9f2a...

# 部署前验证签名与签发者
cosign verify \
  --certificate-identity-regexp '.*@example.com' \
  --certificate-oidc-issuer https://accounts.example.com \
  registry.example.com/order-service@sha256:9f2a...

5.2 SLSA 来源溯源

SLSA(Supply-chain Levels for Software Artifacts)用分级描述构建过程的完整性:制品是否由受信任的构建服务产出、构建过程是否可复现、来源信息是否被签名。

等级要求抵御的风险
SLSA 1有构建过程文档最低可追溯
SLSA 2由托管构建服务产出、有签名来源篡改构建脚本
SLSA 3构建环境隔离、来源不可伪造污染构建环境
SLSA 4双人评审、可复现构建内部人员作恶

5.3 Provenance 证明

来源证明(provenance)记录「谁、用什么源码、在什么环境、用什么命令构建了这个制品」,用 in-toto 格式签名后附在制品旁。部署时校验证明,确认制品确实来自预期流水线。

6. 供应链安全门禁

6.1 门禁的位置

门禁至少设在三处:构建时(阻断引入高危依赖)、入库时(拒绝未签名或扫描不通过的制品)、部署时(准入控制器校验签名与证明)。

6.2 准入控制

在 Kubernetes 里用准入控制器强制「未签名不得部署」:镜像必须有有效签名、SBOM 可查、来源证明可信,否则拒绝创建 Pod。

# 准入策略示意:只允许来自可信仓库且已签名的镜像
apiVersion: policy.sigstore.dev/v1beta1
kind: ClusterImagePolicy
metadata:
  name: require-signed-images
spec:
  images:
    - glob: "registry.example.com/**"
  authorities:
    - keyless:
        identities:
          - issuer: https://accounts.example.com
            subject: ".*@example.com"

6.3 从告警到阻断

门禁上线应分两阶段:先以「只告警不阻断」模式运行,观察误报与遗漏;规则稳定后再切到阻断模式,避免一上线就把发布流程卡死。

7. 制品清理与生命周期

7.1 为什么必须清理

制品仓库会无限膨胀:每次构建都产生新镜像,几个月就是几 TB。不清理不仅占存储,还拖慢索引与拉取,并扩大漏洞暴露面。

7.2 保留策略

按「环境 + 时间 + 数量」组合制定保留规则:生产环境保留全部已发布版本,预发保留最近 N 个,开发环境只保留最近几天的构建。

保留策略示例
  prod   : 保留所有已晋升版本,永不自动删除
  staging: 保留最近 20 个版本
  dev    : 保留最近 7 天
  清理前 : 标记为待删除,观察期 7 天后再真正删除
  例外   : 有生产引用的 digest 强制保留

7.3 安全删除

删除前必须确认「没有运行中的工作负载引用该 digest」。用引用扫描建立「制品到部署」的映射,避免误删正在被使用的镜像导致滚动重启拉不到镜像。

8. 可追溯性与审计

8.1 端到端链路

一条完整的可追溯链路是:源码 commit → 构建流水线运行 → 制品 digest → SBOM → 签名与证明 → 晋升记录 → 生产部署。任何一环缺失,追溯就断。

环节记录内容存放位置
源码commit sha、作者、评审版本控制
构建流水线 ID、参数、环境CI 系统
制品digest、标签、扫描结果制品仓库
签名签名者身份、时间、日志Rekor 透明日志
部署环境、时间、操作者CD 系统

8.2 漏洞响应的价值

当爆发一个严重 CVE,如果 SBOM 与溯源链路齐全,可以在几分钟内回答「哪些生产制品受影响、分别部署在哪些环境」,而不是靠人工逐个排查。这正是供应链治理最直接的回报。

8.3 审计留痕

所有晋升、签名、放行操作都要留审计日志,记录操作者、时间与理由。审计不是为了事后追责,而是为了在出问题时能快速还原事实。

9. 案例与最佳实践

9.1 落地 Checklist

□ 一次构建多次晋升,同一 digest 贯穿所有环境
□ 部署引用 digest,tag 仅作人读标识
□ 每个环境独立准入策略与审批门禁
□ 构建时自动生成 SBOM,与镜像同 digest 关联入库
□ 用 cosign keyless 签名,签名绑定 CI 身份
□ 按 SLSA 分级推进,先做到来源可签、可验
□ 准入控制器强制「未签名不得部署」
□ 制定保留策略,删除前确认无引用
□ 打通 commit 到部署的端到端可追溯链路

9.2 常见坑与对策

坑现象对策
部署用可变 tag上线内容与预期不符部署引用 digest
各环境重新构建测试过的不是上线的一次构建多次晋升
SBOM 只生成不消费出漏洞时仍靠人工排查接入漏洞响应流程
门禁一上来就阻断误报卡死发布先告警后阻断
无保留策略仓库膨胀到数 TB按环境制定保留规则
误删在用镜像滚动重启拉不到镜像删除前做引用扫描
签名不绑身份谁签的说不清keyless 绑定 CI 身份

小结

制品管理与供应链溯源的完整链路是:构建产出不可变制品 → 存入仓库并用 digest 标识 → 一次构建多次晋升 → 生成 SBOM 与签名证明 → 在准入处校验并放行 → 用保留策略控制膨胀 → 打通端到端可追溯。核心原则有三条:部署永远引用 digest 而非可变标签、制品只构建一次然后晋升、每一个放行决定都基于可验证的签名与证明。做到这三点,才能在漏洞爆发时快速定位、在审计时从容举证。

继续阅读

探索更多技术文章

浏览归档,发现更多关于系统设计、工具链和工程实践的内容。

全部文章 返回首页

「DevOps」更多文章

  1. 可观测性驱动的发布验证与自动回滚
  2. 策略即代码:OPA、Conftest 与合规门禁
  3. 配置管理:Ansible 与不可变基础设施的取舍