chore: enforce supply chain age gating#16
Conversation
Supply chain hardening — reject npm packages published less than 7 days ago and disable install scripts by default. Override for emergency updates: npm install <pkg> --min-release-age=0 Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
PR Review: chore: enforce supply chain age gatingGood supply-chain hardening initiative. A couple of items to consider before merging: 1.
|
CR feedback: document that min-release-age requires npm 11+ (CI-enforced only on older Node), and that ignore-scripts suppresses prepublishOnly during local publish (CI runs build explicitly). Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
PR Review: chore: enforce supply chain age gatingOverall AssessmentThis is a well-scoped, high-value security hardening change. The Positives
Minor Considerations (non-blocking)
SecurityNo concerns — this strictly tightens the security posture with no new attack surface. VerdictApprove. Clean, well-documented, and the CI workflows already handle the |
Both reviews flagged that `min-release-age=7` silently no-ops on npm <11 (Node <22), so contributors on older Node versions get no local enforcement. CI already runs Node 22 and is the real gate, but an `.nvmrc` nudges local dev toward the enforced version. Also extends the `ignore-scripts` comment in `.npmrc` with the per-package override escape hatch (`npm install <pkg> --ignore-scripts=false`), documenting how to handle future dependencies that legitimately need a postinstall hook. Deferred from the review: bumping `engines.node` from `>=18` to `>=22`. That is a user-facing breaking change for a published SDK (consumers would see EBADENGINE warnings / hard errors with engine-strict) and belongs in its own PR with explicit intent, not buried in a supply-chain hardening change. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Review feedback addressed — commit 3b8cdf2Both reviews' remaining non-blocking items are in. Fixed
Deferred
Already addressed in earlier commits
All earlier suggestions are now either landed or explicitly deferred with reasoning. |
PR Review —
|
The .npmrc sets ignore-scripts=true as a supply-chain defense, which also suppresses prepublishOnly during `npm publish`. CI explicitly runs `npm run build` before publishing so the release workflow is safe, but a local publish would ship whatever is in dist/ without re-running the build. Called out in the Releases section of CONTRIBUTING.md so contributors don't trip over this footgun, and pointed at `npm run build` as the alternative for local artifact inspection. Addresses the reviewer's footgun note on #16. Verified `npm ci` still completes cleanly with the .npmrc in place. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Additional round addressed — commit 5b0dd00New review came back clean-approve with three minor non-blocking observations. Picked up the two actionable ones. Fixed
Deferred (explicit, reviewer agreed)
All three items from the latest review are now either landed or explicitly deferred with reviewer-agreed reasoning. |
PR Review:
|
Review acknowledged — no changes neededRead the latest review carefully. It's a clean Approve. Ready to merge. verdict with zero actionable items — every section is either (a) confirming existing choices are correct or (b) positive observations. The one explicit "nit" is flagged as "a non-issue in practice" by the reviewer themselves. Verified the one nit
Cross-checked:
All three are intentionally aligned at the major-version level. Pinning further (e.g., On version manager compatibility: nvm, fnm, volta, and asdf-nodejs all handle a plain major version in Verified across the rest of the review
Nothing to change. Ready to merge whenever you pull the trigger. |
Summary
.npmrcwithmin-release-age=7to reject npm packages published less than 7 days agoignore-scripts=trueto block arbitrary install scripts from packagesWhy
Newly published or hijacked packages are typically detected and removed within days. A 7-day quarantine ensures compromised packages never enter our dependency tree.
Override for critical updates
Test plan
npm config get min-release-age --location=projectreturns7npm installstill resolves existing dependencies from lock filenpm install --min-release-age=0 <pkg>bypasses the restriction