Sigstore root of trust explained: how keyless signing works
Sigstore is the open-source signing infrastructure that powers npm provenance, PyPI Trusted Publishing, and a growing list of artifact-attestation systems. Its design choice is unusual: instead of long-lived signing keys held by package authors, Sigstore issues short-lived signing certificates from an OpenID Connect identity, signs the artifact, and publishes the signature to a public transparency log. This post explains how that root of trust works and why it matters.
The problem keyless signing solves
Traditional package signing is hard for one boring reason: developers lose keys, leak keys, or never set them up. PGP-signed releases were a 2000s ideal that never reached scale. Even where keys exist, most consumers don't verify them, and key revocation when a maintainer's machine is compromised is messy.
Sigstore inverts the model. Instead of "the maintainer holds a key forever and we trust the key," the model is "the maintainer authenticates with an identity provider at the moment of release, and we trust the identity provider to assert who they are."
The components
Sigstore has three pieces.
Fulcio is a certificate authority that issues short-lived (10-minute) X.509 signing certificates. To get one, you authenticate via OpenID Connect — typically GitHub Actions OIDC, Google, or another supported provider. Fulcio bakes your verified identity claim (e.g. repo:org/repo:ref:refs/heads/main for a GitHub Actions workflow, or your verified email) into the certificate's subject.
Cosign is the client tool. It calls Fulcio to get a certificate, signs the artifact with the private key it generated for the certificate, and publishes the certificate plus signature.
Rekor is a public, append-only transparency log. Every signature produced by Cosign is logged here. Anyone can later look up "what signatures were issued for this artifact, by what identity, at what time" by querying Rekor.
The transparency log is the key piece. Even though signing keys are short-lived and discarded, the log preserves a permanent record of every signing event.
How verification works
When you verify a Sigstore-signed artifact, the verifier checks:
- The signature on the artifact matches the public key in the signing certificate.
- The signing certificate was issued by Fulcio (verified against Fulcio's root certificate).
- The certificate's subject matches what you expect — for example, "this artifact was signed by a GitHub Actions workflow in
org/repoon branchmain." - The signing event is recorded in Rekor with a timestamp inside the certificate's brief validity window.
If all four pass, you have established that an authenticated identity (GitHub Actions workflow, in this example) signed this exact artifact at a specific time.
Why short-lived keys
Short-lived keys remove key custody as a maintainer responsibility. There is no key to leak, no key to rotate, no key to lose. Each signing event creates a fresh key, signs, and discards. The 10-minute validity window is shorter than any realistic theft-and-reuse pipeline.
The tradeoff is that you can no longer say "this artifact was signed by X's key." You can say "this artifact was signed by an authenticated session of X's identity at time T, and the transparency log proves it." For most use cases this is stronger, not weaker.
Why a transparency log
The transparency log addresses the "trust but verify" problem with the identity provider. Even if Fulcio or your identity provider misbehaved and issued a certificate to the wrong identity, the misbehavior is logged publicly. Defenders can audit Rekor for signatures that shouldn't exist (e.g. "my repo never released yesterday — why is there a signature claiming it did?").
Transparency logs are a known cryptographic primitive (Certificate Transparency for TLS uses the same idea). The Sigstore log uses Trillian under the hood and produces inclusion proofs that anyone can verify offline.
How npm and PyPI use Sigstore
npm provenance. When a package is published with npm publish --provenance from a CI workflow with OIDC enabled, the registry gets a Sigstore attestation linking the published artifact to the source repository, commit, and workflow that built it. Consumers can verify the attestation matches the upstream source they expect.
PyPI Trusted Publishing. Maintainers register a CI workflow as a trusted publisher; PyPI then accepts uploads from that workflow's OIDC identity without API tokens. Sigstore is the underlying mechanism.
Both systems shift "the maintainer has a token" to "the registry trusts that this build came from this source." Compromise of a build environment is still possible, but compromise of the maintainer's laptop no longer translates to "publish a malicious version."
Verification today
For most consumers, Sigstore verification is automatic when using the package manager's verification flag (npm install --provenance, similar work in progress for PyPI consumption tools). The work is in producing attestations on the publishing side; the verification work on the consuming side is shrinking as tooling matures.
What it does not do
Sigstore proves who signed what and when. It does not prove the signed artifact is benign. A compromised CI workflow can still produce a valid attestation for a malicious version. Provenance plus content review is stronger than either alone.
Takeaway
Sigstore replaces "trust the maintainer's key" with "trust the maintainer's authenticated identity at signing time, and the public log of every signing event." For npm and PyPI, it's the foundation under provenance and Trusted Publishing. The shift is a meaningful improvement; pair it with content review and cooling-period gates to cover the cases where signed artifacts can still be malicious.