基于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 的签名过程遵循“先摘要、后签名”的原则:
- 计算镜像摘要:对镜像 manifest 进行 SHA-256 哈希,得到不可变的 digest。
- 生成签名载荷:使用私钥或临时密钥对 digest 签名,并封装为 DSSE(Dead Simple Signing Envelope)格式。
- 附加证书链:若使用 OIDC 模式,签名中会嵌入由 Fulcio 签发的短期证书,包含签名者身份信息。
- 推送至仓库:签名对象以
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 生态中扮演“客户端入口”的角色:
- 签名时: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 和策略系统中。