What does an npm provenance attestation assert about a package, and what does it not?
answer
- answers how, not whether
- subject digest, plus source and builder
- signed by the CI identity, keyless
- a backdoored repo attests cleanly
basics
~20 sIt binds a published tarball's digest to the source repository, commit and CI workflow that built it, signed by that build's identity. It says nothing about whether the code is reviewed, safe, or free of vulnerabilities.
solid answer
~50 snpm provenance is a SLSA provenance statement produced when you publish with the npm CLI's `--provenance` flag from a supported CI provider. Its `subject` is the published tarball's digest; its predicate names the source repository, the commit, the workflow that ran, and the builder identity. Signing is keyless through Sigstore: the CI job's OIDC identity gets a short-lived certificate, and the signed bundle is recorded in a public transparency log. So the attestation answers *how this artifact came to be*, and lets a consumer confirm that version 1.4.2 really was built by that workflow from that commit. It is not a code review, not an SBOM, and not a vulnerability verdict. A repository containing a deliberate backdoor produces a perfectly valid provenance attestation. Reading a provenance badge as "this release is safe" is the single most common mistake here.
code
json · 18 lines{
"_type": "https://in-toto.io/Statement/v1",
"subject": [
{ "name": "pkg:npm/[email protected]",
"digest": { "sha512": "9f2c..." } }
],
"predicateType": "https://slsa.dev/provenance/v1",
"predicate": {
"buildDefinition": {
"externalParameters": {
"workflow": { "repository": "https://example.com/acme/example",
"ref": "refs/heads/main",
"path": ".ci/release.yml" }
}
},
"runDetails": { "builder": { "id": "https://example.com/hosted-runner" } }
}
}go deeper
Be ready to state the three facts a provenance attestation binds together: this exact tarball, that builder, that source commit. Then say plainly what it does not cover — code quality, review, vulnerabilities.
You are expected to describe the document itself: an in-toto statement whose subject is a digest and whose predicate is the build, signed in a separate envelope. Explain why the digest is what makes the claim non-transferable.
Show that verification is meaningless without an expected identity. Talk about asserting the source repository and workflow you require, and about the attacks provenance closes versus the ones scanners close.
Own the framing: provenance is an origin control, not a quality control, and an organisation that markets it internally as "safe" has bought a false assurance. Be able to say what you would pair it with.
## The shape of the document An npm provenance attestation is an **in-toto statement** — a small JSON payload with four parts: - `_type` — a URI saying "this is an in-toto statement". - `subject` — *the thing being described*. Here it is the published package tarball, named and identified by a cryptographic **digest** (a hash of the exact bytes). The digest is what welds the claim to one specific artifact: change a byte of the tarball and the statement no longer describes it. - `predicateType` — a URI naming the vocabulary of the claim. For npm provenance that is SLSA provenance. - `predicate` — the claim itself: which source repository and commit the build started from, which workflow file and ref defined it, and which builder ran it. The statement is only a payload. It is signed **separately**, wrapped in an envelope, and the signature is what makes it worth anything — an unsigned statement is a JSON file that anybody could have written by hand. ## How it comes into existence You publish from a supported CI provider (GitHub Actions and GitLab CI are the supported ones) with the npm CLI's `--provenance` flag. The CLI reads the CI environment to fill in the repository, commit and workflow, requests an OIDC identity token for that job, and uses Sigstore's keyless flow to sign: a short-lived certificate is issued that binds an ephemeral key to that workload identity, the statement is signed, and the bundle is submitted to the Rekor transparency log. The registry stores the attestation next to the package and shows a provenance badge linking to the commit and the build run. The crucial consequence: **you cannot mint one of these from a laptop.** The identity in the certificate is the CI workload's, not a human's. That is the whole point. ## What it therefore asserts — three linked facts 1. *This exact tarball* (by digest), 2. was produced by *that builder*, 3. from *that source repository at that commit*. Together they give you a chain of custody from source to registry. If someone steals a maintainer's publish token and pushes a tarball from their own machine, that publish cannot produce a valid statement naming your CI identity, and a consumer who requires provenance from an expected repository and workflow rejects it. ## What it does not assert - **Not that the code is good.** Provenance is indifferent to what the source contains. A backdoor committed to `main` and built by the real workflow attests cleanly. - **Not that the code was reviewed.** SLSA v1.0 split its requirements into tracks and left source review outside the build track; provenance is build-track material. - **Not that the package is free of known vulnerabilities.** That is a scanner's answer against an advisory database, a completely separate question. - **Not what is inside the package.** That is an SBOM's job — an SBOM enumerates components, provenance describes production. Neither substitutes for the other. - **Not that the named repository is the one you meant.** Verification checks that the signature is valid and the subject digest matches. Matching the source repository and workflow against what you *expect* is a policy decision the consumer has to make and state. Tooling that reports "provenance verified" without you asserting an expected identity has told you almost nothing — some builder somewhere signed something. - **Not that anyone checked it.** Publishing trust material and acting on it are separate projects, and most consumers do neither. ## Getting the direction of the claim right Three artifacts are constantly confused, and interviewers probe the confusion directly: | Artifact | Question it answers | | --- | --- | | SBOM | What is inside this artifact? | | Provenance | How did this artifact come to be? | | Signature | Who vouches for this artifact? | Provenance is the middle row. It is also *signed*, which is why people collapse it into the third row, but the signature is the delivery mechanism and the build description is the content. ## Why it is still worth having The attacks it closes are the ones where the artifact on the registry did not come from the stated source at all: a stolen publish token, a hijacked maintainer account, a tampered tarball substituted between build and upload, or a release built from an unpublished branch. Those are real and they are common, and no scanner catches them, because the malicious tarball may be perfectly "clean" against every advisory database. Provenance is the control that makes the *origin* checkable — and only that.
- If provenance passes no judgement on the code, which attacks does it actually stop?The ones where the published artifact never came from the stated source: a stolen publish token, a hijacked maintainer account, a tarball substituted after the build, or a release cut from an unpublished branch. A consumer who requires provenance naming a known repository and workflow rejects those, because a publish from someone's laptop cannot mint a statement carrying your CI identity.
- A package has provenance, but the repository it names is not the one you assumed. How would you notice?Only by reading the statement, or by telling your verification step which repository and workflow you expect. Verification on its own checks that the signature is valid and that the subject digest matches the tarball — both would pass. Asserting the expected identity is a consumer-side policy decision, and skipping it turns "provenance verified" into a badge with almost no content.
- Does provenance tell you what is inside the package?No — that is an SBOM. Provenance describes how the artifact was produced: source, builder, build parameters. An SBOM enumerates the components the artifact contains, which is what you match against vulnerability advisories. They answer different questions and neither one is a substitute for the other.
It is the shipping label on a crate saying which plant and which production run made this exact crate. That is genuinely useful when you suspect the crate was swapped in transit, and it tells you nothing whatsoever about whether the contents are any good.
saying these in an interview costs you the question
- Says provenance means the release was reviewed
- Claims provenance proves the package has no vulnerabilities
- Confuses provenance with an SBOM's component list
- Thinks a valid signature implies a trustworthy source repository
- Assumes npm install checks provenance automatically