What this integration does
Your npm clients — npm, yarn, pnpm, and any CI job
that runs them — fetch packages through mShield instead of straight from the registry. Every
tarball download is evaluated against your policies first. Installs that pass behave exactly as
before; installs that fail stop with an HTTP 403 naming the package and the check that
refused it.
Nothing is installed on the developer's machine. The whole integration is a
registry= line in an .npmrc, or — in egress-interception mode
— no client change at all.
For SaaS and on-prem. This guide uses client configuration. DNS mode is an alternative available only on-prem; see deployment models.
Point npm at your mShield endpoint
Your deployment provides the hostname and the credentials to use. Replace
npm.example.mshield.dev below with your own; the commands are otherwise exactly what you
will run.
Project scope — recommended for a pilot
Writes .npmrc in the project directory. Only builds run from inside that project use
mShield; everything else on the machine is untouched, which is what makes a first evaluation easy
to reverse.
cd /path/to/your/project
npm config set registry https://npm.example.mshield.dev/ --location=project
npm config set "//npm.example.mshield.dev/:_authToken" <your-token> --location=project
chmod 600 .npmrc
Or write the file directly:
registry=https://npm.example.mshield.dev/
//npm.example.mshield.dev/:_authToken=<your-token>
User scope
Writes $HOME/.npmrc, so every project for that user account goes through mShield
unless the project ships its own registry= line, which still wins.
npm config set registry https://npm.example.mshield.dev/ --location=user
npm config set "//npm.example.mshield.dev/:_authToken" <your-token> --location=user
chmod 600 "$HOME/.npmrc"
Machine scope
Writes the npm prefix's shared npmrc, covering every account on the machine that has
no .npmrc of its own. Needs administrator rights, and is usually how a build image or a
shared CI runner is configured.
sudo npm config set registry https://npm.example.mshield.dev/ --location=global
sudo npm config set "//npm.example.mshield.dev/:_authToken" <your-token> --location=global
Merging into an existing .npmrc. An .npmrc is one
key=value per line. Append to a file that already exists rather than replacing it, and
remove only an earlier registry= or //<host>/:_authToken= line for
the same host — leave settings such as engine-strict or save-exact
alone. Running the npm config set commands does that merge for you.
On tokens. npm stores the token in a plain-text file. Keep the file private, keep it out of version control, and rotate the token if it leaks.
Verify it took effect
cd /path/to/your/project
npm config get registry
npm ping --registry https://npm.example.mshield.dev/
Inside the project, npm config get registry should print your mShield endpoint. Run
the same command from a directory outside the project and you should still see whatever you
used before — that difference is the proof the change stopped at this project.
npm ping should print Ping success.
For user scope, the endpoint should print from any directory without its own
.npmrc. For machine scope, check npm config get prefix first: if it prints
a path inside your own profile, only your account was configured.
CI runners
A CI job is the same client with a shorter memory. Two options:
- Write the
.npmrcin the job, from a secret holding the token, before the install step. Project scope, discarded with the workspace. - Bake it into the build image at machine scope, so every job on that image is covered without touching pipeline definitions.
A CI runner is often the better half of a pilot to start with: its traffic is reproducible, and a blocked install shows up as a failed build with a readable reason rather than as a developer interrupted mid-task.
What a blocked install looks like
npm reports the refusal and fails the install, the way it fails any rejected download. The response names the package, the version, and the rule that refused it, so the reason appears in the terminal output rather than in a support ticket.
npm error code E403
npm error 403 Forbidden - GET https://npm.example.mshield.dev/lodash/-/lodash-4.17.20.tgz
npm error 403 lodash@4.17.20 was refused by policy "Production dependencies"
npm error 403 | More details: https://mshield.example.com/...
The refusal also carries a link to a page that explains the block in full — what was refused, why, the version that would satisfy the policy, and a way to request an exclusion. It needs no login, and it is scoped to that single refusal. See what the developer opens.
If the block is wrong for a case your team has accepted, the developer requests an exclusion from that page and gets back a link to follow the decision; an operator grants or refuses it, and a granted exclusion is package-scoped, time-boxed, and recorded like any other decision.
Rolling back
Point the client back at the public registry. There is nothing else to uninstall.
npm config delete registry --location=project
npm config delete "//npm.example.mshield.dev/:_authToken" --location=project
Use the same --location you configured. Decisions already recorded stay in the
dashboard.