| name | npm-supply-chain-hygiene |
| description | Harden the npm supply chain: committed lockfiles, frozen CI installs (npm ci), integrity hashes, .npmrc registry pin, and lifecycle-script risk (preinstall/install/postinstall/prepare). Use when package-lock.json, npm ci vs npm install, ignore-scripts, postinstall malware, registry.npmjs vs private registry, package.json scripts, or npm CI cache trust is in scope โ hand multi-ecosystem pins to dependency-pinning-strategies, namespace confusion to dependency-confusion, and SBOM gates to sbom-ci-enforcement.
|
npm Supply-Chain Hygiene
Own npm install-time trust: lockfile fidelity, CI install commands,
registry/auth config, and lifecycle scripts that run as the build user.
Does not own multi-ecosystem pin policy, SBOM legal format, or license law.
When To Use
- Reviewing or fixing
package-lock.json / npm-shrinkwrap.json drift
- CI uses
npm install (rewrites lock) instead of npm ci
- Suspicious or unexpected
preinstall / install / postinstall / prepare / prepublish
- Hardening
.npmrc (registry, always-auth, scope maps, ignore-scripts)
- Audit of monorepo workspaces, optionalDeps, git/URL deps, or tarball installs
- Mentions: npm supply chain, lockfile integrity, lifecycle script, npm ci, postinstall
Do not use as primary for:
| Need | Skill instead |
|---|
| Exact-vs-range / Renovate across ecosystems | dependency-pinning-strategies |
| Private vs public namespace confusion | dependency-confusion |
| SBOM generate/attest gates | sbom-ci-enforcement / sbom-and-supply-chain |
| License allow/deny | license-compliance-scan |
| Pipeline layout / fork PR secrets | ci-cd-pipeline-patterns |
| Registry token lifecycle / leak IR | secrets-management-hygiene |
Repo Config First
Repo and org npm policy outrank defaults below.
- Manifests: root and workspace
package.json; engines / packageManager field
- Lockfile:
package-lock.json (or shrinkwrap); lockfileVersion; committed vs gitignored
- Installer: npm vs yarn vs pnpm โ one story; do not mix generators on the same tree
- CI jobs: install command, cache key (lock hash), Node version (
.nvmrc / setup-node)
.npmrc / project + user: registry, @scope:registry, ignore-scripts, proxy
- Script policy: allowed lifecycle scripts,
ignore-scripts in CI, review owners
- Neighbors: Dependabot/Renovate, SCA job, private registry (Artifactory/GitHub Packages)
Precedence: Follow existing lock tooling and registry. Flag npm install that mutates
lock in CI, missing lock commit, or broad trust of third-party postinstall without review.
Workflow
1. Inventory the resolve surface
- List every
package.json (workspaces via workspaces field or packages/*).
- Confirm a single lockfile path CI uses; note lockfileVersion (v2/v3).
- Table high-risk direct deps: git/HTTP URLs,
file:, link:, latest/wide ranges,
optionalDependencies that pull native toolchains, and packages with install scripts.
- Capture
.npmrc registry hosts and whether auth is required for all private scopes.
2. Lockfile and frozen CI
| Rule | Why |
|---|
| Commit lock for apps/services | Same tree in CI, laptop, and prod image build |
npm ci in CI (not npm install) | Fails on lock/manifest mismatch; no silent rewrite |
| Cache keyed on lock hash | Poisoned or stale cache must not float versions |
| Review lock diffs | New packages, version jumps, resolved URL/host, integrity changes |
| Prefer integrity entries | Detect tarball swap when registry or CDN is compromised |
Never โfixโ CI by deleting the lock or running npm install to force a green build.
Regenerate lock on a controlled runner with the teamโs Node/npm major, then review the diff.
3. Lifecycle scripts (install-time code execution)
npm may run package scripts during install. Treat them as untrusted code until reviewed.
| Script | Typical trigger | Risk note |
|---|
preinstall / install / postinstall | Dependency install | Classic malware / crypto-miner vector |
prepare | Install from git; local npm install | Runs on consumers of git deps |
prepublish / prepublishOnly / prepack | Publish path | Can alter shipped tarball contents |
Root scripts in app | Explicit npm run | Lower install risk; still review CI npm run |
Controls (pick what policy allows):
ignore-scripts=true in CI when the product does not need native compile steps;
document exceptions (e.g. sharp, esbuild) installed in a controlled step.
- Review new or changed install scripts on every lock/manifest PR.
- Prefer packages that ship prebuilds over compile-at-install when possible.
- Run installs in least-privilege CI (no cloud OIDC/deploy keys until after install if feasible).
- Block unexpected network from install scripts in hardened runners when tooling exists.
4. Registry and auth hygiene
- Pin default
registry= and every @scope:registry= in committed project .npmrc or org template.
- Never commit tokens; use CI secrets / OIDC to the private registry.
- Fail closed if private scope resolves to
registry.npmjs.org unexpectedly.
- Avoid dual-index footguns that prefer public higher semver for internal names
(
dependency-confusion for full assessment).
- Disable or gate
npm audit fix that rewrites the tree without review in release branches.
5. Verify
- Clean
npm ci (cache miss): exit 0, lock unchanged. 2. Break lock vs manifest โ npm ci fails.
- Scripts-ignored path (if policy) still builds or exception list is explicit.
- Dep-bump lock diff shows only expected name/version/integrity/resolved host; no secrets in logs.
Routing
| Situation | Primary | Helper |
|---|
npm lock, npm ci, lifecycle scripts, .npmrc install trust | This skill | โ |
| Cross-ecosystem pin/Renovate policy | dependency-pinning-strategies | this for npm details |
| Namespace / registry confusion | dependency-confusion | this for npmrc/ci |
| SBOM CI presence/attest | sbom-ci-enforcement | frozen npm ci first |
| License policy | license-compliance-scan | lock versions from here |
| Pipeline topology / caches / checks | ci-cd-pipeline-patterns | this for npm job body |
| npm tokens / leak / rotation | secrets-management-hygiene | this for token use sites |
| CI YAML / script quality | code-quality-standards | always |
Keep this skill primary for npm install-time hygiene; hand off SBOM, license, and org-wide pin bots when those are the main ask.
Output Checklist