cosign attest "signing" failed generating an attestation in CI
cosign attest wraps your predicate (an SBOM or provenance) in an in-toto statement and signs it. If no signing key is available and keyless has no OIDC token, cosign fails before it can attach the attestation.
What this error means
cosign attest exits with "signing ... failed", "no key provided", or "getting signer" while trying to attach an SBOM or provenance attestation to an image.
cosign attest --predicate sbom.json --type cyclonedx ghcr.io/acme/app@sha256:...
Error: signing ghcr.io/acme/app: getting signer: no key provided, please provide a key or enable keyless signingCommon causes
No signing key and keyless not enabled
Without --key or a keyless flow, cosign has no way to sign. In older cosign versions keyless also required COSIGN_EXPERIMENTAL=1.
Keyless has no OIDC identity token
Keyless signing needs an ambient OIDC token. Without id-token: write permission in the workflow, there is no token to exchange with Fulcio.
How to fix it
Enable keyless signing with an OIDC token
- Grant
id-token: writeso the workflow can mint an OIDC token. - Use a recent cosign (v2+) where keyless is the default (no COSIGN_EXPERIMENTAL needed).
- Attest against the image digest, not a mutable tag.
permissions:
id-token: write
packages: write
steps:
- uses: sigstore/cosign-installer@v3
- run: cosign attest --yes --predicate sbom.json --type cyclonedx ghcr.io/acme/app@${{ steps.build.outputs.digest }}Or provide an explicit key
For key-based signing, pass the private key and its password from secrets instead of relying on keyless.
cosign attest --key env://COSIGN_KEY --predicate sbom.json --type cyclonedx ghcr.io/acme/app@sha256:...How to prevent it
- Add
id-token: writefor keyless signing in the workflow permissions. - Upgrade to cosign v2+ so keyless is default without COSIGN_EXPERIMENTAL.
- Always attest against the immutable image digest.