Skip to content

npm

The proxy implements the npm registry protocol, so any client that speaks it can install through ShieldedStack.

Endpoint: <proxy-url>/npm/

Authentication: the API key, sent as a bearer token. npm’s _authToken setting does this for you.

Configuration below is written for npm, pnpm, and Yarn. Other package managers that speak the same protocol use the same endpoint and the same key through their own registry and auth-token settings: Bun reads .npmrc, and Deno resolves npm: specifiers through NPM_CONFIG_REGISTRY.

Create or update .npmrc, either in the project root or your home directory:

registry=<proxy-url>/npm/
//<proxy-host-and-port>/npm/:_authToken=YOUR_API_KEY_HERE
//<proxy-host-and-port>/npm/:always-auth=true

The registry line takes the full URL. The two auth lines take the host without a scheme, which is npm’s own convention for matching credentials to a registry, and the port when the deployment uses a non-default one.

always-auth matters more than it looks: without it, npm sends credentials on package downloads but not on metadata requests, and the proxy cannot attribute those to a project.

pnpm reads the same .npmrc. No separate configuration is needed.

Yarn uses .yarnrc.yml:

npmRegistryServer: "<proxy-url>/npm/"
npmAlwaysAuth: true
npmAuthToken: "${SHIELDEDSTACK_API_KEY}"

Yarn requires HTTPS registries. Against an HTTP-only deployment it refuses to connect unless the host is listed explicitly:

unsafeHttpWhitelist:
- "<proxy-host>"

That exception disables a real protection. It is for local testing, not for a shared or production deployment.

Scoped registry overrides. A line such as @scope:registry=https://registry.npmjs.org/ takes precedence over the default registry, and packages in that scope go straight to the public registry. Remove or repoint scoped overrides in both .npmrc and .yarnrc.yml.

Config layering. npm merges project .npmrc, user ~/.npmrc, and global config. When the same registry key appears in more than one with different values, requests can authenticate with different tokens depending on where they run. Keep one source of truth for the ShieldedStack registry token.

For commands that spawn child npm processes or change directory, pin the config file explicitly:

Terminal window
npm_config_userconfig="$PWD/.npmrc" npx create-react-app my-app

.npmrc is safe to commit as long as the token comes from the environment:

registry=<proxy-url>/npm/
//<proxy-host-and-port>/npm/:_authToken=${SHIELDEDSTACK_API_KEY}
//<proxy-host-and-port>/npm/:always-auth=true

npm expands ${SHIELDEDSTACK_API_KEY} at read time, so the same committed file works on a workstation and on a build agent:

Terminal window
export SHIELDEDSTACK_API_KEY=your-api-key-here
Terminal window
npm install
# or: pnpm install
# or: yarn install

The installed package appears under Packages in the Control Plane, attributed to the project name on the API key.

401 or 403. Confirm always-auth=true is present, so npm authenticates metadata requests as well as downloads. Confirm the registry URL matches exactly, trailing slash included.

Installs succeed but nothing is tracked. The request went somewhere else. Check for a scoped registry override, then check whether the config file you edited is the one npm actually read.

Credential drift across config layers. Compare what each layer holds:

Terminal window
npm config get //<proxy-host-and-port>/npm/:_authToken --location=project
npm config get //<proxy-host-and-port>/npm/:_authToken --location=user

If both have values, make them identical or remove one.

Stale cache. npm cache clean --force.