Open-Source Wikis

/

Cosign

/

How to contribute

/

Debugging

sigstore/cosign

Debugging

A grab-bag of things to try when cosign isn't doing what you expect.

Turn the volume up

cosign -d verify $IMAGE ...
# or
cosign --verbose verify $IMAGE ...

-d / --verbose flips ro.Verbose in cmd/cosign/cli/options/root.go, which routes go-containerregistry's logs.Debug to stderr. That surfaces every HTTP request to the OCI registry, including the deterministic signature-tag lookups.

For the new bundle format, --debug-bundle (where supported) prints the raw protobuf bundle.

Inspect what's attached to an image

cosign tree $IMAGE                    # show all attached signatures, attestations, SBOMs
cosign triangulate $IMAGE             # print the deterministic .sig tag
crane manifest $(cosign triangulate $IMAGE)  # raw manifest of the signature artifact

cosign tree is implemented in cmd/cosign/cli/tree.go. cosign triangulate is in cmd/cosign/cli/triangulate.go.

Verify failed: certificate identity mismatch

The most common keyless-verify error. Cosign requires both --certificate-identity (or -regexp) and --certificate-oidc-issuer (or -regexp) on every cosign verify/verify-attestation/verify-blob invocation that uses keyless signatures. The actual identity is the SAN of the leaf cert in the bundle:

cosign verify $IMAGE \
  --certificate-identity-regexp ".*" \
  --certificate-oidc-issuer-regexp ".*" \
  --output text 2>&1 | head

Then inspect the certificate identity it printed.

TUF / trusted root issues

If verification complains about Fulcio CA or Rekor public-key mismatches, refresh your local TUF cache:

cosign initialize    # re-pulls trusted_root.json from the public-good TUF repo
ls ~/.sigstore/root  # default cache location

Override with TUF_ROOT, TUF_MIRROR, or TUF_ROOT_JSON (see pkg/cosign/env/env.go). For air-gapped scenarios, point --trusted-root at a hand-curated trusted_root.json.

OIDC / browser problems

The keyless flow opens a browser and runs an OAuth code-grant against oauth2.sigstore.dev. If you're on a headless box:

  • Use the device flow: cosign sign --oidc-disable-providers --oidc-disable-ambient ... (or omit, then watch stderr — it falls back to a printed code).
  • Pre-supply a token: set SIGSTORE_ID_TOKEN to a JWT and cosign will skip the browser entirely.
  • In CI: rely on the ambient providers — pkg/providers/github/, pkg/providers/gitlab/, pkg/providers/buildkite/, pkg/providers/spiffe/, pkg/providers/google/, pkg/providers/filesystem/, pkg/providers/envvar/. They register themselves and Enabled() returns true automatically when the right env signals are present.

Registry auth issues

Cosign reuses the user's docker keychain via go-containerregistry. If you can docker push to the target registry, cosign can read/write signatures there. To force a credential refresh:

cosign login $REGISTRY

cosign login is provided by cranecmd.NewCmdAuthLogin("cosign") (see the bottom of cmd/cosign/cli/commands.go).

Errors with exit codes

cmd/cosign/main.go knows about cosignError.CosignError (defined in cmd/cosign/errors/) — those carry an exit code. The codes are documented in doc/cosign_exit_codes.md. If you're scripting cosign and need to differentiate "image not found" from "signature mismatch", these are the codes to switch on.

Re-creating the prod-like state locally

The test/ driver scripts spin up ghcr.io/sigstore/scaffolding, which gives you Fulcio+Rekor+TSA in a KinD cluster. That's also what the kind-verify-attestation.yaml workflow does. Reusing the same scaffolding locally is the fastest way to repro a CI failure.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Debugging – Cosign wiki | Factory