cosign generate-key-pair creates a cosign.key private key and cosign.pub public key for signing container images.
Before keyless signing existed, cosign used a key pair. It still does when you want a long-lived key, and generate-key-pair is how you create one, locally or in a KMS.
What it does
cosign generate-key-pair writes an encrypted cosign.key and a cosign.pub. The private key is protected by a password taken from the COSIGN_PASSWORD environment variable (or prompted). With a KMS or k8s reference it stores the key there instead of on disk.
Common usage
Terminal
# local key pair (password from env so it is non-interactive)
COSIGN_PASSWORD= cosign generate-key-pair
# store the key in a cloud KMS
cosign generate-key-pair --kms awskms:///alias/cosign
# store in a Kubernetes secret
cosign generate-key-pair k8s://cosign-system/cosign-key
Options
Flag / arg
What it does
--kms <ref>
Generate and store the key in a KMS provider
k8s://<ns>/<name>
Store the key pair in a Kubernetes secret
--output-key-prefix
Prefix for the cosign.key/cosign.pub files
COSIGN_PASSWORD
Env var supplying the private-key password
In CI
For non-interactive runs, set COSIGN_PASSWORD in the environment (empty is allowed for an unencrypted key in throwaway test setups, but prefer a real secret). For production, prefer KMS-backed keys or keyless OIDC signing so no private key material lives in the repo or runner.
Common errors in CI
"error getting password: EOF" means cosign tried to prompt with no TTY; set COSIGN_PASSWORD. "key already exists" means cosign.key is present; remove it or use --output-key-prefix. KMS errors like "AccessDenied" mean the runner credentials lack permission on the key alias.
Frequently asked questions
cosign generate-key-pair: Signing Keys?
Before keyless signing existed, cosign used a key pair. It still does when you want a long-lived key, and generate-key-pair is how you create one, locally or in a KMS.
What it does?
cosign generate-key-pair writes an encrypted cosign.key and a cosign.pub. The private key is protected by a password taken from the COSIGN_PASSWORD environment variable (or prompted). With a KMS or k8s reference it stores the key there instead of on disk.
In CI?
For non-interactive runs, set COSIGN_PASSWORD in the environment (empty is allowed for an unencrypted key in throwaway test setups, but prefer a real secret). For production, prefer KMS-backed keys or keyless OIDC signing so no private key material lives in the repo or runner.
Common errors in CI?
"error getting password: EOF" means cosign tried to prompt with no TTY; set COSIGN_PASSWORD. "key already exists" means cosign.key is present; remove it or use --output-key-prefix. KMS errors like "AccessDenied" mean the runner credentials lack permission on the key alias.