cosign verify-blob-attestation 完全指南:基于密钥、KMS 与 keyless 的 blob 断言验证
2026/9/17 16:33:17 网站建设 项目流程

cosign verify-blob-attestation 完全指南:基于密钥、KMS 与 keyless 的 blob 断言验证

【免费下载链接】cosignCode signing and transparency for containers and binaries项目地址: https://gitcode.com/GitHub_Trending/co/cosign

本指南系统讲解 sigstore cosign 的verify-blob-attestation子命令:如何对 blob 文件上携带的 in-toto 格式 attestation(断言)进行签名验证,涵盖 keyless(Fulcio 证书 + OIDC 身份)、公钥、Azure/AWS/GCP/HashiCorp Vault KMS 以及硬件安全密钥等全部验证路径,并深入源码揭示其参数校验、断言摘要比对与 predicate 类型匹配的底层实现。读完本文,你将能独立完成 blob attestation 从生成 bundle 到离线/在线验证的完整闭环。本文对应的官方命令参考文档位于 doc/cosign_verify-blob-attestation.md,核心命令入口见 cmd/cosign/cli/verify/verify_blob_attestation.go。

命令定位:为什么要验证 blob 上的 attestation

cosign verify-blob-attestation用于验证「作用于某个 blob 输入」的 attestation。与cosign verify-blob(验证 blob 的普通签名)不同,attestation 的签名材料以DSSE 信封(envelope)形式存在,内容遵循 in-toto Statement 规范,因此验证逻辑需要额外完成两件事:一是验证 DSSE 信封的签名有效性,二是校验 Statement 中 subject 的摘要与所给 blob(或 --digest)一致,三是确认 predicate 类型匹配预期。

该命令的官方 Synopsis 明确了两点输入约束:

  • 签名材料通过--bundle标志提供(bundle 文件即cosign attest-blob生成、或从远端拉取的 Sigstore bundle);
  • blob 可以通过文件路径指定(也支持不传 blob、仅凭--digest进行验证)。

从源码结构看,命令的 CLI 参数定义在 cmd/cosign/cli/options/verify.go 的VerifyBlobAttestationOptions,实际执行逻辑则在VerifyBlobAttestationCommand.Exec。Exec 入口处 cmd/cosign/cli/verify/verify_blob_attestation.go 依次做了四类前置校验,是理解命令行为的关键:

  • 必须提供--signature--bundle之一,否则报错please specify path to the DSSE envelope signature via --signature or --bundle
  • 必须提供密钥/证书/bundle 三者之一(--key--sk--certificate--bundle),否则报错provide a key with --key or --sk, a certificate to verify against with --certificate, or a bundle with --bundle
  • --key--certificate-identity/--certificate-identity-regexp互斥(不可同时指定),违反时报KeyAndIdentityParseError
  • --key--sk互斥,违反时报KeyParseError

这些互斥规则同样被单元测试覆盖,见 cmd/cosign/cli/verify/verify_blob_attestation_test.go 的TestVerifyBlobAttestationMutuallyExclusiveFlags

典型用法示例(对应官方 Examples)

官方文档给出了五种验证方式,均可直接复制运行(<blob>替换为实际 blob 文件路径):

# 通用形式:bundle + 证书身份 + OIDC issuer cosign verify-blob-attestation --bundle <path> --certificate-identity <identity> --certificate-oidc-issuer <issuer> <blob> # keyless 模式验证 blob attestation cosign verify-blob-attestation --bundle artifact.sigstore.json --certificate-identity foo@example.com --certificate-oidc-issuer https://accounts.google.com <blob> # 使用公钥验证 cosign verify-blob-attestation --bundle artifact.sigstore.json --key cosign.pub <blob> # Azure KMS cosign verify-blob-attestation --bundle artifact.sigstore.json --key azurekms://[VAULT_NAME][VAULT_URI]/[KEY] <blob> # AWS KMS cosign verify-blob-attestation --bundle artifact.sigstore.json --key awskms://[ENDPOINT]/[ID/ALIAS/ARN] <blob> # GCP KMS cosign verify-blob-attestation --bundle artifact.sigstore.json --key gcpkms://projects/[PROJECT]/locations/global/keyRings/[KEYRING]/cryptoKeys/[KEY] <blob> # HashiCorp Vault cosign verify-blob-attestation --bundle artifact.sigstore.json --key hashivault://[KEY] <blob>

