Keyless Signing with Sigstore

SecuritySupply ChainDevSecOps

The oldest problem in code signing isn't the cryptography — it's the key. Somebody has to generate a private signing key, store it somewhere safe, rotate it, keep it out of CI logs, and pray it never leaks. Sigstore's keyless signing throws that whole problem out. Instead of a durable private key, you sign with a short-lived certificate bound to an OIDC identity — your CI workflow, your Google account, a service identity — and the key material evaporates after a few minutes. There's no signing key to steal because none survives the operation.

I've cleaned up after a leaked signing key once, and it's exactly as bad as it sounds: you can't easily tell what was signed maliciously, and rotating trust downstream is a slog. Keyless signing makes that class of incident structurally impossible. Here's the machinery, the cosign workflow, and where the model's trust actually rests.

The three moving parts

Keyless signing coordinates three Sigstore services, and understanding them demystifies the whole thing:

The flow: you authenticate via OIDC, Fulcio issues a short-lived cert for your identity, you sign the artifact with the ephemeral key, the signature and certificate go into Rekor, and the private key is discarded. Verification later checks the signature, confirms the certificate chains to Fulcio, and asserts the recorded identity matches your policy.

Signing an image with cosign

In CI, keyless signing is close to a one-liner. The COSIGN_EXPERIMENTAL flag is no longer needed in current cosign; keyless is the default when you don't pass a key.

# In a CI job with OIDC configured, sign an image by digest
cosign sign \
  --yes \
  registry.example.com/payments-api@sha256:abc123...

There's no --key flag. Cosign detects the ambient OIDC token, requests a certificate from Fulcio, signs, and uploads to Rekor. Always sign by digest, not tag — tags are mutable, so signing :latest signs whatever latest happens to point at right now, which is a signature that means nothing tomorrow.

Verifying with an identity policy

Verification is where the security payoff lands, and it's stricter than people expect. You don't just check "is this signed?" — you assert who signed it and from where:

cosign verify \
  --certificate-identity="https://github.com/myorg/payments-api/.github/workflows/release.yml@refs/heads/main" \
  --certificate-oidc-issuer="https://token.actions.githubusercontent.com" \
  registry.example.com/payments-api@sha256:abc123...

Read that carefully: you're asserting the image was signed by a specific GitHub Actions workflow, on a specific branch, authenticated by GitHub's OIDC issuer. An attacker who compromises your registry can't forge that — they'd need to sign from that exact identity, which means compromising the CI identity itself. This identity-pinned verification is the whole game. A signature you don't verify against an expected identity is theater.

Why a transparency log instead of a key

The conceptual leap that trips people up: if there's no persistent key, what stops someone from signing malware as you? The answer is Rekor plus the ephemeral certificate's short lifetime. Every signature is a public, timestamped, immutable record tied to an OIDC identity. If a signature exists for your identity that you didn't make, that's detectable — it's in a log you can audit. The accountability moves from "trust that a secret was never misused" to "everything is publicly recorded and verifiable."

Traditional key signing Sigstore keyless
Long-lived private key to protect Ephemeral cert, ~10 min lifetime
Key leak = silent forgery risk No key to leak; signings are logged
Rotation is painful Nothing to rotate
Trust = "key wasn't stolen" Trust = OIDC identity + public log

This slots directly into a broader provenance strategy. Signing is one control among several in supply chain security with SLSA and SBOMs — SLSA describes the build provenance, and Sigstore is how you attach a verifiable, identity-bound signature to that provenance and to the artifact itself.

Signing attestations, not just images

Cosign can attach and sign attestations — structured claims about an artifact — using the in-toto format. The most useful pairing is signing your SBOM as an attestation, so consumers get a cryptographically verifiable bill of materials rather than a loose file that could've been swapped:

cosign attest \
  --yes \
  --predicate sbom.spdx.json \
  --type spdxjson \
  registry.example.com/payments-api@sha256:abc123...

Now the SBOM is bound to the image and signed by your CI identity. This is where keyless signing stops being "sign the binary" and becomes the trust backbone for your whole artifact story — the SBOM you generate as part of container image security becomes tamper-evident and attributable, not just present.

The caveats worth stating plainly

Keyless is excellent, but be honest about the dependencies. You're trusting the public Sigstore infrastructure (Fulcio, Rekor) unless you self-host — and self-hosting the whole stack is real operational work. Your security now hinges on the integrity of your OIDC identity: if an attacker can make CI sign on their behalf, keyless signing faithfully signs their malware with your identity. Protect the CI identity and the workflows that can trigger signing as carefully as you'd have protected the old private key.

There's also an availability consideration — signing and verification depend on those services being reachable, so bake in retries and think about your verification path in air-gapped environments (cosign supports offline verification with bundled Rekor proofs for exactly this).

My take after adopting it across pipelines: keyless signing is one of the rare security improvements that also reduces operational burden. No key vault, no rotation runbook, no "who has access to the signing key" audit. You trade a secret you have to guard for an identity you already manage and a public log anyone can audit — and that trade is almost always the right one.

Resources

Frequently asked questions

What is keyless signing with Sigstore?

Keyless signing lets you sign software artifacts using a short-lived certificate tied to an OIDC identity instead of a long-lived private key you have to store and protect. Sigstore issues an ephemeral certificate that binds a signature to an identity (a CI workflow, a person, a service account) for a few minutes, records it in a public transparency log, and then the key material is discarded. There's no signing key to leak because none persists.

What does cosign do?

Cosign is the Sigstore CLI for signing and verifying artifacts, most commonly container images and their attestations. In keyless mode it drives the OIDC flow, obtains an ephemeral certificate from Fulcio, signs the artifact, and uploads the signature and certificate to the Rekor transparency log. On the verify side, it checks the signature and asserts the signer's identity matches a policy you specify.

What is the Rekor transparency log?

Rekor is Sigstore's public, append-only, tamper-evident transparency log of signing events. Every keyless signature is recorded there with its certificate and metadata, so anyone can later verify that a given artifact was signed by a given identity at a given time. Because the log is immutable and publicly auditable, it provides the accountability that replaces a private key you'd otherwise have to trust was never misused.

Hiring a senior Android / Flutter engineer?

I architect and ship production mobile software — Kotlin, Jetpack Compose, Flutter — for robotics, EV infrastructure, fintech, and real-time systems. Open to remote roles in Europe and the US.

Get in touch →