# cosign: Keyless OIDC Signing in CI

> cosign keyless signing uses a CI OIDC token and Fulcio/Rekor instead of a stored key. Reference for the setup, identity flags, and CI errors.

Source: https://latchkey.dev/learn/command-reference/cosign-keyless-oidc  
Updated: 2026-06-30

cosign keyless signing uses your CI OIDC identity with Fulcio and Rekor, so no private key is stored anywhere.

Keyless signing removes the burden of managing a private key. cosign exchanges the runner OIDC token for a short-lived certificate from Fulcio and records the signature in the Rekor transparency log.

## What it does

With COSIGN_EXPERIMENTAL not even required on current versions, cosign sign without --key triggers keyless mode: it requests an OIDC token from the CI provider, gets a short-lived signing certificate from Fulcio bound to that identity, signs, and uploads the entry to Rekor. Verification later checks the certificate identity and issuer.

## Common usage

```Terminal
# GitHub Actions: grant id-token: write, then
cosign sign --yes ghcr.io/org/app@${DIGEST}
# verify by expected identity
cosign verify \
  --certificate-identity-regexp 'https://github.com/org/.+' \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com \
  ghcr.io/org/app@${DIGEST}
```

## Options

| Flag / setting | What it does |
| --- | --- |
| id-token: write | GitHub permission that exposes the OIDC token |
| --yes | Skip the browser/confirmation flow in CI |
| --certificate-identity | Expected signer identity on verify |
| --certificate-oidc-issuer | Expected OIDC issuer URL on verify |
| --oidc-provider | Force a provider when several are present |

## In CI

In GitHub Actions, set permissions: id-token: write at the job so cosign can mint the OIDC token, and pass --yes. On verify, always pin both --certificate-identity (or -regexp) and --certificate-oidc-issuer; without them any valid Sigstore signature would pass. This is the recommended modern approach over long-lived keys.

## Common errors in CI

"getting key from Fulcio: no identity token provided" means the OIDC token is missing; add id-token: write permission. "error obtaining OIDC token" outside the supported providers means cosign cannot detect the environment. On verify, "none of the expected identities matched" means the --certificate-identity or issuer does not match the signing identity.

## FAQ

### cosign: Keyless OIDC Signing in CI?

Keyless signing removes the burden of managing a private key. cosign exchanges the runner OIDC token for a short-lived certificate from Fulcio and records the signature in the Rekor transparency log.

### What it does?

With COSIGN_EXPERIMENTAL not even required on current versions, cosign sign without --key triggers keyless mode: it requests an OIDC token from the CI provider, gets a short-lived signing certificate from Fulcio bound to that identity, signs, and uploads the entry to Rekor. Verification later checks the certificate identity and issuer.

### In CI?

In GitHub Actions, set permissions: id-token: write at the job so cosign can mint the OIDC token, and pass --yes. On verify, always pin both --certificate-identity (or -regexp) and --certificate-oidc-issuer; without them any valid Sigstore signature would pass. This is the recommended modern approach over long-lived keys.

### Common errors in CI?

"getting key from Fulcio: no identity token provided" means the OIDC token is missing; add id-token: write permission. "error obtaining OIDC token" outside the supported providers means cosign cannot detect the environment.

---

Latchkey runs CI/CD that repairs its own failures. Agent entry points: https://latchkey.dev/agent.txt, https://latchkey.dev/openapi.json, https://latchkey.dev/llms.txt
