skip to content

Six of your forty direct npm dependencies publish provenance. What policy do you set?

level: seniorimportance: nice to knowfreq 29%

answer

  1. all-or-nothing gates get switched off
  2. unverifiable and failed are different states
  3. enforce where it exists, pin elsewhere
  4. hashes give continuity, not origin
  5. coverage is a metric, not a gate

basics

~20 s

Enforce provenance where it exists, record its absence elsewhere. Gate the six against an expected source repository, fall back to lockfile integrity hashes for the other thirty-four, and never report a missing attestation as a failed one.

solid answer

~50 s

The trap is an all-or-nothing gate. Requiring provenance across the board fails thirty-four of forty builds and gets switched off within a week; requiring nothing means the six that publish it are never checked. So split the policy. For dependencies that do publish provenance, verify it *and* assert the source repository and workflow you expect, failing the build on a mismatch — that is a genuine gate and it costs nothing to keep green. For the rest, enforce what you can: lockfile integrity hashes so the bytes cannot change underneath you, a single controlled ingestion point, and a dated exception recorded per package. Then track coverage as a number that should rise over time. The discipline that matters most is keeping two states apart: **unverifiable** (no attestation published) and **failed** (an attestation that does not check out). Collapsing them is how a team ends up ignoring both.

go deeper

for a junior

Understand the basic shape of the problem: most packages publish no provenance yet, so a rule requiring it everywhere would break almost every build.

for a middle

Explain what you can still enforce without provenance — lockfile integrity hashes for byte continuity, a single ingestion point — and why those are weaker but real.

for a senior

Design the split policy and defend it: hard gate with an expected source identity where provenance exists, recorded exceptions elsewhere, and unverifiable kept distinct from failed.

for a principal

Be ready to state the organisation's honest coverage position to an auditor or a customer, and to say which upstreams you would invest engineering time in to move the number.

## Start with the arithmetic, honestly Six out of forty is roughly the shape of a real dependency set today, and it is worth saying out loud in an interview rather than pretending the estate is uniform. The forty direct dependencies also pull in a transitive graph that is an order of magnitude larger and where coverage is worse still. Any policy that assumes coverage will be complete is a policy about a different codebase. ## Why the obvious policies both fail **"Require provenance on everything."** Thirty-four builds break on the first run. The team's realistic options are to vendor thirty-four packages, drop them, or turn the gate off — and they will turn the gate off. A control that is switched off on day two is worse than no control, because the org now believes it has one. **"Report coverage, enforce nothing."** A dashboard showing 15% is produced monthly, read by nobody, and the six packages that actually publish verifiable origin material are installed with exactly as little checking as the thirty-four that do not. You have paid for the reporting and bought no security. ## The split policy ### For the six: a real gate Verify, and verify *against an expectation*. A bare "the signature is valid" result means somebody was authenticated and signed something. The gate must assert the source repository and the workflow you expect for each package, and fail the build when the attestation names something else. That is the difference between a check that catches a hijacked publish and a check that catches nothing. This gate is cheap to keep green, because those six already publish provenance on every release. The cost only shows up when something is genuinely wrong, which is the definition of a well-placed control. ### For the thirty-four: enforce what exists - **Lockfile integrity hashes.** These give *continuity*, not origin: the artifact you install today is byte-identical to the one you resolved originally. That is a real property and it is enforced by default. It is not provenance — if the first resolution was already malicious, the hash faithfully pins the malice — but it removes the "silently swapped later" class. - **One controlled ingestion point.** Everything enters through a single proxy or mirror, so there is exactly one place where a check *can* be made, and where trust material must be preserved rather than stripped. - **A recorded, dated exception per package.** Not a blanket waiver. The list is the artifact you re-read in six months, and each row is a candidate for removal as upstream coverage improves. ### Two states, never one The single most important design decision is reporting **unverifiable** and **failed** as distinct results. | Result | Meaning | Response | | --- | --- | --- | | Verified, identity matches | Origin confirmed | Proceed | | Verified, identity unexpected | Origin is not who you thought | Stop | | Failed to verify | Material present, does not check out | Stop, investigate | | No attestation | Nothing was published | Record, do not block | Collapsing rows three and four is how a team learns that this alert always means nothing. ## The intermittent-publisher problem A harder case than "never publishes": a maintainer who cuts normal releases from CI and hotfixes by hand from a laptop. Now provenance exists for some versions and not others, and a consumer genuinely cannot distinguish "built off-pipeline in a hurry" from "tampered with". A hard gate blocks precisely the hotfix release you most urgently want to ship, which is the worst possible moment for a control to fire. The pragmatic answer is to allow the gap but alert on it — a transition from *has provenance* to *no provenance* for a package you were already verifying is a meaningful signal even when the explanation is mundane. And if it is your own package, fix the publishing path so every release takes one route. Inconsistent publishing is the upstream's bug, and it destroys the value of the attestations they do publish. ## Raising coverage You cannot mandate anything to maintainers you do not employ. What actually works: - File the issue or send the PR upstream, especially where the project already builds in a supported CI provider — enabling provenance there is often a small change. - Prefer packages that publish it when you have a genuine choice between comparable options. - Make sure the packages *you* publish carry provenance, consistently, on every release. That is the only part of the graph you fully control, and it is what you owe the consumers downstream of you. ## What to say when asked "so are you covered?" The honest senior answer: six dependencies have verifiable origin and are gated on it; thirty-four have byte-continuity and a recorded exception; the number is tracked and is expected to rise. That is a defensible position. "We require SLSA provenance" said about an estate where it is enforced nowhere is not.

  • A maintainer publishes releases from CI but hotfixes by hand. What does that do to your gate?
    It turns provenance into an intermittent signal: some versions carry it, some do not, and you cannot tell "built off-pipeline" from "tampered with". Gating hard blocks the hotfix you most want to ship. Practically you allow the gap but alert on the transition, since a package that used to publish provenance and suddenly does not is worth a look even when the reason is mundane.
  • How would you actually raise coverage from six out of forty?
    Not by mandate — you do not employ those maintainers. Open issues or send PRs upstream where the project already builds in a supported CI provider, since enabling provenance is often small there. Prefer packages that publish it when you have a real choice. And make sure your own published packages carry it on every release, because that is the only part of the graph you control.
  • Does a lockfile integrity hash give you the same guarantee as provenance?
    No — it gives continuity, not origin. The hash proves the artifact you install today is byte-identical to the one you first resolved. If that first artifact was already malicious, the hash pins the malice perfectly. Provenance is the only one of the two that says anything about where the bytes came from.

saying these in an interview costs you the question

  • Mandates provenance on every dependency and blocks the build
  • Treats a missing attestation as a verification failure
  • Assumes lockfile hashes prove where an artifact came from
  • Reports coverage as a percentage with no enforcement anywhere
  • Verifies signatures without asserting an expected repository

context