
容器和二进制的代码签名与透明度
使用 Sigstore 对 OCI 容器(及其他制品)进行签名!
Cosign 旨在让签名成为无形的基础设施。
Cosign 支持:
Cosign 是作为 sigstore 项目的一部分开发的。
我们还使用一个 slack 频道!
点击此处获取邀请链接。
有关 Homebrew、Arch、Nix、GitHub Action 和 Kubernetes 安装,请参阅安装文档。
有关 Linux、macOS 和 Windows 二进制文件,请参阅 GitHub 发布资产。
🚨 如果你正在从我们的 GCS 存储桶下载 cosign 的发布版本 - 请查看有关 2023 年 7 月 31 日弃用通知的更多信息 🚨
如果你有 Go 1.22+,可以设置开发环境:
$ git clone https://github.com/sigstore/cosign
$ cd cosign
$ go install ./cmd/cosign
$ $(go env GOPATH)/bin/cosign
如果您有兴趣为 cosign 做贡献,请阅读贡献文档。
Cosign 未来的开发将聚焦于下一个主要版本,该版本将基于 sigstore-go。维护者将专注于 sigstore-go 内的功能开发。 欢迎对 sigstore-go 的贡献,特别是围绕自带密钥和签名方面的贡献。 请查看问题跟踪器以寻找适合新手的问题。
Cosign 2.x 是一个稳定版本,将继续定期接收功能更新和错误修复。范围较小、规模不大的 PR 最有可能被快速审查。
显著修改或破坏 API 的 PR 将不被接受。规模较大但不引入破坏性变更的 PR 可能会被接受, 但其优先级将低于 sigstore-go 中的 PR。
以下是如何通过 ghcr.io/sigstore/cosign/cosign 镜像在 Dockerfile 中安装和使用 cosign:
FROM ghcr.io/sigstore/cosign/cosign:v2.4.1 as cosign-bin
# Source: https://github.com/chainguard-images/images/tree/main/images/static
FROM cgr.dev/chainguard/static:latest
COPY --from=cosign-bin /ko-app/cosign /usr/local/bin/cosign
ENTRYPOINT [ "cosign" ]
本节展示如何:
请注意,你应始终基于镜像的摘要(@sha256:...)而非标签(:latest)进行签名,否则你可能会签署并非你本意的东西!
cosign sign $IMAGE
Generating ephemeral keys...
Retrieving signed certificate...
Note that there may be personally identifiable information associated with this signed artifact.
This may include the email address associated with the account with which you authenticate.
This information will be used for signing this artifact and will be stored in public transparency logs and cannot be removed later.
By typing 'y', you attest that you grant (or have permission to grant) and agree to have this information stored permanently in transparency logs.
Are you sure you would like to continue? [y/N] y
Your browser will now be opened to:
https://oauth2.sigstore.dev/auth/auth?access_type=online&client_id=sigstore&code_challenge=OrXitVKUZm2lEWHVt1oQWR4HZvn0rSlKhLcltglYxCY&code_challenge_method=S256&nonce=2KvOWeTFxYfxyzHtssvlIXmY6Jk&redirect_uri=http%3A%2F%2Flocalhost%3A57102%2Fauth%2Fcallback&response_type=code&scope=openid+email&state=2KvOWfbQJ1caqScgjwibzK2qJmb
Successfully verified SCT...
tlog entry created with index: 12086900
Pushing signature to: $IMAGE
Cosign 会提示你通过 OIDC 进行身份验证,届时你将使用自己的电子邮件地址登录。 在底层,cosign 会向 Fulcio 证书颁发机构申请代码签名证书。 证书的主题将与你登录时使用的电子邮件地址相匹配。 随后,Cosign 会将签名和证书存储在 Rekor 透明度日志中,并将签名与你正在签名的镜像一起上传到 OCI 注册表。
要验证镜像,你需要通过 --certificate-identity 和 --certificate-oidc-issuer 标志传入预期的证书主题和证书颁发者:
cosign verify $IMAGE --certificate-identity=$IDENTITY --certificate-oidc-issuer=$OIDC_ISSUER
你也可以为证书身份和颁发者标志传入正则表达式,即 --certificate-identity-regexp 和 --certificate-oidc-issuer-regexp。
如果找到至少一个与公钥匹配的 cosign 格式的镜像签名,此命令返回 0。
有关其他签名格式的信息和注意事项,请参阅下面的详细用法。
任何有效的负载都会以 json 格式打印到 stdout。 请注意,这些已签名的负载包含容器镜像的摘要,这就是我们能够确信这些“分离的”签名覆盖了正确镜像的方式。
$ cosign verify --key cosign.pub $IMAGE_URI:1h
The following checks were performed on these signatures:
- The cosign claims were validated
- The signatures were verified against the specified public key
{"Critical":{"Identity":{"docker-reference":""},"Image":{"Docker-manifest-digest":"sha256:87ef60f558bad79beea6425a3b28989f01dd417164150ab3baab98dcbf04def8"},"Type":"cosign container image signature"},"Optional":null}
注意: 本节内容已过时。
注意: 大多数验证工作流需要定期从 TUF 仓库请求服务密钥。 对于使用公共实例进行签名的气隙验证,您需要从生产 TUF 仓库中获取 受信任根 文件。该文件的内容会未经通知而变更。如果不使用 TUF,您需要 构建自己的机制来保持此文件的气隙副本处于最新状态。
Cosign 可以通过验证 bundle 来执行完全离线验证,该 bundle 通常作为镜像清单上的注解分发。
只要此注解存在,就可以进行离线验证。
此 bundle 注解在无密钥签名中始终默认包含,因此默认的 cosign sign 功能将包含离线验证所需的所有材料。
要在气隙环境中验证镜像,镜像和签名必须可在本地文件系统上获取。
可以使用 cosign save 将镜像保存到本地(注意,此步骤必须在有网络连接的情况下完成):
cosign initialize # This will pull in the latest TUF root
cosign save $IMAGE_NAME --dir ./path/to/dir
现在,在气隙环境中,可以验证此本地镜像:
cosign verify \
--certificate-identity $CERT_IDENTITY \
--certificate-oidc-issuer $CERT_OIDC_ISSUER \
--offline=true \
--new-bundle-format=false \ # for artifacts signed without the new protobuf bundle format
--trusted-root ~/.sigstore/root/tuf-repo-cdn.sigstore.dev/targets/trusted_root.json \ # default location of trusted root
--local-image ./path/to/dir
你需要传入 $CERT_IDENTITY 和 $CERT_OIDC_ISSUER 的预期值,以正确验证此镜像。
如果你使用密钥对进行签名,只要本地存在公钥材料,同样的命令即可生效:
cosign verify --key cosign.pub --offline --local-image ./path/to/dir
使用无密钥数据块签名(不带 --key 的 cosign sign-blob),并依据预期的签名者身份进行验证:
$ cosign sign-blob artifact --bundle artifact.sigstore.json --yes
$ cosign verify-blob artifact \
--bundle artifact.sigstore.json \
--certificate-identity "https://github.com/ORG/REPO/.github/workflows/release.yml@refs/heads/main" \
--certificate-oidc-issuer "https://token.actions.githubusercontent.com"
如果您在使用 Cosign 时遇到问题,首先请确保您使用的是最新版本:Cosign 项目积极支持最新版本以及 v2 系列中的上一个版本。
failed to verify timestamps: threshold not met for verified log entry integrated timestamps: 0 < 1:您可能正在验证需要 RFC3161 时间戳支持的签名
--use-signed-timestampsno signatures found:您可能正在验证需要 Rekor v2 透明日志支持的镜像签名
OCI 注册表不仅可用于存储容器镜像!
Cosign 还包含一些实用工具,用于使用 OCI 协议发布通用工件,包括二进制文件、脚本和配置文件。
本节展示如何利用这些工具构建一个易于使用、向后兼容的工件分发系统,并与 Sigstore 的其他部分良好集成。
有关更多信息,请参阅文档。
您可以使用 cosign upload blob 发布工件:
$ echo "my first artifact" > artifact
$ BLOB_SUM=$(shasum -a 256 artifact | cut -d' ' -f 1) && echo "$BLOB_SUM"
c69d72c98b55258f9026f984e4656f0e9fd3ef024ea3fac1d7e5c7e6249f1626
$ BLOB_NAME=my-artifact-$(uuidgen | head -c 8 | tr 'A-Z' 'a-z')
$ BLOB_URI=ttl.sh/$BLOB_NAME:1h