Provenance Attestation, Sigstore, and SLSA Level 3: What They Mean for Indie Package Authors
What provenance attestation, Sigstore, and SLSA Level 3 actually buy you as a solo or small-team npm package author. Plain-language definitions, the verification chain, and what is still your responsibility.
Sources: S-001 S-003 S-004
You enabled npm publish --provenance. Your package page now shows a green provenance badge. What did you actually buy, and what is still your responsibility?
This post is the plain-language version of the Sigstore docs (S-004), the npm trusted-publisher docs (S-001), and the npm CLI release notes for --provenance (S-003). Sources are primary; independent third-party analyses of the same chain are limited, so wording is cautious where third-party validation is thin.
TLDR
- Provenance attestation is a signed statement that a specific tarball was built by a specific workflow run on a specific commit.
- Sigstore is the underlying signing system: Fulcio (issues short-lived certs to OIDC identities), Rekor (the public append-only log), Cosign/cosign-like tooling (the signing CLI).
- SLSA Level 3 is a supply-chain framework rating; “L3 build” roughly means “the build provenance is signed by a hardened build platform that the author does not control.”
- For an indie maintainer, the provenance badge on npm proves the published tarball came from the workflow you registered. It does not prove the workflow itself is benign.
Plain-language definitions
Provenance attestation
A signed JSON statement, in the in-toto attestation format, that says:
“I, the npm publish flow, observed that this tarball SHA was produced by this GitHub Actions run, for this commit, on this repo.”
That statement is signed using a short-lived cert from Sigstore’s Fulcio CA. The signing identity is the OIDC token of the workflow run.
Sigstore
Three pieces:
- Fulcio — a certificate authority that issues short-lived (~10 minute) X.509 certs bound to an OIDC identity. The OIDC identity is the GitHub Actions run.
- Rekor — an append-only transparency log. Every Fulcio-issued signature gets logged in Rekor. Anyone can audit the log and prove “this signature existed by this time.”
- Cosign (and the npm CLI’s internal equivalent) — the tooling that requests the cert, signs the statement, and submits it to Rekor.
SLSA Level 3
A level in the SLSA framework for build-supply-chain integrity. Roughly:
- L1: provenance exists.
- L2: provenance is authenticated and signed by the build platform.
- L3: the build platform is hardened — isolated, no persistent build state, parameterized only by the source.
GitHub Actions hosted runners + npm trusted publishing claims to meet L3 for the build provenance. Whether your overall release process meets L3 depends on what you do in the workflow.
What the provenance badge actually proves
On a npm package version with a provenance badge, a downstream user can verify:
- The tarball SHA matches what is recorded in the attestation.
- The attestation is signed by a Sigstore Fulcio cert.
- The Fulcio cert’s OIDC identity is
repo: <your-owner>/<your-repo>,workflow: .github/workflows/publish.yml,ref: refs/tags/v1.2.3. - The attestation was logged in Rekor.
So the verifier knows: “this tarball came out of run #12345 of that workflow on that commit.”
What it does NOT prove
- That your workflow itself is benign. A malicious
npm run prepublishstep earlier in the workflow can build a poisoned tarball that is then faithfully attested. - That your dependencies are clean. Provenance covers your build, not the upstream packages you pulled in.
- That your release tag was created by a human you trust. If someone pushed a tag with stolen GitHub credentials, the workflow runs and the provenance is genuine.
- That the registry will keep serving this exact tarball. npm could rewrite metadata; provenance attests to the tarball SHA at publish time.
This is the “necessary, not sufficient” framing. Provenance closes the “is this tarball really from that build?” question. It opens the “is that build trustworthy?” question.
What is still your responsibility
- Workflow review. Treat your
.github/workflows/publish.ymllike prod code. Every action you call (actions/checkout, third-party actions) becomes part of your supply chain. - Pinning third-party actions by SHA.
actions/checkout@v4floats;actions/checkout@<sha>does not. If you pin by tag, you trust the action author to never rotate the tag. - Dependency hygiene.
npm audit,socket.dev, or similar. Provenance on your tarball does not vouch forlodash@4.xinside it. - Tag protection. A signed git tag, branch protection, and a required reviewer on the release workflow keep stolen-credential publishes from being trivial.
- Account 2FA. Trusted publishing reduces the value of stealing an
NPM_TOKEN. It does not reduce the value of stealing your npm account session for manual web actions like adding a malicious co-maintainer.
Verification example
To verify a npm package’s provenance from the command line:
npm audit signatures <package-name>
The CLI walks the registry-reported attestation, verifies the Fulcio chain, looks up the Rekor entry, and confirms the OIDC identity. Run it on your own package after the first trusted publish to confirm the provenance is wired right.
For indie maintainers: the practical floor
You do not have to chase every SLSA level to gain most of the value:
| Step | Effort | Value |
|---|---|---|
| Switch from NPM_TOKEN to trusted publishing | Low (one workflow PR) | High (blast radius collapses) |
Add --provenance | Trivial | Medium (transparency, not security) |
| Pin third-party actions by SHA | Medium | High (closes the supply-chain side door) |
| Protect the publish branch / require signed tags | Medium | Medium |
| Move to a private build with reproducible-build verification | High | Marginal for most indie use cases |
The first two are what the preflight checklist verifies.
Common mistakes
- Treating the provenance badge as a stamp of approval. It is a stamp of origin.
- Believing “we have SLSA L3” because GitHub Actions hosted is L3-capable, while running
curl | bashinside the workflow. - Reusing the same
NPM_TOKENacross packages “until OIDC is wired” — the token is the blast radius until you actually delete it.
FAQ
Can I verify provenance offline?
Sigstore’s verification flow can be run against a downloaded Rekor entry, but the canonical chain requires reaching Rekor. Air-gapped verification is possible but non-trivial.
Does Sigstore charge?
No. The public Sigstore instance (Fulcio + Rekor) is free and run by the Sigstore project. Some organizations run private instances.
Is provenance privacy-preserving?
Partially. The Rekor entry is public — it records the OIDC identity (repo + workflow + ref + commit). If your repo is public, that is fine. If your repo is private, the existence of a publish is visible in the public log; the source code is not.
Next step
Run the preflight on your own setup — it flags whether --provenance is present and whether your workflow is shaped for trusted publishing. For the OIDC migration mechanics, read npm publish OIDC vs NPM_TOKEN and provenance failure modes.