Join our Newsletter — 33% off our NHI Course

What should teams do first when npm install scripts are no longer trusted by default?

Start by inventorying every package that relies on install-time execution, including lifecycle scripts, Git dependencies, and remote URLs. Then separate what is required for build correctness from what is merely convenient, because only the required set should enter an approval workflow. The first control objective is visibility into where code currently runs during installation.

Start by making installation-time execution visible

The first move is to find where package installation still runs code, because that is the control boundary that changed when npm install scripts stopped being trusted by default. Inventory lifecycle scripts, Git dependencies, remote tarballs, and any package that assumes install-time execution for setup. If you do not know where code executes during install, you cannot decide what to approve, replace, or remove.

That inventory should distinguish build-critical behaviour from convenience behaviour. Some packages need install-time work to compile native modules or generate artifacts, while others only use scripts for telemetry, postinstall prompts, or optional tooling. Treat those two classes differently, because only the first class should survive a tighter approval model.

Teams should also look for hidden dependency paths that reintroduce execution indirectly. A direct npm package may be clean, while a transitive dependency, Git URL, or downloaded helper script still runs code during installation. The practical question is not whether the package is popular, but whether the install path has execution authority that must now be justified.

Separate required execution from convenience execution

Once the inventory exists, classify each install-time action by necessity. Build correctness means the package cannot be installed, compiled, or used without that step; convenience means the step only improves developer experience, automation speed, or optional setup. That separation matters because approval workflows should be reserved for the smallest possible set of packages and scripts that actually affect correctness.

This is also the point where teams should challenge assumptions about “standard” package behaviour. Many install scripts grew over time to support legacy environments, native build steps, or shortcuts that are no longer essential. If a package can function with prebuilt artifacts, explicit setup commands, or a separate build phase, those options usually reduce the amount of code that needs execution during install.

Where installation is genuinely required, prefer controls that make the dependency visible and auditable rather than invisible and automatic. The goal is to keep the build deterministic while shrinking the number of places where third-party code can execute before review, logging, or isolation controls have a chance to apply.

Approve only the narrow set that still needs runtime installation

After classification, move only the required set into an approval workflow and treat everything else as removable or replaceable. That workflow should answer a simple question: does this install-time action materially affect the package’s ability to build or run, or is it just a historical convenience? If it is only convenience, it should not earn trusted execution by default.

For the required set, approval should be tied to concrete evidence such as package provenance, install behaviour, and the expected output of the script. For non-required cases, the correct response is to remove the script, pin a safer distribution method, or switch to a package that does not depend on install-time execution. This is how teams reduce the blast radius without breaking every build at once.

Internal validation of installation-time execution should sit alongside broader supply-chain checks. The same dependency review that identifies install scripts should also catch abnormal source locations, unexpected Git dependencies, and packages that pull in remote code at install time. In practice, those are the paths most likely to turn a routine install into an execution event.

Risk and Threat Considerations

Install-time code is attractive to attackers because it runs early, often with the developer’s or CI system’s permissions, and is easy to hide inside legitimate package behaviour. Once teams stop trusting npm install scripts by default, the main risk becomes incomplete visibility: a dependency that still executes during installation can steal secrets, modify the build, or seed persistence before anyone notices.

Failure mechanism: A package, transitive dependency, or Git-based install path executes code during installation without a clear business need, allowing malicious or compromised code to run before normal review and isolation controls.

Impact: The result can be credential theft, poisoned builds, supply-chain propagation, or the silent expansion of trust to packages that should have been treated as untrusted input.

Standards & Framework Alignment

This section maps relevant standards and security frameworks to the operational risks and controls described in this guidance.

SLSA, CIS Controls v8, NIST SP 800-53 Rev 5 and OWASP ASVS set the governance and control requirements practitioners need to meet.

Framework Control / Reference Relevance
SLSA Supply chain provenance Install-time execution changes supply-chain trust and artifact integrity.
Recommendation — Require provenance controls for packages that still execute during install.
CIS Controls v8 CIS-5 — Account Management Trusted install paths often execute with developer or CI account access.
Recommendation — Limit install-time execution to accounts and environments that truly need it.
NIST SP 800-53 Rev 5 CM-7 — Least Functionality Unneeded install scripts are unnecessary functionality that expands exposure.
SA-12 — Supply Chain Protection The question is about controlling third-party code introduced during installation.
Recommendation — Remove install-time functionality that is not required for correct operation. Vet package sources and installation behaviour before allowing execution.
OWASP ASVS V15 — Secure Coding and Architecture The answer distinguishes required build behaviour from convenience-driven execution.
Recommendation — Design builds so installation does not depend on unnecessary code execution.

Practitioner Guidance

What to verify: Teams should verify not just the package name, but the exact install behaviour. Check lifecycle scripts, package source, transitive dependencies, and whether the build breaks if install-time execution is removed. If the answer is “only the script keeps convenience features alive,” that script is a removal candidate, not an approval candidate.

Decision rule: If a package needs install-time execution to build correctly, route it through approval and tighter review. If it only improves convenience, move that work out of installation and do not let it inherit default trust.

Practitioner takeaway: The first objective is not to ban all installation-time behaviour, but to make it explicit enough that teams can separate required build logic from unnecessary execution and shrink trust to the minimum viable set.