注意 keyless 模式与公钥/KMS 模式的区别:keyless 验证需要同时提供--certificate-identity(或--certificate-identity-regexp)与--certificate-oidc-issuer(或--certificate-oidc-issuer-regexp),这在 options/certificate.go 的Identities()方法中强制校验;而使用--key时无需这些身份参数,二者互斥。

完整参数参考(Options)

核心验证参数

参数类型/默认值说明
--bundle string无默认指向 bundle 文件的路径,bundle 内包含签名、证书及(可选)Rekor 包含证明与时间戳
--key string无默认公钥文件路径、KMS URI 或 Kubernetes Secret,详见KeyOpts解析
--type string"custom"指定 predicate 类型:slsaprovenanceslsaprovenance02slsaprovenance1linkspdxspdxjsoncyclonedxvulnopenvexcustom,或直接传一个 predicate URI
--check-claimstrue为 true 时校验摘要存在于 in-toto subject 中(使用提供的 digest+digestAlg,或对 blob 计算 sha256);为 false 时仅验证 DSSE 信封本身
--digest string无默认不提供 blob 时,用它替代 blob 进行 in-toto subject 校验
--digestAlg string无默认--digest配套的摘要算法(sha256/sha384/sha512
--allow-certificate-chainfalse允许 v0.3+ bundle 验证材料中包含 X.509 证书链
--use-signed-timestampsfalse验证 RFC3161 时间戳
--trusted-root string无默认Sigstore TrustedRoot JSON 文件路径(用于 bundle 验证的服务密钥与证书)
--max-workers int10并行执行的最大 worker 数

keyless 身份与证书参数

参数说明
--certificate-identity string合法 Fulcio 证书中期望的身份,支持邮箱、DNS 名、IP 与 URI;keyless 流程中与--certificate-identity-regexp二选一必填
--certificate-identity-regexp string--certificate-identity的正则替代形式,采用 Go 正则语法(RE2)
--certificate-oidc-issuer string合法 Fulcio 证书中期望的 OIDC issuer,如https://token.actions.githubusercontent.comhttps://oauth2.sigstore.dev/auth;与 regexp 版二选一必填
--certificate-oidc-issuer-regexp string上述参数的正则替代形式
--certificate-github-workflow-name stringGitHub OIDC Identity token 中workflowclaim,即执行的 workflow 名称
--certificate-github-workflow-ref stringtoken 中refclaim,即 workflow 运行基于的 git ref
--certificate-github-workflow-repository stringtoken 中repositoryclaim,即 workflow 运行所在的仓库
--certificate-github-workflow-sha stringtoken 中shaclaim,即 workflow 运行基于的 commit SHA
--certificate-github-workflow-trigger stringtoken 中event_nameclaim,即触发 workflow 运行的事件名

这些 GitHub Workflow 相关的 claim 会被写入CheckOpts并在证书扩展验证阶段比对,见 verify_blob_attestation.go 中co := &cosign.CheckOpts{...}的赋值。

安全性与信任边界参数

参数说明
--insecure-ignore-sct为 true 时不检查证书是否内嵌 SCT(证书透明度日志包含证明)
--insecure-ignore-tlog忽略透明度日志验证,用于签名未上传到日志的场景;注意未入日志的工件无法被公开验证
--sk是否使用硬件安全密钥(如 YubiKey/PIV)
--slot string安全密钥槽位,取值为authenticationsignaturecard-authenticationkey-management(默认signature
-h, --help显示帮助

父命令继承参数

参数说明
--output-file string将日志输出到指定文件
-t, --timeout duration命令超时时间,默认3m0s
-d, --verbose输出调试日志

底层验证流程:从参数到 "Verified OK"

Exec的完整流程(cmd/cosign/cli/verify/verify_blob_attestation.go)可以拆解为五个阶段:

  1. 加载验证器:调用LoadVerifierFromKeyOrCert,根据--key/--sk/--certificate构造公钥验证器。当HashAlgorithm未设置时,验证器会按密钥类型自动选择匹配的摘要算法(例如 P-521 ECDSA 密钥不会硬编码为 SHA-256),见源码中 L89-L92 的注释说明。
  2. 计算/收集摘要:若--check-claims=true且提供了 blob 路径,则打开文件(走filepath.Clean清理路径)、校验大小限制后按默认sha256(或--digestAlg指定的算法)计算摘要,并通过cosign.IntotoSubjectClaimVerifier作为 claim 验证器;若提供--digest--digestAlg则直接使用十六进制解码后的摘要。
  3. 装配信任材料SetTrustedMaterial--trusted-root、证书链、CA 根等注入CheckOpts
  4. 核心签名验证:新 bundle 格式(v0.3+)走cosign.VerifyNewBundle+sigstore-goWithArtifact/WithArtifactDigest策略;旧格式则通过static.NewAttestation组装签名对象后调用cosign.VerifyBlobAttestation(定义于 pkg/cosign/verify.go,其内部复用verifyInternal+verifyOCIAttestation)。若 bundle 内含证书,还会校验 CLI 传入的--certificate与 bundle 证书一致,不一致直接报错the cert passed in does not match the cert in the provided bundle
  5. predicate 类型检查:调用policy.AttestationToPayloadJSON将 DSSE 信封转为可消费的 predicate 负载;若返回空 payload 且无错误,说明断言不属于所给 predicate 类型,报错invalid predicate type, expected %s got %s。全部通过后输出Verified OK

新旧 bundle 格式分支

从源码看,命令同时支持两种验证路径(L209-L289):

  • 新 bundle 格式(v0.3+,默认):要求--trusted-root,通过sgbundle.LoadJSONFromPath加载 bundle,用sgverify.WithArtifact(传 blob 文件)或WithArtifactDigest(传摘要)构造 artifact 策略。选择WithoutArtifactUnsafe仅在--check-claims=false时出现。
  • 旧 bundle 格式--trusted-root与之不兼容(直接报错--trusted-root only supported with --new-bundle-format),改由FetchLocalSignedPayloadFromPath解析本地 bundle JSON 并提取base64Signature与证书。

digest 摘要算法白名单

--digestAlg仅接受sha256sha384sha512三个值,由 parseBlobHashAlgorithm 映射到crypto.Hash,且大小写敏感SHA256也会被拒绝)。对应测试见 verify_blob_attestation_test.go 的TestParseBlobHashAlgorithm,其中sha1md5、空字符串、SHA256均为错误用例。

predicate 类型解析:别名到 URI 的映射

--type的取值由 cmd/cosign/cli/options/predicate.go 的PredicateTypeMap定义。别名与底层 predicate URI 的对应关系如下:

CLI 别名predicate URI
custom(默认)cosign.sigstore.dev/attestation/v1(CosignCustomProvenanceV01)
slsaprovenancehttps://slsa.dev/provenance/v0.2
slsaprovenance02https://slsa.dev/provenance/v0.2
slsaprovenance1https://slsa.dev/provenance/v1
linkin-totolinkpredicate v1
spdx/spdxjsonin-toto SPDX predicate
cyclonedxin-toto CycloneDX predicate
vulncosign.sigstore.dev/attestation/vuln/v1
openvexOpenVEX namespace

如果传入的--type不在映射表中,ParsePredicateType会尝试将其解析为合法 URI(url.ParseRequestURI),失败则报invalid predicate type。因此你可以直接传自定义 predicate 的完整 URI 而无需依赖内置别名。注意slsaprovenanceslsaprovenance02指向同一 URI,测试用例TestVerifyBlobAttestation中错误 predicate(如customnotreallyslsaprovenance)均被正确拒绝,见 verify_blob_attestation_test.go。

验证行为细节与边界

--check-claims 的双重语义

  • --check-claims=true(默认):要求 in-toto Statement 的 subject 摘要与 blob 的实际 sha256(或--digest)匹配。测试表明,subject 为空、缺失 sha256 digest、多 subject 中没有一个匹配时均验证失败(verify_blob_attestation_test.go);而多 subject 中「至少一个」匹配即可通过。
  • --check-claims=false:只验证 DSSE 信封的签名,不关心 subject 摘要。此时即使 blob 路径指向另一个文件甚至/dev/null也能通过——这正是测试TestVerifyBlobAttestationNoCheckClaims所验证的行为(L188-L252)。

blob 大小限制

--check-claims=true且传入 blob 文件时,代码会调用payloadsize.CheckSize检查文件大小,默认上限为128MiB,定义于 internal/pkg/cosign/payload/size/size.go。可通过环境变量COSIGN_MAX_ATTACHMENT_SIZE(接受 humanize 格式,如128MB1GB)覆盖;测试override file size limit展示了设置较小上限后大 blob 被拒绝的场景(verify_blob_attestation_test.go)。

用 --digest 替代 blob

--digest--digestAlg允许你在不持有 blob 文件本身的情况下,仅凭摘要验证 attestation。测试verify with digest instead of blob直接以blobSha256完成验证(L144-L149)。源码中若同时传入 blob 与--digest,会以 blob 为准并打印警告Ignoring provided --digest in favor of provided blob

与 attest-blob 的配套使用闭环

verify-blob-attestation的典型上游是cosign attest-blob(实现见 cmd/cosign/cli/attest/attest_blob.go)。attest-blob读取 blob 计算 SHA-256 摘要,用--predicate/--statement组装 in-toto Statement 与 DSSE 信封,最终写出 bundle 文件(新格式直接写 protobuf JSON bundle;旧格式写出base64Signature+ 证书的 legacy bundle)。因此推荐工作流为:

# 1. 为 blob 生成带 attestation 的 bundle cosign attest-blob --predicate predicate.json --type slsaprovenance --bundle artifact.sigstore.json <blob> # 2. 用公钥验证(注意 attest-blob 需用对应私钥签名) cosign verify-blob-attestation --bundle artifact.sigstore.json --key cosign.pub <blob> # 3. 或 keyless 验证 cosign verify-blob-attestation --bundle artifact.sigstore.json \ --certificate-identity foo@example.com \ --certificate-oidc-issuer https://accounts.google.com <blob>

常见错误与排查速查

错误信息原因解决
please specify path to the DSSE envelope signature via --signature or --bundle未提供任何签名材料补传--bundle
provide a key with --key or --sk, a certificate to verify against with --certificate, or a bundle with --bundle无任何信任锚点至少指定 key/certificate/bundle 之一
KeyAndIdentityParseError--key--certificate-identity*同时使用二选一
KeyParseError--key--sk同时使用二选一
invalid predicate type, expected %s got %sbundle 内 predicate 与--type不匹配检查--type或改用自定义 URI
--trusted-root only supported with --new-bundle-format旧格式 + trusted-root 混用使用新 bundle 格式
--certificate-identity or --certificate-identity-regexp is required for verification in keyless modekeyless 缺少身份参数补传身份与 OIDC issuer 参数
unsupported --digestAlg--digestAlg不在白名单使用sha256/sha384/sha512
MaxLayerSizeExceededblob 超过 128MiB 上限调大COSIGN_MAX_ATTACHMENT_SIZE或改用--digest

小结

cosign verify-blob-attestation是 sigstore blob 供应链验证体系中专用于 DSSE/in-toto attestation 的校验入口,其能力覆盖 keyless、公钥、四大 KMS 与硬件安全密钥,并通过--check-claims--type--digest/--digestAlg提供细粒度控制。建议在生产实践中始终使用--bundle携带完整验证材料(签名 + 证书 + Rekor 包含证明 + 时间戳),结合--trusted-root实现可离线、可审计的强验证。命令参考的其余相关入口还包括 doc/cosign.md(全局命令索引)与 doc/cosign_attest-blob.md(对应签名侧命令)。

【免费下载链接】cosignCode signing and transparency for containers and binaries项目地址: https://gitcode.com/GitHub_Trending/co/cosign

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询