You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[REQUEST] Consider provenance-backed patch releases for legacy v5/v6 lines #886
Hi, would the maintainers be open to publishing no-code-change patch releases for the legacy v5 and v6 lines, for example semver@5.7.3 and semver@6.3.2, using npm provenance?
Context:
semver@7.5.1 through 7.5.4 were published with provenance.
semver@5.7.2 and semver@6.3.1 were published afterward without provenance.
pnpm's trustPolicy: no-downgrade checks publish chronology, not semver major lines, so semver@6.3.1 is reported as a trust downgrade.
A provenance-backed patch release on the legacy lines would let consumers resolve within the declared dependency ranges without using package-manager-specific exceptions such as trustPolicyExclude.
Provenance is a useless signal, so doing a release solely to add it would be sending the wrong message.
It is 100% legitimate for a maintainer to start, and then stop, using provenance; it's also perfectly possible for an attacker to publish malware with provenance; as such, provenance disappearing is simply not an indicator of anything whatsoever.
Reacted by Ranieri Althoff, Lucas Santos, Roz, ふぁ, moons14, Marcelo Pecin, Anguel, Artem Tamoian, Simon Winter and ina-lieder
It is 100% legitimate for a maintainer to start, and then stop, using provenance; it's also perfectly possible for an attacker to publish malware with provenance; as such, provenance disappearing is simply not an indicator of anything whatsoever.
You seem to grossly misunderstand provenance. It has nothing to do with security (judging by mentioning an attacker as the threat factor), but reproducibility and traceability of the code. Provenance doesn't attest "this code is safe", it attests "this is the code and how it was built".
While a maintainer can, there's little reason to stop using it once set up. Fine if you don't like it, just don't use it in your packages, but this is causing issues for everyone.
Reacted by ふぁ, Lucas Santos, Roz, moons14 and ina-lieder
All it attests is that a given GHA workflow published the package. It gives you no guarantees about the contents, or the reliability of the artifact, and after 3 months it's gone forever.
It adds no value, and relying on it as a supply chain indicator is a category error.
it attests that the artifact came directly from the repository code with a specific commit SHA, thus allowing users to inspect exactly what code generated the artifact.
giving you guarantees about the artifact contents is precisely what it does...
and after 3 months it's gone forever
it's really not. the GHA logs are gone, but you can still open the repo and inspect the commit a version was published from. the code is still there
It only allows that for 3 months because that's when GHA logs expire; the packument already contains a git sha and that's been possible for 16 years; and that information simply isn't useful and wouldn't have stopped any incidents that have ever actually happened.
You can open the repo only if the sha still exists - which was also true long before provenance existed. It adds nothing, it serves no purpose, it has no value, and most importantly, it is not a trust signal and should never be treated as one..
It only allows that for 3 months because that's when GHA logs expire;
You don't need GHA logs to verify provenance at all. The proof is the signed attestation stored in the registry plus its entry in Sigstore's public transparency log (Rekor), which are both permanent. npm audit signatures verifies it years after the Actions run logs are gone; what expires at 90 days is the run log, which is a convenience, not the attestation. The source commit and workflow definition also stay in the repo regardless. Provenance isn't meant to prove trust, it proves origin: this exact binary was built from this source at this commit.
the packument already contains a git sha
Which is not signed nor tracked. It is entirely self reported and anyone that can publish a package can forge it. What's stopping an attacker that already has your token from cloning your repository, adding malware, then running npm publish? That would set the packument to the latest (genuine) commit SHA, but the published code would be malicious. The same thing is true for an ill-intentioned maintainer who could embed code in the package without ever making that code publicly available on the repo.
and that information simply isn't useful and wouldn't have stopped any incidents that have ever actually happened
That is simply not true.
Let's see an example:
Package foo normally publishes from GitHub Actions with provenance.
An attacker phishes or steals the maintainer's npm automation token (which is what happened with ua-parser-js, coa, rc in 2021 and Shai-Hulud / the qix phishing).
Attacker runs npm publish from their own laptop with a tarball whose postinstall contains a payload that was never in the repo.
Since the attacker's payload was not published from GH Actions, it does not have provenance (the cryptographic signature proving it was built from that code specifically). Anyone who uses that package and has provenance policies set up will skip that update, and might be alerted by scanners.
Now, if your package never had provenance to begin with, the attacker's tarball will just be a regular, valid version which, if published as a patch, is likely to be blindly updated anyway. The malware code never reaches the repo, it's way harder to audit because you don't have the source code and is way more likely to go unnoticed because inspecting tarballs is not as common as inspecting source code.
So, addressing your original points again:
It is 100% legitimate for a maintainer to start, and then stop, using provenance
It can be done legitimately, but it's meant to be taken as a red flag for a new release, prompting users to at least check with the maintainer if that is the intended outcome
it's also perfectly possible for an attacker to publish malware with provenance
It is, but not without going through the public repository, leaving a trail, and making the attack way louder.
provenance disappearing is simply not an indicator of anything whatsoever
This is also wrong. It is an indicator that there is no longer cryptographic proof that that specific tarball was generated by that specific code.
And you're right: it is not a trust signal when it exists, and it's not meant to attest to how safe the code is, or how genuine the maintainers intentions are or any of those things; it's simply meant to prove that a given binary was generated from a given source code, in a way that's public, traceable and auditable by the public and, thus, it's an important distrust signal when it goes missing.
Lastly, if you don't want to add it, it's your call. But saying it "proves nothing" is flat out wrong, and adding it only costs a one-time setup.
It's true empirically - your example is contrived. Provenance absolutely could theoretically stop an attack, but there hasn't been any attacks of note that it would have stopped.
that principle doesn't apply here, because an attack that's stopped is something we still hear about :-) if provenance had never existed, precisely nothing would be different with the state of security incidents in npm.
Adding a current reproduction in support of this request. With Node 24 and pnpm 10.33.2, an isolated project depending on exactly semver@6.3.1 fails resolution with:
trustPolicy: no-downgrademinimumReleaseAge: 10080
pnpm install --lockfile-only --ignore-scripts
The error is ERR_PNPM_TRUST_DOWNGRADE. Adding only semver@6.3.1 to trustPolicyExclude makes the same reproduction pass. We also encountered this transitively through @babel/core in a dependency-install CI job.
The npm registry metadata we checked shows 6.3.1 published on 2023-07-10 without an attestation, after attested 7.5.1–7.5.4 releases. Its registry integrity matches our existing lockfile; we are not reporting evidence of a compromised package.
Would an attested patch release within the 6.x range be feasible, or is there a recommended migration path for consumers still constrained to that major? We are keeping an exact-version exception in the meantime, rather than disabling the policy globally. Thanks for considering the compatibility impact.
Thanks @ljharb — I hear you that provenance is not a sufficiency proof of package safety, and that an attacker with the right identity/CI control can still ship attested malware. We agree that identity controls (mandatory 2FA / locked-down trusted publishing) are a necessary prong; we don’t treat provenance as a substitute for that.
We enabled trustPolicy: no-downgrade because our AppSec scanner (Semgrep rule package_managers.pnpm.pnpm-trust-policy, finding against our pnpm-workspace.yaml) and pnpm’s own supply-chain guidance both recommend it as a consumer control that refuses trust-evidence downgrades across publish chronology — not as a claim that “attested == safe.” In our model it’s one distrust signal among several (release age, advisories, lockfile integrity, maintainer/2FA expectations). When it fires, we verify and carve out known false positives rather than turning the policy off globally. That’s what we did for semver@6.3.1: registry integrity matches; we are not alleging compromise.
So the narrow ask isn’t “please endorse the gate.” It’s whether this project will ship an attested no-code-change patch on the still-widely-resolved 6.x (and/or 5.x) lines so consumers who follow that Semgrep/pnpm guidance don’t need a permanent exclude for a chronological cross-major artifact. If the answer is no, we’ll document semver as a standing exclude and leave the tooling gap to pnpm (#10202).
If you have a preferred consumer path for orgs that are going to keep the gate anyway, we’re happy to follow that instead.
Adding measurements in support of this request, as an FYI. This is not a bug in semver.
semver@6.3.1 and semver@5.7.2 (2023-07-10) are the CVE-2022-25883 fixes for the 6.x and 5.x lines. They were published without provenance, after 7.5.1–7.5.4 had it.
pnpm's trustPolicy: no-downgrade orders history by publish date, not by line, so it rejects both with ERR_PNPM_TRUST_DOWNGRADE, and everything that depends on them fails with them. For example @babel/core@7.29.7 (^6.3.1), eslint-plugin-react, eslint-plugin-import.
In a random sample of 200 stable npm releases we replayed with pnpm 10.29.3, 3 of the 18 that could not be installed were blocked by semver@6.3.1.
Reproduce (lockfile-only, read-only):
mkdir t &&cd t
echo'{"name":"t","version":"0.0.0","private":true,"dependencies":{"semver":"6.3.1"}}'> package.json
printf'trustPolicy: no-downgrade\n'> pnpm-workspace.yaml
npx pnpm@10.29.3 install --lockfile-only --ignore-scripts
We agree the root cause lies in the policy's design, and we have raised it with pnpm. That said, a no-code-change 6.3.2 / 5.7.3 published through the same trusted-publisher workflow as 7.x would unblock these lines for pnpm users now, without any package-manager-specific exclusions. Thanks for considering it.
The root cause is using provenance as any kind of gate whatsoever. It should never be used this way - it's a post-incident forensics tool only and anyone claiming otherwise is ill-informed.
Activity
ljharb commentedon Jul 6, 2026
Provenance is a useless signal, so doing a release solely to add it would be sending the wrong message.
It is 100% legitimate for a maintainer to start, and then stop, using provenance; it's also perfectly possible for an attacker to publish malware with provenance; as such, provenance disappearing is simply not an indicator of anything whatsoever.
ranisalt commentedon Jul 7, 2026
You seem to grossly misunderstand provenance. It has nothing to do with security (judging by mentioning an attacker as the threat factor), but reproducibility and traceability of the code. Provenance doesn't attest "this code is safe", it attests "this is the code and how it was built".
While a maintainer can, there's little reason to stop using it once set up. Fine if you don't like it, just don't use it in your packages, but this is causing issues for everyone.
ljharb commentedon Jul 7, 2026
All it attests is that a given GHA workflow published the package. It gives you no guarantees about the contents, or the reliability of the artifact, and after 3 months it's gone forever.
It adds no value, and relying on it as a supply chain indicator is a category error.
roziscoding commentedon Jul 7, 2026
it attests that the artifact came directly from the repository code with a specific commit SHA, thus allowing users to inspect exactly what code generated the artifact.
giving you guarantees about the artifact contents is precisely what it does...
it's really not. the GHA logs are gone, but you can still open the repo and inspect the commit a version was published from. the code is still there
ljharb commentedon Jul 8, 2026
It only allows that for 3 months because that's when GHA logs expire; the packument already contains a git sha and that's been possible for 16 years; and that information simply isn't useful and wouldn't have stopped any incidents that have ever actually happened.
You can open the repo only if the sha still exists - which was also true long before provenance existed. It adds nothing, it serves no purpose, it has no value, and most importantly, it is not a trust signal and should never be treated as one..
roziscoding commentedon Jul 17, 2026
You don't need GHA logs to verify provenance at all. The proof is the signed attestation stored in the registry plus its entry in Sigstore's public transparency log (Rekor), which are both permanent.
npm audit signaturesverifies it years after the Actions run logs are gone; what expires at 90 days is the run log, which is a convenience, not the attestation. The source commit and workflow definition also stay in the repo regardless. Provenance isn't meant to prove trust, it proves origin: this exact binary was built from this source at this commit.Which is not signed nor tracked. It is entirely self reported and anyone that can publish a package can forge it. What's stopping an attacker that already has your token from cloning your repository, adding malware, then running
npm publish? That would set the packument to the latest (genuine) commit SHA, but the published code would be malicious. The same thing is true for an ill-intentioned maintainer who could embed code in the package without ever making that code publicly available on the repo.That is simply not true.
Let's see an example:
npm publishfrom their own laptop with a tarball whosepostinstallcontains a payload that was never in the repo.Since the attacker's payload was not published from GH Actions, it does not have provenance (the cryptographic signature proving it was built from that code specifically). Anyone who uses that package and has provenance policies set up will skip that update, and might be alerted by scanners.
Now, if your package never had provenance to begin with, the attacker's tarball will just be a regular, valid version which, if published as a patch, is likely to be blindly updated anyway. The malware code never reaches the repo, it's way harder to audit because you don't have the source code and is way more likely to go unnoticed because inspecting tarballs is not as common as inspecting source code.
So, addressing your original points again:
It can be done legitimately, but it's meant to be taken as a red flag for a new release, prompting users to at least check with the maintainer if that is the intended outcome
It is, but not without going through the public repository, leaving a trail, and making the attack way louder.
This is also wrong. It is an indicator that there is no longer cryptographic proof that that specific tarball was generated by that specific code.
And you're right: it is not a trust signal when it exists, and it's not meant to attest to how safe the code is, or how genuine the maintainers intentions are or any of those things; it's simply meant to prove that a given binary was generated from a given source code, in a way that's public, traceable and auditable by the public and, thus, it's an important distrust signal when it goes missing.
Lastly, if you don't want to add it, it's your call. But saying it "proves nothing" is flat out wrong, and adding it only costs a one-time setup.
ljharb commentedon Jul 17, 2026
It's true empirically - your example is contrived. Provenance absolutely could theoretically stop an attack, but there hasn't been any attacks of note that it would have stopped.
ranisalt commentedon Jul 17, 2026
ljharb commentedon Jul 18, 2026
that principle doesn't apply here, because an attack that's stopped is something we still hear about :-) if provenance had never existed, precisely nothing would be different with the state of security incidents in npm.
ianrothfuss commentedon Sep 15, 2026
Adding a current reproduction in support of this request. With Node 24 and pnpm 10.33.2, an isolated project depending on exactly
semver@6.3.1fails resolution with:The error is
ERR_PNPM_TRUST_DOWNGRADE. Adding onlysemver@6.3.1totrustPolicyExcludemakes the same reproduction pass. We also encountered this transitively through@babel/corein a dependency-install CI job.The npm registry metadata we checked shows 6.3.1 published on 2023-07-10 without an attestation, after attested 7.5.1–7.5.4 releases. Its registry integrity matches our existing lockfile; we are not reporting evidence of a compromised package.
Would an attested patch release within the 6.x range be feasible, or is there a recommended migration path for consumers still constrained to that major? We are keeping an exact-version exception in the meantime, rather than disabling the policy globally. Thanks for considering the compatibility impact.
ljharb commentedon Sep 15, 2026
@ianrothfuss that setting should simply not be used, ever, since provenance is not a security indicator, merely a post-incident forensics tool.
fa0311 commentedon Sep 15, 2026
@ljharb
Is your position that provenance should never be used as an install-time gate the official position of the npm project, or your own view?
ref: npm/cli#9242
ljharb commentedon Sep 15, 2026
@fa0311 it's my own view, based on the facts of what it secures and what it does not, and it's shared by most security experts i've discussed it with.
ianrothfuss commentedon Sep 16, 2026
Thanks @ljharb — I hear you that provenance is not a sufficiency proof of package safety, and that an attacker with the right identity/CI control can still ship attested malware. We agree that identity controls (mandatory 2FA / locked-down trusted publishing) are a necessary prong; we don’t treat provenance as a substitute for that.
We enabled
trustPolicy: no-downgradebecause our AppSec scanner (Semgrep rulepackage_managers.pnpm.pnpm-trust-policy, finding against ourpnpm-workspace.yaml) and pnpm’s own supply-chain guidance both recommend it as a consumer control that refuses trust-evidence downgrades across publish chronology — not as a claim that “attested == safe.” In our model it’s one distrust signal among several (release age, advisories, lockfile integrity, maintainer/2FA expectations). When it fires, we verify and carve out known false positives rather than turning the policy off globally. That’s what we did forsemver@6.3.1: registry integrity matches; we are not alleging compromise.So the narrow ask isn’t “please endorse the gate.” It’s whether this project will ship an attested no-code-change patch on the still-widely-resolved 6.x (and/or 5.x) lines so consumers who follow that Semgrep/pnpm guidance don’t need a permanent exclude for a chronological cross-major artifact. If the answer is no, we’ll document
semveras a standing exclude and leave the tooling gap to pnpm (#10202).If you have a preferred consumer path for orgs that are going to keep the gate anyway, we’re happy to follow that instead.
igorsantosgrueiro commentedon Sep 27, 2026
Adding measurements in support of this request, as an FYI. This is not a bug in semver.
semver@6.3.1andsemver@5.7.2(2023-07-10) are the CVE-2022-25883 fixes for the 6.x and 5.x lines. They were published without provenance, after 7.5.1–7.5.4 had it.pnpm's
trustPolicy: no-downgradeorders history by publish date, not by line, so it rejects both withERR_PNPM_TRUST_DOWNGRADE, and everything that depends on them fails with them. For example@babel/core@7.29.7(^6.3.1),eslint-plugin-react,eslint-plugin-import.In a random sample of 200 stable npm releases we replayed with pnpm 10.29.3, 3 of the 18 that could not be installed were blocked by
semver@6.3.1.Reproduce (lockfile-only, read-only):
We agree the root cause lies in the policy's design, and we have raised it with pnpm. That said, a no-code-change
6.3.2/5.7.3published through the same trusted-publisher workflow as 7.x would unblock these lines for pnpm users now, without any package-manager-specific exclusions. Thanks for considering it.ljharb commentedon Oct 1, 2026
The root cause is using provenance as any kind of gate whatsoever. It should never be used this way - it's a post-incident forensics tool only and anyone claiming otherwise is ill-informed.