npm integration

Point npm at your mShield endpoint and every tarball download becomes a policy decision. Setup is one line of client configuration — or none, in egress-interception mode.

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.

Terminal
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:

.npmrc
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.

Terminal
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.

Terminal
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

Terminal
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 .npmrc in 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.

Example
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.

Terminal
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.

Discuss a pilot

See whether package policy fits your build.

Tell us your team, ecosystem, and current dependency-policy challenge. Pilot scope and commercial terms are agreed before provisioning.

Email about a pilot