
cosign 根命令完全指南容器签名、验证与 OCI 注册表存储【免费下载链接】cosignCode signing and transparency for containers and binaries项目地址: https://gitcode.com/GitHub_Trending/co/cosign本指南以当前仓库doc/cosign.mdcosign 根命令 CLI 参考为骨架结合源码、子命令文档与签名规范系统讲解 cosign 的全局选项、全部子命令、签名存储机制与常见问题排查。读完本文你将掌握 cosign 的命令行体系能够独立完成容器镜像的密钥签名与无密钥keyless签名、验证、签名存储定位以及基于退出码的自动化脚本编写。cosign 是什么cosign 是一个用于在 OCI 注册表中进行容器签名、验证与存储的工具A tool for Container Signing, Verification and Storage in an OCI registry它由 Sigstore 项目孵化致力于让签名成为隐形基础设施invisible infrastructure。它支持使用 Sigstore 公共 Fulcio 证书颁发机构和 Rekor 透明日志的无密钥签名keyless signing默认方式硬件令牌与 KMS 签名Vault、AWS KMS、GCP KMS、Azure Key Vault使用 cosign 生成的加密私钥/公钥对进行签名在 OCI 注册表中存储、验证容器签名自带 PKIBring-your-own PKI。从源码结构看cosign 的 CLI 采用 Cobra 命令框架实现入口在 cmd/cosign/main.go根命令在 cmd/cosign/cli/commands.go 的New()中注册全部子命令。本文档doc/cosign.md正是由该根命令生成的命令行参考。全局选项Global Options在根命令层级执行cosign --help可以看到如下全局选项-h, --help help for cosign --output-file string log output to a file -t, --timeout duration timeout for commands (default 3m0s) -d, --verbose log debug output这些选项全部声明为PersistentFlags持久标志因此对 cosign 的每一个子命令都生效。对应实现位于 cmd/cosign/cli/options/root.go选项短标志类型默认值说明--output-file—string空将日志输出重定向到指定文件--timeout-tduration3m0s命令执行超时时间--verbose-dboolfalse输出调试日志--output-file在根命令的PersistentPreRunE中cosign 会用os.Create创建该文件并把os.Stdout指向它参见 cmd/cosign/cli/commands.go命令结束后再恢复标准输出。适合把冗长日志落盘留存。--timeout默认 3 分钟。与 Sigstore 各公共服务Fulcio、Rekor、OIDC交互耗时较长网络环境不佳时可调大例如cosign sign --timeout 5m IMAGE。--verbose开启后会将 go-containerregistry 的logs.Debug输出到 stderr便于排查注册表交互问题。标志归一化cert 系列别名根命令还注册了一个全局标志归一化函数cmd/cosign/cli/commands.go把历史遗留的短名自动映射为长名--cert→--certificate--cert-email→--certificate-email--cert-chain→--certificate-chain--cert-oidc-issuer→--certificate-oidc-issuer--output-cert→--output-certificate--cert-identity→--certificate-identity这保证了旧脚本中--cert-identity等写法仍能正常工作。子命令全景一套命令覆盖完整供应链签名闭环根命令注册了以下子命令见 cmd/cosign/cli/commands.go 与doc/cosign.md的 SEE ALSO 段落子命令一句话说明所属环节cosign attest为指定容器镜像附加in-toto断言签名/断言cosign attest-blob为指定 blob 附加断言签名/断言cosign bundle与 Sigstore protobuf bundle 交互验证材料cosign clean移除镜像上的所有签名管理cosign completion生成 shell 补全脚本辅助cosign download下载制品及其附加产物签名、SBOM、断言获取cosign env打印 cosign 环境变量诊断cosign generate-key-pair生成密钥对密钥管理cosign import-key-pair导入 PEM 编码的 RSA 或 EC 私钥密钥管理cosign initialize初始化 Sigstore 根TUF获取可信证书与密钥目标信任初始化cosign load将磁盘上已签名的镜像加载到远程注册表传输cosign login登录注册表注册表cosign piv-tool管理硬件令牌YubiKey 等密钥管理cosign pkcs11-tool从 PKCS11 令牌检索信息密钥管理cosign public-key从密钥对中导出公钥密钥管理cosign save将容器镜像及关联签名保存到磁盘指定目录传输cosign sign为指定容器镜像签名签名cosign sign-blob为指定 blob 签名输出 base64 编码签名到 stdout签名cosign signing-config与 Sigstore protobuf signing config 交互配置cosign tree展示镜像的供应链安全产物签名、SBOM、断言查看cosign trusted-root与 Sigstore protobuf trusted root 交互信任cosign verify验证指定容器镜像上的签名验证cosign verify-attestation验证指定容器镜像上的断言验证cosign verify-blob验证指定 blob 上的签名验证cosign verify-blob-attestation验证指定 blob 上的断言验证cosign version打印版本辅助注login、completion分别由 go-containerregistry 的 crane auth 与 autocomplete 库提供见 cmd/cosign/cli/commands.go。核心实操一无密钥签名与验证容器镜像签名keyless signingcosign 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. ... 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?... Successfully verified SCT... tlog entry created with index: 12086900 Pushing signature to: $IMAGE其底层流程是cosign 生成临时密钥 → 通过 OIDC 交互登录使用邮箱→ 向 Fulcio 证书颁发机构申请代码签名证书证书主体与登录邮箱一致→ 将签名与证书写入 Rekor 透明日志 → 把签名上传到 OCI 注册表中镜像旁边。请务必基于镜像摘要sha256:...而不是标签:latest签名否则可能签错对象。cosign sign的完整参数见 doc/cosign_sign.md常用的有--key key path|kms uri使用本地密钥、KMS URIazurekms://、awskms://、gcpkms://、hashivault://、k8s://或环境变量密钥env://[ENV_VAR]-a keyvalue附加签名注解--recursive/-r多架构镜像连同其引用的每个离散镜像一并签名--tlog-uploadfalse跳过透明日志上传--uploadfalse仅本地签名不上传--fulcio-auth-flow指定 OIDC 流程normal|device|token|client_credentials--sk/--slot使用硬件安全密钥默认槽位signatureCOSIGN_DOCKER_MEDIA_TYPES1在不完全支持 OCI media types 的注册表上回退到传统类型。验证keylesscosign verify $IMAGE --certificate-identity$IDENTITY --certificate-oidc-issuer$OIDC_ISSUERkeyless 流程必须显式声明预期的证书主体--certificate-identity与证书签发者--certificate-oidc-issuer例如 GitHub Actions 场景为cosign verify-blob artifact \ --bundle artifact.sigstore.json \ --certificate-identity https://github.com/ORG/REPO/.github/workflows/release.ymlrefs/heads/main \ --certificate-oidc-issuer https://token.actions.githubusercontent.com也可以用正则替代精确匹配--certificate-identity-regexp、--certificate-oidc-issuer-regexp。cosign verify的完整参数见 doc/cosign_verify.md包括--key公钥文件/URL/KMS/K8s Secret/GitLab、--local-image验证cosign save保存的本地镜像、--output json|text、--max-workers默认 10等。使用公钥验证$ 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}只要至少一个匹配公钥的 cosign 格式签名被找到命令即返回 0。注意 payload 中内嵌了镜像摘要因此分离式detached签名能确保覆盖正确的镜像。核心实操二blob 签名与验证blob二进制文件的 keyless 签名与验证同样开箱即用$ 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.ymlrefs/heads/main \ --certificate-oidc-issuer https://token.actions.githubusercontent.com--bundle会把离线验证所需的全部材料Rekor 日志条目、证书、时间戳等写入一个 JSON 文件便于与工件一起分发--yes跳过非破坏性操作的确认提示。核心实操三离线air-gapped环境验证keyless 签名默认会在镜像 manifest 的注解中携带一个 bundle见 签名规范 的 Properties 一节因此可以完全离线验证cosign initialize # 拉取最新 TUF root需网络 cosign save $IMAGE_NAME --dir ./path/to/dir # 把镜像连同签名保存到本地目录需网络然后在离线环境中cosign verify \ --certificate-identity $CERT_IDENTITY \ --certificate-oidc-issuer $CERT_OIDC_ISSUER \ --offlinetrue \ --new-bundle-formatfalse \ # 针对未使用新 protobuf bundle 格式签名的制品 --trusted-root ~/.sigstore/root/tuf-repo-cdn.sigstore.dev/targets/trusted_root.json \ # trusted root 默认位置 --local-image ./path/to/dir使用密钥对签名时同理cosign verify --key cosign.pub --offline --local-image ./path/to/dir。签名存储规范签名到底存在哪里cosign 把签名存放在 OCI 注册表中并采用基于被签名对象 sha256 的命名约定定位签名索引tag 机制规则忽略主机名中的端口把:替换为-把替换为:再追加.sig后缀。例如镜像reg.example.com/ubuntusha256:703218c0465075f4425e58fac086e09e1de5c340b12976ab9eb8ad26615c3715的签名位于reg.example.com/ubuntu:sha256-703218c0465075f4425e58fac086e09e1de5c340b12976ab9eb8ad26615c3715.sig更规范的表述见 签名规范 的 Tag-based Discovery 一节对象引用先解析为摘要再把sha256:abcdef...编码进 tag:→-追加.sig。指定签名仓库COSIGN_REPOSITORY默认签名存储在与镜像相同的仓库中可用环境变量COSIGN_REPOSITORY指定其他仓库$ export COSIGN_REPOSITORYgcr.io/my-new-repo $ cosign sign --key cosign.key $IMAGE_URI_DIGESTgcr.io/dlorenc-vmtest2/demo的签名将存放在gcr.io/my-new-repo/demo:sha256-DIGEST.sig。注意不同注册表对repository格式要求不同GCRgcr.io/$REPO即可Artifact Registry必须给完整镜像名$LOCATION-docker.pkg.dev/$PROJECT/$REPO/$STORAGE_IMAGE仅给仓库名不生效。存储方式的已知权衡签名与镜像之间只是弱引用注册表不理解该关系删除镜像时签名不会被垃圾回收多签名列表的写入采用读-追加-写模式存在竞态条件并发签名时最后写入者胜出优点是签名对象易于复制迁移缺点是不会自动跟随镜像。签名与密钥的格式私钥cosign 仅生成 ECDSA-P256 密钥、使用 SHA256 哈希私钥以 PEM 编码 PKCS8 格式存储并使用 scrypt 作为 KDF、nacl/secretbox 加密PEM 头为ENCRYPTED SIGSTORE PRIVATE KEY-----BEGIN ENCRYPTED SIGSTORE PRIVATE KEY----- ... -----END ENCRYPTED SIGSTORE PRIVATE KEY-----公钥PEM 编码的标准 PKIX 格式头为PUBLIC KEY-----BEGIN PUBLIC KEY----- MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAELigCnlLNKgOglRTx1D7JhI7eRw99 QolE9Jo4QUxnbMy5nUuBLUZF9qqfm/Dg1BNeHRThHzWh2ki9vAEgWEDOw -----END PUBLIC KEY-----Payload 格式cosign 采用 Red Hat Simple Signing 格式可用cosign generate $IMAGE_URI_DIGEST生成{ critical: { identity: { docker-reference: testing/manifest }, image: { Docker-manifest-digest: sha256:20be...fe55 }, type: cosign container image signature }, optional: { creator: Bob the Builder, timestamp: 1458239713 } }在 OCI manifest 中payload 作为 blob 被引用media type 为application/vnd.dev.cosign.simplesigning.v1json签名以 base64 形式存放在 layer 注解dev.cosignproject.cosign/signature中证书与证书链则存放在dev.cosignproject.cosign/certificate与dev.cosignproject.cosign/chain注解中详见 签名规范 的 OCI Image Manifest V1 一节。签名与镜像的绑定关系为两级哈希Sign(sha256(SimpleSigningPayload(sha256(Image Manifest))))哈希算法与注册表一致实践中即 sha256。退出码让验证结果可脚本化cosign 为验证类错误定义了稳定的退出码详见 doc/cosign_exit_codes.md 与 cmd/cosign/errors/exit_code_lookup.go退出码含义10镜像无签名导致验证失败ErrNoSignaturesFound11标签不存在导致验证失败ErrImageTagNotFound12无匹配签名导致验证失败ErrNoMatchingSignatures13签名上未找到证书导致验证失败ErrNoCertificateFoundOnSignature其余错误默认退出码为 1。入口在 cmd/cosign/main.go当错误实现了CosignError接口时按ExitCode()退出否则log.Fatalf以 1 退出。CI 流水线中可直接用echo $?区分不同的失败原因。环境变量与诊断执行cosign env可打印全部已注册的 cosign 环境变量描述与期望值敏感变量默认以******遮蔽可用--show-descriptions --show-sensitive-values展开实现见 cmd/cosign/cli/env.go 与 cmd/cosign/cli/options/env.go。常用变量包括COSIGN_REPOSITORY指定签名存储仓库COSIGN_DOCKER_MEDIA_TYPES1在不支持 OCI media types 的注册表上回退到 Docker 媒体类型COSIGN_EXPERIMENTAL开启实验特性相关代码见 cmd/cosign/cli/options/experimental.go。此外所有带-的 CLI 标志都可以用环境变量形式覆盖根命令的 Viper 绑定逻辑cmd/cosign/cli/options/root.go会把--some-flag映射为COSIGN_SOME_FLAG。常见问题排查failed to verify timestamps: threshold not met for verified log entry integrated timestamps: 0 1签名的验证需要 RFC3161 时间戳支持。升级到最新版 cosign若使用 Cosign 2.6.x可加--use-signed-timestamps。no signatures found可能是该镜像签名需要 Rekor v2 透明日志支持请升级到最新版 cosign。签名时 HTTP 错误签名依赖多个 Sigstore 公共服务Fulcio/Rekor/OIDC服务故障时重试通常有效。小结从根命令的四个全局选项到覆盖密钥管理—签名—验证—存储—传输—审计全链路的 26 个子命令cosign 把容器与二进制的代码签名做成了标准化的供应链安全基础设施。本文介绍的签名存储定位规则sha256-DIGEST.sigtag、退出码约定与离线验证流程可直接用于 CI/CD 与制品发布的安全审计实践更底层的签名格式与发现机制细节可继续阅读 签名规范 与 签名存储示意图。【免费下载链接】cosignCode signing and transparency for containers and binaries项目地址: https://gitcode.com/GitHub_Trending/co/cosign创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考