Editorial

Provenance attestations and trusted publishing do not mean a package is safe

RobertUpdated Sep 15, 20266 min readmethodology
Terminal-style graphic reading PROVENANCE VALID, TRUSTED PUBLISH PASS, and PACKAGE SAFE FALSE, showing that attestations do not equal install safety.

Valid npm provenance and trusted publishing prove how a package was built and which identity published it. They do not prove the published bytes are safe.

That gap is not theoretical anymore. On 3 September 2026, npm made multiple trusted publishing (OIDC) configurations generally available, along with stricter staged-publish rules that wait for malware scanning before approval. Those are real hardening steps for publishers. They still do not answer the install-time question developers actually ask:

Is this version safe to run?

Public ChainDrop analysis from Zscaler ThreatLabz shows why. Attackers who control a trusted source repository or CI path can ship poisoned releases that still carry authentic SLSA provenance, because the attestation correctly describes a compromised build that the legitimate workflow really ran.

Trusted publishing proves publisher identity, not package safety#

Trusted publishing replaces long-lived npm tokens with short-lived OIDC credentials from a named CI workflow. Provenance (Sigstore / SLSA) binds the published tarball to that build identity and source metadata.

npm's own provenance docs are explicit about the limitation: establishing provenance does not guarantee the package has no malicious code. It gives a verifiable link to source and build instructions so reviewers can decide what to trust.

The 3 September 2026 changelog strengthens that publish path:

  • Multiple independent OIDC configurations per package (stable, prerelease, staging).
  • Staged packages cannot be approved until npm malware scanning completes.
  • Maintainers can inspect staged history in the versions tab.

Those controls reduce token theft and make direct publish from a compromised workflow harder when staging is enforced. They do not certify that the trusted workflow, repository, or maintainer identity was uncompromised when the build ran.

ChainDrop showed valid SLSA on poisoned releases#

ChainDrop was the August 2026 self-propagating npm worm that spread across hundreds of packages after attackers poisoned trusted publish paths. The 2026 state of npm supply chain security post already flagged the same failure mode: malicious versions published through legitimate GitHub Actions workflows with valid provenance attestations.

Zscaler's ChainDrop write-up is the primary public confirmation for the provenance point. The attacker compromised maintainer GitHub access for packages in the keyv ecosystem, pushed malicious commits, and let the project's own release pipeline build and publish. Because the build came from the legitimate repository and workflow, releases such as [email protected] carried authentic SLSA Build Level 3 provenance. Automated checks that only ask "does this package have valid provenance?" would have waved it through.

That is the mechanism:

  1. Attacker controls source or CI inputs inside a trusted publish path.
  2. The authorized workflow builds attacker-controlled code.
  3. Sigstore / SLSA attestations are valid for that workflow identity.
  4. The registry artifact is still malware.

Provenance answered: which workflow built this?

It did not answer: should anyone install it?

Account takeover without provenance is a different failure mode#

Not every high-impact npm compromise looks like ChainDrop.

The Sapphire Sleet campaign against debug, chalk, and axios was largely account-takeover driven. In several of those publishes, missing or incomplete trusted-publisher metadata was itself a useful anomaly signal. That is the opposite fingerprint from ChainDrop.

Both classes matter:

  • Token or account takeover: publish may lack expected provenance.
  • Trusted path takeover: publish may have perfect provenance.

A policy that only requires "provenance present" fails the second class. A policy that only requires "provenance missing" fails when attackers publish without it on purpose, or when older packages never adopted it.

Defence needs an independent malicious-publish signal, not a single attestation checkbox.

What Attestd returns for a ChainDrop version (live-verified)#

Attestd keeps CVE-derived risk_state and supply-chain compromise as separate conditions. For monitored packages it also exposes a supply_chain.provenance field. That field is Attestd's own recorded provenance state for the version. It is not a substitute for reading the Sigstore attestation on the registry.

Live verification on 12 September 2026 against Attestd production (GET /v1/check):

[email protected] (npm):

text
ecosystem: npm (product=keyv)
version: 6.0.0
risk_state: critical
actively_exploited: false
cve_ids: []
supply_chain_monitored: true
supply_chain.compromised: true
supply_chain.compromised_at: 2026-08-04T11:19:14Z
supply_chain.provenance: null
supply_chain.sources: ["agent", "npm_registry", "osv"]

Compare with a clean later line on the same package:

[email protected]:

text
risk_state: none
supply_chain.compromised: false
supply_chain.provenance: null

And another ChainDrop-adjacent version from the Detection Ledger / OSV set:

[email protected]:

text
risk_state: critical
supply_chain.compromised: true
supply_chain.compromised_at: 2026-08-04T10:43:17Z
supply_chain.provenance: false
supply_chain.sources: ["agent", "osv"]

What this means for the thesis: Attestd's meaningful addition here is not "we re-validated SLSA." Primary reporting already established that some ChainDrop publishes carried valid provenance. Attestd's contribution is the independent supply_chain.compromised: true condition (with version-specific compromised_at and sources), which still fires when a provenance-only gate would pass.

The Detection Ledger entry keyv-2026-08-04 records npm package keyv version 6.0.0 with OSV MAL-2026-11524 (OSV published at 2026-08-04T11:19:14Z). That timestamp is the advisory / registration side of the record, not press time.

For a constructed request shape (authorization required):

bash
curl "https://api.attestd.io/v1/check?product=keyv&version=6.0.0" \
  -H "Authorization: Bearer $ATTESTD_API_KEY"

Treat the field values above as live-verified as of 12 September 2026. Do not collapse them into "provenance said safe."

A 10-minute checklist before you trust an install#

  1. Require trusted publishing where you control the package. Prefer stage-only OIDC configs after the 3 September 2026 GA, and treat direct publish as an exception.
  2. Do not stop at attestation presence. Valid SLSA proves build identity. Review whether that identity is still the one you expect, and whether the commit was authorized.
  3. Check an independent compromise signal. Gate CI on supply_chain.compromised before npm ci, as described in CI/CD supply-chain checks and the supply chain docs.
  4. Keep CVE risk separate. risk_state answers vulnerability state. Compromise can still present with empty cve_ids, as in the [email protected] live response above. See also supply chain compromise vs CVE.
  5. Assume credential exposure if a compromised version ran. Rotate npm, GitHub, cloud, and AI-provider secrets from affected runners and laptops. Upgrading away from the bad version does not revoke what already left the box.
  6. Watch for both fingerprints. Missing provenance can be a tell for token theft. Present provenance can still be malware after CI or source compromise.

Provenance is necessary. It is not sufficient.#

Trusted publishing and provenance attestations are worth adopting. They shrink the blast radius of stolen classic tokens and make publish identity auditable.

They are not a package safety verdict.

ChainDrop made that concrete: authentic SLSA on a release that should never have been installed. npm's September 2026 trusted-publishing GA makes the publish path better for maintainers. Install-time defence still needs a separate malicious-publish signal, version by version.

If you are mapping the wider attack surface, start with the pillar on how npm supply chain attacks work, then wire compromise checks into the path that actually installs software.