Summary
Add a configuration option (e.g. trustPolicy: no-downgrade in .yarnrc.yml) that prevents Yarn from installing a package version whose trust level (trusted publisher → provenance → none) is lower than what previous versions of that package established. This is the single most impactful client-side mitigation against account-takeover supply chain attacks.
Motivation
On March 31, 2026, axios — a package with 60M+ weekly downloads — was compromised when an attacker gained access to the lead maintainer's machine via social engineering and published two malicious versions (1.14.1 and 0.30.4) directly from the compromised account. The malicious versions injected a dependency containing a cross-platform remote access trojan. They were live for ~3 hours before removal. Full post-mortem: axios/axios#10636.
The critical detail: axios had been publishing with provenance attestations prior to the attack, but the malicious versions were published manually from the attacker's machine — without provenance. This is a clear, detectable trust downgrade. If Yarn had a mechanism to reject installs where provenance disappears after previously being present, every consumer with that setting enabled would have been protected automatically, without needing to wait for community detection or registry intervention.
This is not a hypothetical scenario. The same pattern appeared in the s1ngularity attack (August 2025) and is the expected fingerprint of any credential-theft attack: the attacker has the maintainer's npm token but not access to the CI/CD pipeline, so the malicious publish lacks provenance.
Yarn already supports publishing with provenance via npmPublishProvenance: true (since v4.9.0), so the infrastructure for reading and verifying attestation metadata is partially in place. This proposal extends that to the install side.
Prior art
pnpm (trustPolicy: no-downgrade)
pnpm shipped this in v10.21 (November 2025). Configuration:
# pnpm-workspace.yaml
trustPolicy: no-downgrade
trustPolicyExclude:
- 'chokidar@4.0.3'
- 'webpack@4.47.0 || 5.102.1'
trustPolicyIgnoreAfter: 525600 # ignore for packages published >1 year ago
Trust levels are ordered: trusted publisher > provenance > none. If any previously published version of a package had a higher trust level than the version being resolved, installation fails with a clear error:
ERR_PNPM_TRUST_DOWNGRADE High-risk trust downgrade for "axios@1.14.1" (possible package takeover)
Earlier versions had provenance attestation, but this version has no trust evidence.
A trust downgrade may indicate a supply chain incident.
The trustPolicyExclude setting allows allowlisting specific package@version pairs for legitimate downgrades (new maintainer, CI migration, etc.), and trustPolicyIgnoreAfter prevents false positives from old packages that predate provenance.
npm RFC 0049
The accepted RFC 0049 already anticipated this direction:
"The long-term solution to bypassing verification is enforcing or requiring that all packages have provenance information set during install time in the npm CLI. [...] We could make it harder to remove provenance information once it's been set by a maintainer. For example, blocking a npm publish that doesn't include it if the current latest version does include it."
This feature request is asking for the consumer-side half of that vision, for Yarn users.
Existing Yarn provenance support
Yarn already consumes and produces provenance on the publish side via the npmPublishProvenance option. What's missing is the symmetric guarantee on the install side: ensuring the packages we consume don't silently lose their trust signals between versions.
Proposal
Configuration
Add a trustPolicy setting to .yarnrc.yml:
trustPolicy: no-downgrade
This should be respected by yarn install across all supported linkers (node-modules, pnp, pnpm) and workspaces.
Behavior
During yarn install, after resolution and before fetching/linking to the project's virtual filesystem, check each resolved package:
- Query the npm registry (or configured
npmRegistryServer) for attestation metadata across published versions of that package.
- Determine the highest trust level any previously published version achieved.
- If the version being installed has a lower trust level, fail the install with a clear, actionable error message.
This check should integrate with Yarn's existing fetch pipeline so that results can be cached, and should respect npmScopes / npmRegistries configuration for packages served from non-default registries (skipping the check gracefully for registries that don't expose attestation APIs).
Escape hatches
Following pnpm's proven model, adapted to Yarn's config conventions:
trustPolicyExclude: allowlist specific package@version pairs (or ranges) that are known-safe despite a downgrade.
trustPolicyIgnoreAfter: skip the check for packages whose most recent provenance-bearing version was published more than N minutes ago (handles legacy packages that never had provenance).
Example .yarnrc.yml
trustPolicy: no-downgrade
trustPolicyExclude:
- 'chokidar@4.0.3'
- 'webpack@4.47.0 || 5.102.1'
trustPolicyIgnoreAfter: 525600 # minutes (1 year)
Error output
A Yarn-native error message, consistent with Yarn's existing diagnostic style:
➤ YN0088: │ Trust downgrade detected for axios@1.14.1
│ Previous versions had provenance attestations, but this version does not.
│ This may indicate a supply chain compromise.
│
│ If this downgrade is expected, add it to trustPolicyExclude in .yarnrc.yml:
│ trustPolicyExclude:
│ - 'axios@1.14.1'
Impact
- axios incident: would have been blocked. The attacker published without provenance after prior versions had it → trust downgrade → install refused.
- s1ngularity incident: same pattern, would have been blocked.
- Any credential-theft attack where the attacker doesn't control CI/CD: blocked by default.
This doesn't prevent all supply chain attacks (a compromised CI/CD pipeline would still produce valid provenance), but it eliminates the most common and easiest attack vector at near-zero cost to developers.
Considerations
- Performance: attestation metadata fetching can piggyback on the existing packument fetch in Yarn's npm resolver, or be batched. The registry could include trust-level info in the packument to avoid extra round-trips.
- Adoption: this should be opt-in initially (off by default), similar to how pnpm rolled it out. Organizations and security-conscious teams can enable it immediately.
- Offline / zero-install workflows: since Yarn caches resolved packages in
.yarn/cache and supports zero-installs, the trust check should run at resolution time and its result should be recorded in yarn.lock (or a sidecar file) so that subsequent offline installs don't require re-fetching attestation metadata. Invalidation happens naturally when the lockfile changes.
- Plugin vs. core: this could ship as a first-party plugin (
@yarnpkg/plugin-trust-policy) to allow iteration before landing in core, following Yarn's usual pattern.
- False positives: legitimate trust downgrades do happen (maintainer migrating CI, publishing a hotfix manually). The exclude list and ignore-after settings handle this gracefully. pnpm's real-world experience shows these are manageable.
- Private registries: many private registries (Verdaccio, Artifactory, GitHub Packages) don't currently expose provenance metadata. The implementation should degrade gracefully — scopes pointing at registries without attestation APIs should be skipped rather than failing the install.
- Registry-side complement: ideally the registry could also enforce this (block a publish without provenance if previous latest had it, as RFC 0049 suggested). But the client-side check is independently valuable and doesn't require registry changes.
References
Summary
Add a configuration option (e.g.
trustPolicy: no-downgradein.yarnrc.yml) that prevents Yarn from installing a package version whose trust level (trusted publisher → provenance → none) is lower than what previous versions of that package established. This is the single most impactful client-side mitigation against account-takeover supply chain attacks.Motivation
On March 31, 2026, axios — a package with 60M+ weekly downloads — was compromised when an attacker gained access to the lead maintainer's machine via social engineering and published two malicious versions (
1.14.1and0.30.4) directly from the compromised account. The malicious versions injected a dependency containing a cross-platform remote access trojan. They were live for ~3 hours before removal. Full post-mortem: axios/axios#10636.The critical detail: axios had been publishing with provenance attestations prior to the attack, but the malicious versions were published manually from the attacker's machine — without provenance. This is a clear, detectable trust downgrade. If Yarn had a mechanism to reject installs where provenance disappears after previously being present, every consumer with that setting enabled would have been protected automatically, without needing to wait for community detection or registry intervention.
This is not a hypothetical scenario. The same pattern appeared in the s1ngularity attack (August 2025) and is the expected fingerprint of any credential-theft attack: the attacker has the maintainer's npm token but not access to the CI/CD pipeline, so the malicious publish lacks provenance.
Yarn already supports publishing with provenance via
npmPublishProvenance: true(since v4.9.0), so the infrastructure for reading and verifying attestation metadata is partially in place. This proposal extends that to the install side.Prior art
pnpm (
trustPolicy: no-downgrade)pnpm shipped this in v10.21 (November 2025). Configuration:
Trust levels are ordered: trusted publisher > provenance > none. If any previously published version of a package had a higher trust level than the version being resolved, installation fails with a clear error:
The
trustPolicyExcludesetting allows allowlisting specific package@version pairs for legitimate downgrades (new maintainer, CI migration, etc.), andtrustPolicyIgnoreAfterprevents false positives from old packages that predate provenance.npm RFC 0049
The accepted RFC 0049 already anticipated this direction:
This feature request is asking for the consumer-side half of that vision, for Yarn users.
Existing Yarn provenance support
Yarn already consumes and produces provenance on the publish side via the
npmPublishProvenanceoption. What's missing is the symmetric guarantee on the install side: ensuring the packages we consume don't silently lose their trust signals between versions.Proposal
Configuration
Add a
trustPolicysetting to.yarnrc.yml:This should be respected by
yarn installacross all supported linkers (node-modules,pnp,pnpm) and workspaces.Behavior
During
yarn install, after resolution and before fetching/linking to the project's virtual filesystem, check each resolved package:npmRegistryServer) for attestation metadata across published versions of that package.This check should integrate with Yarn's existing fetch pipeline so that results can be cached, and should respect
npmScopes/npmRegistriesconfiguration for packages served from non-default registries (skipping the check gracefully for registries that don't expose attestation APIs).Escape hatches
Following pnpm's proven model, adapted to Yarn's config conventions:
trustPolicyExclude: allowlist specificpackage@versionpairs (or ranges) that are known-safe despite a downgrade.trustPolicyIgnoreAfter: skip the check for packages whose most recent provenance-bearing version was published more than N minutes ago (handles legacy packages that never had provenance).Example
.yarnrc.ymlError output
A Yarn-native error message, consistent with Yarn's existing diagnostic style:
Impact
This doesn't prevent all supply chain attacks (a compromised CI/CD pipeline would still produce valid provenance), but it eliminates the most common and easiest attack vector at near-zero cost to developers.
Considerations
.yarn/cacheand supports zero-installs, the trust check should run at resolution time and its result should be recorded inyarn.lock(or a sidecar file) so that subsequent offline installs don't require re-fetching attestation metadata. Invalidation happens naturally when the lockfile changes.@yarnpkg/plugin-trust-policy) to allow iteration before landing in core, following Yarn's usual pattern.References
trustPolicydocumentationnpmPublishProvenanceconfiguration