Software Supply Chain Security
Software supply chain security protects the path from someone else's source code to software running in your environment. Dependencies, package registries, build tools, CI workflows, and publishing identities all belong to that path. A secure application can still ship compromised code if its build or dependencies are compromised.
Coverage window: October 5, 2025–October 5, 2026. This guide uses npm's authentication changes and a documented package incident to explain practical controls. Foundational concepts below predate this window; dated developments are identified separately. The examples focus on JavaScript, but the separation of acquisition, build, and release applies across ecosystems.
TL;DR
- Review dependency changes before executing their code, including installation scripts.
- Use short-lived publishing identities and restrict which workflow can obtain them.
- Treat provenance as evidence of origin and build process, not a malware-free certificate.
- Keep dependency installation and tests away from production and publishing credentials.
- Preserve dependency inventories and release evidence so incidents can be investigated quickly.
Quick Example
Start with an offline inspection. Save this as audit-lockfile.mjs beside an npm lockfile using format 2 or 3, then run node audit-lockfile.mjs. It reads metadata without installing dependencies, accessing the network, or running package code.
The lockfile documentation defines these metadata fields. Workspaces, private registries, and native modules can produce legitimate findings. An empty report only means these checks found nothing; it does not establish that the dependency tree is safe.
Core Concepts
Integrity, identity, and intent
An integrity hash helps identify a particular artifact. A signature ties data to a signing identity. Neither answers whether the code does what your application needs or whether its behavior is acceptable. If a malicious release is the artifact you approved, faithfully retrieving its bytes preserves the problem.
Provenance
Provenance records how an artifact relates to source and its build. Consumers can examine that evidence when deciding whether to trust a release. npm explicitly states that provenance does not guarantee the absence of malicious code. Its provenance documentation also distinguishes this evidence from ordinary package metadata. npm provenance
Publishing authority
Trusted publishing uses OpenID Connect, or OIDC, to associate a CI workflow with registry publishing permission. Configure the intended repository and workflow precisely. For GitHub Actions, npm also supports an environment constraint. This reduces reliance on stored publishing secrets, while making protection of the authorized workflow particularly important. Trusted publishing documentation
Inventory
A software bill of materials, or SBOM, lists components. npm can produce CycloneDX or SPDX output with npm sbom; its lockfile-only mode reads the recorded dependency tree. That inventory helps locate affected releases, but it does not prove what a running deployment contains. Associate it with the actual build artifact. npm SBOM documentation
What Changed During the Last Year
November 2025: a concrete dependency incident
On November 24, 2025, Postman disclosed that public packages in its npm organization had been infected during the Shai-Hulud 2.0 campaign. Its notice identifies affected package versions and distinguishes those packages from its application and production cloud services, which it reported were not compromised. Use the version list and updated timeline when investigating historical exposure. Postman incident notice
The practical lesson is to investigate where a package was installed and executed, rather than assuming the scope of a familiar vendor's incident from its name alone.
December 2025: classic npm tokens stopped working
On December 9, 2025, npm permanently revoked classic tokens and introduced two-hour sessions for npm login. The announcement also documented a maximum 90-day lifetime for granular write tokens. December 9 is the completed revocation date; earlier migration announcements had proposed an earlier deadline. npm authentication changes
Audit release jobs for assumptions about permanent credentials. A pipeline that still expects an obsolete authentication method needs a publishing migration, not repeated retries.
September 2026: staging and promotion gained narrower controls
On September 18, 2026, npm introduced opt-in stage-only granular tokens. They can submit a version with npm stage publish, followed by maintainer approval using 2FA, but cannot directly publish a new version. They still retain other write capabilities, including changing dist-tags and deprecating versions. The announcement describes January 2027 removal of direct publishing through bypass-2FA tokens as a target, not a completed change within this guide's window. Stage-only token announcement
On September 30, npm added an independent, opt-in permission for trusted publishers to manage dist-tags using OIDC. This lets teams evaluate removing a stored token previously retained solely for promotion or rollback. The permission defaults to off. Dist-tag permission announcement
Build a Dependency-to-Release Workflow
Start dependency updates in a review branch. Inspect the manifest and lockfile diff together: a small direct upgrade can replace many transitive packages. Check unexpected registry origins, newly introduced installation scripts, and unexplained changes to the upstream release process.
Install in a disposable build environment with only the access needed for that job. npm ci --ignore-scripts suppresses package scripts during installation, but a later explicit npm test or npm run still executes the requested script. Some dependencies require reviewed build steps before they function correctly. npm ci behavior
Use separate checks for separate questions. npm audit asks the configured registry about known vulnerabilities; npm audit signatures verifies supported registry signatures and provenance attestations for downloaded packages. Neither result substitutes for reviewing code or release authority. npm audit documentation
Finally, promote an identified artifact through a controlled release job. Record its digest, source revision, dependency inventory, and approval. This gives responders something concrete to compare with deployed software.
Best Practices
Minimize credentials during builds
Give dependency-fetching jobs read-only registry access when required. Keep publishing authority out of pull-request tests. For example, a failed unit test should never have had permission to release a package in the first place.
Review the release boundary
Protect workflow changes and require appropriate review before release. A reviewer should inspect the artifact being approved, including generated files; approving only a source diff misses what packaging added or omitted.
Prepare incident evidence
Keep lockfiles and build records with release identifiers. During a suspected compromise, pause affected releases, identify executions, preserve evidence, and revoke exposed credentials from a clean environment. GitHub's December 2025 guidance describes compromised credentials and malicious installation scripts as recurring campaign mechanisms. GitHub supply-chain guidance
Comparison
Common Mistakes
Assuming a signature approves behavior
Bad: Accept every signed dependency automatically.
Correct: Verify expected identities and review changes according to the dependency's role and exposure.
Restoring a compromised build with the same secrets
Bad: Remove the affected dependency and immediately rerun the release job.
Correct: Investigate execution and credential exposure, rebuild in a clean environment, and replace affected credentials before restoring releases.
Treating development dependencies as harmless
Bad: Review only packages that ship inside the production bundle.
Correct: Include test tools, transpilers, and release utilities. Their execution can affect the resulting artifact or the machine building it.
FAQ
Does trusted publishing prevent every supply chain attack?
No. It reduces reliance on reusable publishing tokens. A compromised authorized workflow can still perform authorized actions, so source review and release controls remain necessary.
Is disabling installation scripts enough?
No. It reduces one execution opportunity. Dependency code can also execute when imported, tested, built, or run as a tool; isolation must cover those stages too.
Should every vulnerability alert block a release?
Set an explicit policy based on severity, reachability, available fixes, and the deployment context. Record exceptions with an owner and review date so a temporary decision does not become permanent neglect.
Can an SBOM replace a lockfile?
They serve different jobs. A lockfile guides dependency resolution; an SBOM communicates component inventory. Keep both associated with the build they describe.
Related Topics
- Application Security — broader defensive engineering practices.
- Secrets Management — credential storage and rotation.
- CI/CD Pipelines — build, test, and release boundaries.
- GitHub Actions — workflow execution and automation.
References
- npm trusted publishing
- npm provenance statements
- npm lockfile format
- npm audit, npm ci, and npm SBOM
- Postman incident disclosure, November 24, 2025
- npm token revocation, December 9, 2025
- GitHub campaign preparedness, December 23, 2025
- Stage-only tokens, September 18, 2026
- OIDC dist-tag permissions, September 30, 2026