RFC: package-level install trust check - #916
Conversation
8776f84 to
96753a3
Compare
|
The information about how a package was published is largely secret, intentionally so, so I'm not sure how this would be enforced. Separately, trusted publishing is simply not a security indicator of any kind, and using it in any such policy is a category error. |
fc2a7aa to
c0971d4
Compare
c0971d4 to
c019e97
Compare
Deep Technical Review: Package-level install trust check for automated and human consumersVerdictShip What's Well Done
Where the Threat Model MissesThe two incidents that defined npm security in the past year — Shai-Hulud (Sept 2025, 500+ packages via postinstall token theft) and the chalk/debug phished-maintainer takeover (17 packages, 2B+ weekly downloads) — were both publish-side compromises:
npm and GitHub's actual hardening this year has correctly landed on the publish side:
A download-side "prove you're human/CI" gate does not touch that chain. The worm runs after a legitimate install already succeeded, on hardware that already proved it was human. If Second-Order Risks Introduced
Mode-by-Mode Assessment
Concrete Recommendations
Open Questions Requiring Answers Before Merge
Review by nillmore — reasoning via deep-technical-reviewer agent |
|
slap happy agents be tweakin... |
Summary
This RFC adds an opt-in, per-package trust gate at the registry tarball endpoint.
Publishers choose one of four modes via
publishConfig.trustCheck:none(default)auditrequirerequire-humanautomation/servicetokens or OIDC trusted publishingThree traffic lanes, zero CAPTCHA:
X-NPM-Trust-Check-Challengenonce). No tokens, no browser, no setup.428 Precondition Required. The npm CLI triggers a native OS biometric prompt (Touch ID, Windows Hello, security key) via WebAuthn withuserVerification=required. The signature is bound tonpmjs.comand the package name; a remote LLM in a cloud sandbox cannot touch the enclave.spam_userblock — Known scrapers, TOR exits, open proxies, exploit tooling, and repeat abusers get403 TRUST_CHECK_BLOCKEDimmediately. No challenge, no fallback, no CAPTCHA.Every fetch (allowed or blocked) emits a standardized
install-trust-checkevent with atokenKind(heuristic-automation,unattended,human,automation,service, orspam_user), giving publishers real visibility into human vs automated adoption — something per-package CI tokens never delivered.Why this approach
Files added
accepted/0000-package-install-trust-check.md— the proposalaccepted/assets/package-install-trust-check/trust-check-ui-mockup.htmlaccepted/assets/package-install-trust-check/trust-check-ui-mockup.pngaccepted/assets/package-install-trust-check/trustcard-logo.pngValidation passed:
All RFC-required sections are present and no template placeholders remain.