cosign 签名需在 ci/cd 中镜像推送后、部署前完成,基于 digest 而非 tag,使用 kms 或安全密钥管理,签名存为独立 artifact 并可验证。

在 Kubernetes 中对 CI/CD 产出的镜像做 Cosign 数字指纹签名,核心是把签名动作嵌入构建流程,并确保签名可被集群后续验证。这不是“打个标签”,而是为镜像内容生成不可篡改的密码学绑定——即对 manifest 和所有 layer digest 的整体哈希进行私钥签名。
一、CI/CD 流水线中完成签名(关键入口)
签名必须发生在镜像构建完成、推送 registry 之后,且在部署到集群之前。典型步骤如下:
- 用
docker build或buildx构建镜像,打上语义化标签(如ghcr.io/org/app:v1.2.0) - 执行
docker push ghcr.io/org/app:v1.2.0,确保镜像已上传至支持 OCI Artifact 的仓库(如 GHCR、Harbor 2.8+、ECR) - 运行
cosign sign --key cosign.key ghcr.io/org/app:v1.2.0,签名会以独立 artifact 形式存入同一仓库路径(如@sha256:...sig) - (推荐)添加注解说明签名上下文:
cosign sign --key cosign.key --annotations "buildID=ci-job-789" ghcr.io/org/app:v1.2.0
二、密钥管理必须安全隔离
私钥绝不能明文出现在 CI 环境或 Git 仓库中:
- 生产环境应使用 KMS(如 AWS KMS、GCP KMS)或 HSM 托管私钥,通过
cosign sign --kms <uri></uri>调用 - 若用文件密钥,需从 CI 秘密管理器(如 GitHub Secrets、GitLab CI Variables)注入,且仅限签名作业访问
- 公钥
cosign.pub可公开分发,建议提前导入集群作为信任锚点
三、签名不是签 tag,而是签 digest
Cosign 默认对镜像的 digest(如 sha256:abc123...)签名,而非 tag。这意味着:
- 重打同名 tag(如
v1.2.0)不会覆盖原有签名,新镜像需重新签名 - Kubernetes 验证时也基于 digest,避免 tag 被覆盖导致的验证绕过
- 可在流水线末尾加一步:提取 digest 并记录,例如
docker inspect ghcr.io/org/app:v1.2.0 --format='{{.Id}}'
四、验证签名是否成功写入仓库
签名后立即本地验证,确认元数据就位:
-
cosign verify --key cosign.pub ghcr.io/org/app:v1.2.0—— 检查能否读取并验签 -
cosign triangulate ghcr.io/org/app:v1.2.0—— 输出签名 artifact 的完整 registry 地址(如ghcr.io/org/app@sha256:...sig) - 用 curl 或 registry API 直接请求该地址,确认 HTTP 200 返回签名 envelope 内容











