Verify a downloaded release before you install it
More projects now publish a Sigstore bundle (a .sigstore.json file) next to
each release binary. The bundle carries the signature, the short-lived signing
certificate and the transparency-log proof. It does not tell you whether the
signer is the one you expected. That part is yours: a valid signature from the
wrong identity is still a valid signature.
cilock verify-bundle checks a bundle under the Sigstore client verification
procedure and refuses to run without an expected identity and issuer. In this
session the prompt asks Claude to check a cosign release before installing it,
and to take the expected signer from Sigstore's documentation rather than from
the bundle.
TestifySec wrote both prompts and sent them into the session. Claude Code and
cilock ran unedited, and the recording was not changed afterwards.
What happens, step by step
-
Find the expected signer somewhere other than the bundle. Claude sends a subagent to read Sigstore's installation docs ("Verifying Cosign Releases", for cosign 3.x), which name the signer as
[email protected]with the issuerhttps://accounts.google.com. Reading the identity out of the bundle and then checking the bundle against it would prove nothing. -
Download the release and its bundle.
cosign-darwin-arm64andcosign-darwin-arm64.sigstore.jsonfrom the v3.1.3 GitHub release, withcurl. -
Verify.
cilock verify-bundle --bundle cosign-darwin-arm64.sigstore.json \ --certificate-identity [email protected] \ --certificate-oidc-issuer https://accounts.google.com \ cosign-darwin-arm64cilock prints
Verified OKand exits0. It fetched the public-good Sigstore trusted root over TUF, because no--trusted-rootwas given. -
Stop before installing. Claude reports the SHA-256 and the install command and waits. A second prompt asks for proof the check can fail first.
-
Change one bit. A copy with one bit flipped at offset 1,000,000 is refused:
invalid signature when validating ASN.1 encoded signature. -
Expect the wrong signer. The real binary checked against
[email protected]is refused:expected SAN value "[email protected]", got "[email protected]". Claude adds a test of its own: the right identity with the GitHub Actions issuer is refused too, because the identity and the issuer must both match.
What the verification requires
cilock verify-bundle requires every check the trusted root can back:
| Check | What it rules out |
|---|---|
| Signature over the file's digest | a changed or swapped binary |
Exact certificate SAN (--certificate-identity) | a valid signature from someone else |
Exact OIDC issuer (--certificate-oidc-issuer) | the same identity string minted by a different provider |
| SCT, when the root distributes CT logs | a certificate the CA never logged |
| Transparency-log entry, when the root distributes Rekor logs | a signature that was never publicly recorded |
| Signing time from a TSA timestamp or a log inclusion promise | a signature made outside the certificate's lifetime |
Neither --certificate-identity nor --certificate-oidc-issuer can be empty,
and both are exact matches. For a bundle signed with a managed key, pass
--key with the PEM public key instead. The artifact can be a file path or a
digest such as sha256:<hex>.
For a release built in GitHub Actions the identity is usually the workflow
path at a tag, for example
https://github.com/acme/app/.github/workflows/release.yml@refs/tags/v1.2.0,
with the issuer https://token.actions.githubusercontent.com. Take it from
the project's documentation or security policy, not from the bundle you are
checking.
Run it yourself
The recording used cilock built from main at commit 5b614726; the
verify-bundle command ships in CI/lock 4.6.0 and later. Verification needs
network access to fetch the Sigstore trusted root unless you pass
--trusted-root with a local trusted_root.json.
To record your own evidence about a build rather than check someone else's signature, see Release gates and Signing and identity.
Reference generated from the product documentation. Match commands and support details to your installed release.