@ministryofjustice/hmpps-npm-script-allowlist
v0.0.3
Published
A tool to restrict npm scripts from running unless as part of an allowlist
Downloads
2,159
Readme
@ministryofjustice/hmpps-npm-allow-scripts
This package aims to restrict npm scripts from running unless as part of a predefined allowlist.
Status
This library is currently: ready to trial.
Teams are welcome to trial this library. Please provide feedback via slack to the #typescript channel.
Migrating existing projects
Automatically installing the library
The package will self install and initialised by running via npx:
npx @ministryofjustice/hmpps-npm-allow-scripts
Note: The project needs to be initialised before use - solely adding the library will not apply the required changes. Once the project has been initialised and changes commited, other developers should be able to benefit from the library without further local initialisation.
How this works
The library can be applied to a service by running npx @ministryofjustice/hmpps-npm-script-allowlist
This will:
- Set some sensible defaults in
.npmrcto prevent execution of scripts - Install the package
- Add a default configuration file
- Add a new npm script called
setup - Run the tool, which will likely fail allowing the developer to complete configuration
The tool can then be configured with a list of packages and their associated versions that should run be allowed to run scripts post install.
To work with the project after that:
npm installwill install packages but no longer executes any scripts due to the defaults set in.npmrcnpm run setuprunsnpm ci(without scripts) and then executes only those scripts that have been explicitly allowed.
A manual step is required to move CI and docker over to use npm run setup instead of npm ci
Configuration
To configure the tool update ./allowed-scripts.mjs and set ALLOW or FORBID to each entry in allowed-scripts.mjs, e.g::
import configureAllowedScripts from '@ministryofjustice/hmpps-npm-script-allowlist/index.mjs'
export default configureAllowedScripts({
allowlist: {
"node_modules/@parcel/[email protected]": "ALLOW",
"node_modules/[email protected]": "FORBID",
"node_modules/[email protected]": "ALLOW",
"node_modules/[email protected]": "FORBID",
"node_modules/[email protected]": "ALLOW"
},
})(The tool will play back the configuration and highlight versions which need to be added so an initial version can easily be copy/pasted in.)
By default hmpps-npm-script-allowlist will only manage and run the following scripts:
preinstallinstallpreparepostinstall
Scripts bound to other lifecycles will not be executed.
This list can be expand by specifying the following options in ./allowed-scripts.mjs:
localScriptsToRun: The list of the current service's scripts to run post installdependencyScriptsToRun: The list of script's belonging to dependencies, that should be allowed to run post install
Doesn't lavamoat do the same thing?
This is heavily inspired by lavamoat's allowscripts.
This works slightly differently:
- Scripts need to be explicitly configured either to be included or not or the script will fail
- This uses the explicit version in the package-lock.json to key whether a script should run or not, rather than just the name of the package
- It provides some extra contextual information about the packages that need to be allowlisted - details about the script and when the package was published.
Example output:
Reading configuration from some-project/.allowed-scripts.mjs
Current configuration: {
"node_modules/@parcel/[email protected]": "RUN",
"node_modules/[email protected]": "<REMOVED>",
"node_modules/[email protected]": "<MISSING>",
"node_modules/[email protected]": "RUN",
"node_modules/[email protected]": "<MISSING>",
"node_modules/[email protected]": "RUN"
}
ACTION REQUIRED:
Explicitly ALLOW/FORBID the following:
* node_modules/[email protected] (package published: 2025-08-07 18:35)
scripts:
postinstall: node dist/index.js --exec install
* node_modules/[email protected] (package published: 2023-08-21 17:24)
scripts:
install: node-gyp rebuild
ACTION REQUIRED:
Remove configuration for the following packages as they are no longer present:
* node_modules/[email protected]
Copy the "Current Configuration" from above and use it to update: some-project/.allowed-scripts.mjs.
* Remove any entries that are <REMOVED>
* Evaluate any entries marked <MISSING>. ALLOW or FORBID depending on whether these entries have scripts that are safe and required to run.Testing
Export a local package:
npm run lint && npm run build && npm run test && npm pack --pack-destination ~
cd to the project you want to test it on, and install:
npm install --ignore-scripts -D ~/ministryofjustice-hmpps-npm-script-allowlist-xxx.tgz
To test the init script:
npx -p ~/ministryofjustice-hmpps-npm-script-allowlist-0.0.1-alpha.2.tgz hmpps-npm-script-allowlist
To test the command directly:
./node_modules/.bin/hmpps-npm-script-run-allowlist
