
cosign v3.1.3
容器和二进制的代码签名与透明度
cosign
使用 Sigstore 对 OCI 容器(及其他制品)进行签名!
Cosign 旨在让签名成为无形的基础设施。
Cosign 支持:
- 使用 Sigstore 公共 Fulcio 证书颁发机构和 Rekor 透明日志进行“无密钥签名”(默认)
- 硬件与 KMS 签名
- 使用 cosign 生成的加密私钥/公钥对进行签名
- 在 OCI 注册表中进行容器签名、验证与存储。
- 自带 PKI
信息
Cosign 是 sigstore 项目的一部分。
我们还使用一个 slack 频道!
点击此处获取邀请链接。
安装
有关 Homebrew、Arch、Nix、GitHub Action 和 Kubernetes 的安装,请参阅安装文档。
对于 Linux 和 macOS 二进制文件,请参见 GitHub 发布资产。
🚨 如果您正在从我们的 GCS 存储桶下载 cosign 的发布版本,请查阅 2023 年 7 月 31 日的弃用通知以获取更多信息 🚨
开发者安装
如果您有 Go 1.22+,可以设置开发环境:```shell $ git clone https://github.com/sigstore/cosign $ cd cosign $ go install ./cmd/cosign $ $(go env GOPATH)/bin/cosign
## 参与贡献
如果你有兴趣为 `cosign` 做贡献,请阅读[贡献文档](https://github.com/sigstore/cosign/blob/main/CONTRIBUTING.md)。
未来的 Cosign 开发将专注于下一个主要版本,该版本将基于 [sigstore-go](https://github.com/sigstore/sigstore-go)。维护者将专注于 sigstore-go 内的功能开发。我们感谢对 sigstore-go 的贡献,特别是关于自带密钥(bring-your-own keys)和签名方面的贡献。请参阅[问题追踪器](https://github.com/sigstore/sigstore-go/issues)以获取适合新手的问题。
Cosign 2.x 是一个稳定版本,将继续接收定期的功能更新和错误修复。范围小且规模小的 PR 最有可能被快速审查。
显著修改或破坏 API 的 PR 将不被接受。规模较大但不引入破坏性变更的 PR 可能会被接受,但优先级将低于 sigstore-go 中的 PR。
## Dockerfile
以下是如何通过 ghcr.io/sigstore/cosign/cosign 镜像在 Dockerfile 中安装和使用 cosign:```shell
FROM ghcr.io/sigstore/cosign/cosign:v2.4.1 as cosign-bin
# Source: https://github.com/chainguard-images/static
FROM cgr.dev/chainguard/static:latest
COPY --from=cosign-bin /ko-app/cosign /usr/local/bin/cosign
ENTRYPOINT [ "cosign" ]
快速开始
以下展示如何:
- 使用默认基于身份的“无密钥签名”方法对容器镜像进行签名(参见文档了解更多信息)
- 验证容器镜像
- 探索更广泛的无密钥 blob 签名/验证流程,详见 Sigstore Cosign 快速入门
对容器进行签名并将签名存储在镜像仓库中
请注意,您应始终基于镜像摘要(@sha256:...)而非标签(:latest)进行签名,否则可能会签名到非预期的内容!```shell
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。 请注意,这些签名负载包含容器映像的摘要,这样我们就能确保这些"分离"签名覆盖了正确的映像。```shell $ 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仓库中获取[trusted root](https://github.com/sigstore/root-signing/blob/main/targets/trusted_root.json)文件。该文件的内容会随时更改,恕不另行通知。如果不使用TUF,您需要自行构建机制来保持您的气隙副本文件是最新的。
Cosign可以通过验证[包](https://github.com/sigstore/cosign/blob/main/specs/SIGNATURE_SPEC.md#properties)来实现完全离线验证,该包通常作为镜像清单的注解分发。只要存在此注解,就可以进行离线验证。默认情况下,无密钥签名始终包含此包注解,因此默认的`cosign sign`功能将包含离线验证所需的所有材料。
要在气隙环境中验证镜像,镜像和签名必须本地存储在文件系统中。
可以使用`cosign save`将镜像保存到本地(注意,此步骤必须有网络连接):```
cosign initialize # This will pull in the latest TUF root
cosign save $IMAGE_NAME --dir ./path/to/dir
现在,在隔离网络环境中,可以验证这个本地镜像:```shell
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
基于身份的 blob 签名与验证
使用无密钥 blob 签名(cosign sign-blob 不加 --key)并根据预期的签名者身份进行验证:```shell
$ 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 系列中的最后一个版本。
#### 常见问题及解决方法
1. 验证失败,显示 `failed to verify timestamps: threshold not met for verified log entry integrated timestamps: 0 < 1`:你可能正在验证一个需要 RFC3161 时间戳支持的签名
* 升级到最新的 Cosign 或
* 对于 Cosign 2.6.x,使用 `--use-signed-timestamps`
1. 验证失败,显示 `no signatures found`:你可能正在验证一个需要 Rekor v2 透明日志支持的镜像签名
* 升级到最新的 Cosign
1. 签名失败并出现 HTTP 错误:使用 Cosign 签名依赖于多个 Sigstore 服务。如果其中任何一个服务失败,重试可能是一个有用的解决方法——也欢迎针对特定失败提交问题
#### 我是其他问题
请创建一个 [issue](https://github.com/sigstore/cosign/issues/new/choose) 或通过 [slack 频道](#info) 询问。
## 与其他工件一起使用
OCI 仓库不仅用于存储容器镜像!
`Cosign` 还包含一些用于发布通用工件的工具,包括二进制文件、脚本和配置文件,使用 OCI 协议。
本节展示如何利用这些功能构建一个易于使用、向后兼容的工件分发系统,与 Sigstore 其余部分良好集成。
有关更多信息,请参阅 [文档](https://docs.sigstore.dev/cosign/signing/other_types/)。
### Blobs
你可以使用 `cosign upload blob` 发布一个工件:```shell
$ 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