npm (Node Package Manager Registry)
What it is: The world’s largest software registry by volume. Public, free to publish, ~3M packages. Owned by GitHub (Microsoft). Status: Mature, ubiquitous, deeply battle-scarred. The canonical case study for “what happens when you make publishing too easy.” Most relevant to Locara: The supply chain horror stories from npm are the cautionary tale Locara must engineer against. Its mistakes are catalogued and well-understood.
Background
npm launched in 2010 as Node.js’s bundled package manager. Anyone with an email address could publish; namespace was first-come-first-served. By 2018 it had become both critical infrastructure for the JavaScript ecosystem and the textbook example of supply chain risk. Microsoft acquired it in 2020 via GitHub.
Key design decisions
- Free, frictionless publishing. No review, no signature initially, no identity verification beyond email.
- Flat namespace — first-come names. (Scoped packages
@org/namecame later as partial fix.) - Semantic versioning —
^1.2.3and~1.2.3ranges encourage automatic minor updates. package.jsonfor metadata + dependencies.- Lockfiles (
package-lock.json,yarn.lock,pnpm-lock.yaml) added later for reproducible builds. npm audit— known-vulnerability scanner against the public advisory database.npm provenance(recent) — Sigstore-based attestation linking package to source/CI.- Two-factor auth for publish — required for high-impact maintainers, optional for others.
- Tarballs immutable after publish — but unpublishing is allowed within 72 hours (lessons from
left-pad). - Deprecation flag for retiring packages without removing them.
What worked
- Frictionless publishing built ecosystem velocity. Without the open-floodgates approach, Node would not have eaten the world.
- Semver + range dependencies = automatic security patch propagation (when it works).
- Lockfiles finally solved reproducibility (after years of pain).
- Provenance via Sigstore is a genuine improvement to supply chain trust — verifies a package was built from claimed source by claimed CI.
npm auditis widely run in CI and during dev.
What failed / criticisms
- Supply chain attacks are routine. Examples:
left-pad(2016): maintainer unpublished a 17-line module; broke 50% of npm builds globally. Led to “no unpublish after 72h” policy.event-stream(2018): popular package transferred to malicious maintainer, who injected crypto-stealing code. Hidden in transitive dep of millions of projects.ua-parser-js(2021): legitimate maintainer’s account compromised, malicious versions published.colors/faker(2022): maintainer self-sabotage — pushed infinite-loop / corrupted versions to protest unpaid OSS labor.- Hundreds of typosquats continually shipped to mimic popular packages.
- First-come namespace allowed name-grabbing and squatting.
- Transitive trust is unbounded. Installing one package pulls hundreds of indirect dependencies, each a potential attack vector.
- Auto-update + range deps make minor version bumps a vehicle for malicious code distribution.
- No identity verification. Anyone can publish under “Microsoft” if the name’s free. (Org-verification only added in response to abuse.)
postinstallscripts = arbitrary code execution at install time. Massive attack surface, used for both legitimate and malicious purposes.- Provenance adoption is low — most packages still don’t have it, and verifying it is opt-in.
Specific learnings for Locara
- Frictionless publishing is dangerous when capabilities are strong. Locara apps will have access to local files, models, tools — much more sensitive than a typical npm package. The “anyone can publish freely” model is unsafe. Locara needs identity-verified publishers from day one.
- Provenance / signed builds are non-optional. Every Locara app must have a signed provenance attestation linking the binary to a specific source commit and CI build. Locara CI does the build; user-uploaded binaries are rejected. Eliminates entire classes of attacks.
- No
postinstall-equivalent. Locara apps should never execute arbitrary code at install time. Install = unpack + register; no scripts run. - No transitive expansion. Locara apps are self-contained binaries. They don’t pull more code at runtime. (Models are content-addressed, fetched separately, verified.)
- Namespace via verified orgs. Apps live under a
publisher/app-namenamespace; publisher is verified (DNS, GitHub, OAuth). Rejects squatters. - Mandatory 2FA for all publishing. No exceptions. Compromised accounts are the most common attack vector; 2FA is the cheapest mitigation.
- Cool-down on capability expansions. If an app updates and adds new capabilities (e.g., gains network access), users get re-prompted and the update goes live with a delay. Catches compromised-update attacks.
- Update auto-application policy. Apple/npm’s auto-update is convenient but compounds compromise impact. Locara might require user-confirmation on minor updates and only auto-apply patch-level (non-capability-changing) updates.
- Immutable artifact history, plus rapid takedown. Bad releases can be marked malicious and uninstalled from user devices remotely (kill-switch), but the record stays. Better than
left-pad-style memory-holing. - Audit-style security reporting. Locara should publish a vuln database for apps and runtime, integrate with
locara auditchecks. Plagiarize npm’s advisory format.
References
- https://docs.npmjs.com/about-the-public-npm-registry
- https://docs.npmjs.com/generating-provenance-statements
- https://snyk.io/blog/javascript-supply-chain-security/
- Postmortems: left-pad (Mar 2016), event-stream (Nov 2018), ua-parser-js (Oct 2021), colors/faker (Jan 2022)
- SLSA framework: https://slsa.dev/