cosign sign: Sign a Container Image
cosign sign signs a container image, storing the signature in the registry alongside the image.
cosign sign is the core signing command. It signs by digest and pushes the signature as an artifact next to the image, so anyone can later verify provenance.
What it does
cosign sign computes the image digest, creates a signature with the given key (or keylessly), and stores it in the registry under a derived tag. Signing by digest is required because a tag is mutable; cosign resolves the tag to a digest and signs that.
Common usage
# key-based, non-interactive
COSIGN_PASSWORD=${COSIGN_PASSWORD} \
cosign sign --key cosign.key --yes \
ghcr.io/org/app@sha256:abc123...
# sign by digest captured from the push step
cosign sign --key cosign.key --yes ghcr.io/org/app@${DIGEST}Options
| Flag | What it does |
|---|---|
| --key <ref> | Signing key: file, env://, or kms:// |
| --yes | Skip the confirmation prompt (required in CI) |
| --recursive | Sign every image in a multi-arch index |
| -a key=value | Add an annotation to the signature |
| --tlog-upload | Upload to the transparency log (default true) |
| COSIGN_PASSWORD | Password for the private key |
In CI
Always pass --yes or cosign waits on a confirmation prompt and hangs the job. Sign the digest the push step printed rather than a tag, since the tag can move. For multi-arch images, add --recursive so each platform image is signed, not just the index.
Common errors in CI
"signing ghcr.io/org/app:tag: GET ... 403" means the registry token lacks write scope for signatures; log in with write permission. "no provider found for that key reference" means a malformed --key. A prompt that never returns means --yes was omitted. Signing a tag warns that it should be a digest.