基于Cosign的镜像供应链信任边界驱动开发实践 - 第3节

3.1 Cosign 项目背景

Cosign 是由 Chainguard 发起、目前由 Sigstore 社区维护的开源容器镜像签名工具。它的诞生直接回应了软件供应链安全中一个核心痛点:如何在不引入复杂 PKI 体系的前提下,对容器镜像进行密码学签名与验证。

在 Cosign 出现之前,容器镜像签名主要依赖 Docker Content Trust(基于 Notary)或手动 GPG 签名,存在以下问题:

  • 密钥管理复杂:需要自行维护 CA 或 GPG 密钥环,轮换与吊销成本高。
  • 签名存储分散:签名数据与镜像分离,缺乏标准化的存储与发现机制。
  • 验证门槛高:验证方需要预先获取公钥,难以在 CI/CD 中自动化集成。

Cosign 通过以下设计解决了上述问题:

  • 无 PKI 依赖:支持基于 OIDC 身份(如 GitHub、Google、Microsoft)的密钥生成,无需自建 CA。
  • 签名存储标准化:将签名写入 OCI 制品仓库,与镜像同生命周期管理。
  • 验证零配置:支持从公共透明日志(Rekor)或 OIDC 令牌自动获取公钥,实现开箱即用的验证。
关键里程碑:Cosign v1.0 于 2021 年 9 月发布,标志着容器镜像签名进入“无密钥”与“透明日志”时代。截至 2024 年,Cosign 已成为 CNCF 生态中下载量最高的镜像签名工具之一。

3.2 核心功能:签名、验证、存储

Cosign 围绕三条核心能力构建,形成完整的镜像信任闭环:

功能 命令示例 核心机制 输出产物
签名 cosign sign 使用私钥或 OIDC 身份对镜像摘要签名,生成 DSSE 格式签名载荷 签名对象 + 签名证书(可选)
验证 cosign verify 从 OCI 仓库或 Rekor 获取签名,验证公钥信任链或 OIDC 身份 验证通过/失败状态 + 签名元数据
存储 cosign attach / cosign copy 将签名、SBOM、附件作为 OCI 制品存入镜像仓库 OCI 引用(tag 或 digest)

3.2.1 签名流程

Cosign 的签名过程遵循“先摘要、后签名”的原则:

  1. 计算镜像摘要:对镜像 manifest 进行 SHA-256 哈希,得到不可变的 digest。
  2. 生成签名载荷:使用私钥或临时密钥对 digest 签名,并封装为 DSSE(Dead Simple Signing Envelope)格式。
  3. 附加证书链:若使用 OIDC 模式,签名中会嵌入由 Fulcio 签发的短期证书,包含签名者身份信息。
  4. 推送至仓库:签名对象以 sha256-xxxx.sig 的 tag 格式写入镜像仓库,与原始镜像同仓库、同 digest 前缀。
# 使用密钥对签名
cosign sign --key cosign.key ghcr.io/myorg/myapp:v1

# 使用 OIDC 身份签名(无密钥模式)
cosign sign ghcr.io/myorg/myapp:v1

3.2.2 验证流程

验证是签名的逆向过程,Cosign 支持多种验证策略:

验证模式 信任来源 适用场景
公钥验证 本地公钥文件或 KMS 企业内部固定签名者
OIDC 身份验证 Fulcio 证书 + OIDC 令牌 CI/CD 流水线、开源社区
透明日志验证 Rekor 日志 + 证书链 需要审计追溯的场景
策略验证 自定义策略文件(CUE/Rego) 细粒度准入控制
# 使用公钥验证
cosign verify --key cosign.pub ghcr.io/myorg/myapp:v1

# 使用 OIDC 身份验证(自动从 Fulcio 获取证书)
cosign verify ghcr.io/myorg/myapp:v1

3.2.3 存储模型

Cosign 的存储设计充分利用了 OCI 制品的扩展性:

  • 签名存储:以 .sig 后缀的 OCI 制品形式存储,与镜像共享仓库命名空间。
  • 附件存储:SBOM、扫描报告等元数据可通过 cosign attach 关联到镜像。
  • 发现机制:通过 cosign triangulate 命令,可从镜像引用自动推导签名存储位置。
# 查看镜像关联的签名
cosign triangulate ghcr.io/myorg/myapp:v1
# 输出: ghcr.io/myorg/myapp:sha256-xxxx.sig
最佳实践:建议将签名与镜像存储在同一仓库,利用仓库的访问控制、备份和清理策略统一管理。避免将签名存储在独立的外部存储中,否则会增加验证延迟和运维复杂度。

3.3 Cosign 与 Sigstore 生态的关系

Cosign 是 Sigstore 项目的客户端组件之一,Sigstore 生态由以下核心服务组成:

组件 角色 与 Cosign 的关系
Cosign 签名/验证客户端 用户直接交互的工具,调用其他 Sigstore 服务
Fulcio 证书颁发机构(CA) Cosign 通过 OIDC 身份向 Fulcio 申请短期签名证书
Rekor 透明日志 Cosign 将签名记录提交至 Rekor,提供不可篡改的审计线索
Sigstore Policy Controller 策略执行引擎 基于 Cosign 验证结果,在 Kubernetes 中实施准入控制

下图展示了 Cosign 在 Sigstore 生态中的位置与交互流程:

Cosign 与 Sigstore 生态交互架构 用户 / CI 流水线 Cosign 客户端 Fulcio 证书颁发机构 Rekor 透明日志 OCI 镜像仓库 镜像 + 签名存储 ① 请求证书 ② 返回证书 ③ 提交签名 ④ 推送签名 验证流程(下游消费者) 从 OCI 仓库获取签名 → 从 Rekor 获取日志证明 → 验证证书链 → 比对镜像摘要 验证通过则镜像可信,否则拒绝部署

从图中可以看出,Cosign 在整个 Sigstore 生态中扮演“客户端入口”的角色:

  • 签名时:Cosign 向 Fulcio 申请证书,将签名提交至 Rekor,并将签名推送至 OCI 仓库。
  • 验证时:Cosign 从 OCI 仓库获取签名,从 Rekor 获取日志证明,验证证书链的有效性。
  • 策略集成:Sigstore Policy Controller 等组件调用 Cosign 的验证结果,在 Kubernetes 中实现自动化准入控制。
注意:Cosign 本身不提供策略引擎或运行时保护。它专注于签名与验证这一核心环节,上层策略(如“仅允许由特定 CI 系统签名的镜像”)需要结合 Policy Controller 或 OPA 等工具实现。

3.4 本章小结

Cosign 作为 Sigstore 生态的客户端工具,通过标准化的签名、验证和存储机制,为容器镜像供应链提供了可验证的信任锚点。其核心价值在于:

  • 降低签名门槛:OIDC 身份模式消除了密钥管理负担。
  • 增强可审计性:Rekor 透明日志确保签名行为不可抵赖。
  • 生态可扩展:OCI 存储模型使签名与镜像生命周期一致,便于集成到现有 CI/CD 和策略系统中。