Block provenance downgrades (trust-policy)

trust-policy=no-downgrade is a pnpm setting that refuses to install a package version whose trust level is weaker than a version you have already had. Once a package has shipped with provenance, pnpm will not silently accept a newer release that arrives without it.

What is provenance?

Provenance is a cryptographic attestation, for example, npm/Sigstore build provenance, that proves where and how a specific package version was built: which source repository, which commit, and which CI workflow produced the published artifact. It links the tarball on the registry back to a verifiable build, so consumers can check that a version was not hand-assembled or tampered with after the fact.

The catch is that provenance is opt-in per release. A maintainer may publish several versions with provenance and then ship a later (or republished) version that drops it. To a normal install, that downgrade is invisible: the version still resolves and installs like any other.

What no-downgrade does

With trust-policy=no-downgrade, pnpm fails the install if a package's trust level has decreased compared to earlier releases. As the pnpm docs put it: if a package was previously published by a trusted publisher but a new version now only has provenance (or no trust evidence at all), installation will fail. The check is based on publication date, not semver: a version cannot be installed if any earlier-published version of the same package carried stronger trust evidence.

Conceptually, this raises the bar on provenance. An attacker who compromises a maintainer account and tries to slip in a tampered build typically cannot reproduce the original signed build pipeline, so the malicious version arrives with weaker (or absent) provenance. no-downgrade turns that gap into a blocked install rather than a quiet upgrade. It is one layer, not a complete defense: it only helps for packages that established a provenance baseline in the first place.

Turn it on

trust-policy is available in pnpm ≥ 10.21. Where the key lives depends on your pnpm version.

pnpm ≤ 10 (rc / .npmrc)

Add to your .npmrc:

trust-policy=no-downgrade

pnpm ≥ 11 (workspace / global config)

Use pnpm-workspace.yaml (per project) or the global config.yaml with the camelCase key:

trustPolicy: "no-downgrade"

Let DepsGuard set it up

DepsGuard checks whether your pnpm version supports trust-policy, sees whether it is already configured, and writes the right key in the right file (with a diff preview and a backup before any change) so you do not have to track which form your pnpm version expects.

Where it fits

Treat trust-policy as one layer among several. It only protects packages that already ship with provenance, and it says nothing about brand-new packages, typosquats, or compromises that keep provenance intact. Pair it with a dependency cooldown so freshly published versions are delayed until the community has time to react, and with install-script blocking so a malicious version cannot run code at install time even if it slips through. Together these settings narrow the windows an attacker has to work with.