Cosign:容器镜像签名与验证
bash brew install cosign
### Linux 使用预编译二进制
```bash
# 下载最新版本(以 amd64 为例)
curl -LO https://github.com/sigstore/cosign/releases/latest/download/cosign-linux-amd64
sudo mv cosign-linux-amd64 /usr/local/bin/cosign
sudo chmod +x /usr/local/bin/cosign
安装完成后,确认版本:
cosign version
生成签名密钥对
Cosign 默认使用 Ed25519 算法生成短小且高度安全的密钥。运行以下命令,按提示为密钥设置密码:
cosign generate-key-pair
命令执行后会在当前目录生成:
cosign.key—— 私钥,切勿外泄cosign.pub—— 公钥,随处分发
如果你想直接在其他位置生成密钥,可添加 --output-key-prefix 参数指定路径前缀。
对镜像进行签名
签名前,确保你已登录到对应的镜像仓库(如 Docker Hub、GitHub Container Registry 等)。然后执行:
cosign sign --key cosign.key <镜像名:TAG>
例如:
cosign sign --key cosign.key myregistry/myimage:v1.0.0
Cosign 会将签名包装为 OCI 制品,自动推送到与镜像相同的仓库中,通常放在名为 sha256-xxxxx.sig 的 tag 下。整个过程不需要额外的签名存储服务。
如果希望签名后自动记录签名者的身份信息,可以使用 -a 添加自定义标注:
cosign sign --key cosign.key -a "dev=team-a" myregistry/myimage:v1.0.0
验证镜像签名
使用公钥验证
拿到发布者提供的公钥后,任何人都可以验证镜像签名:
cosign verify --key cosign.pub <镜像名:TAG>
如果验签成功,终端会输出签名者信息、摘要等;如果失败,则会报错并返回非零退出码。示例:
cosign verify --key cosign.pub myregistry/myimage:v1.0.0
Verification for myregistry/myimage:v1.0.0 --
The following checks were performed on each of these signatures:
- The cosign claims were validated
- The signatures were verified against the specified public key
验证特定标签的镜像
默认情况下 cosign verify 只检查与指定标签关联的签名。若你想验证镜像摘要而非可变标签,使用 @sha256:... 格式更加安全:
cosign verify --key cosign.pub myregistry/myimage@sha256:abc123...
无密钥签名(Keyless)
Keyless 流程利用 OIDC 协议代替手动管理私钥。签名时,Cosign 会引导你通过浏览器完成 OIDC 身份认证(支持 GitHub、Google、Microsoft 等),然后用短期有效证书对镜像签名。
前置条件
- 安装 Cosign 2.0 或更高版本
- 能访问互联网完成 OIDC 认证
无密钥签名命令
cosign sign <镜像名:TAG>
Cosign 会打开浏览器窗口,要求你选择身份提供者并登录。完成后,签名自动使用 Fulcio 颁发的证书生成,并上传至 Rekor 透明日志中。
无密钥验证
验证时,需要指定信任的 OIDC 发行者以及证书主体标识。例如,只接受来源于 GitHub Actions 且仓库为 myorg/myrepo 的签名:
cosign verify \
--certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
--certificate-identity "https://github.com/myorg/myrepo/.github/workflows/release.yaml@refs/heads/main" \
<镜像名:TAG>
通过这种策略,你可以细粒度地控制哪些 CI/CD 流水线可以被信任。
查看镜像上的签名
若想直接列出某个镜像现存的所有签名条目,可使用 cosign triangulate 和 crane 组合,或直接使用:
cosign verify --key cosign.pub --output=json <镜像名:TAG> | jq .
或者使用 cosign tree 观察签名树结构:
cosign tree <镜像名:TAG>