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.
The proxy accepts the key as a bearer token or as HTTP basic auth on this endpoint, which is what lets clients with no token setting embed it in the registry URL instead.
Every client below speaks the same protocol against the same endpoint, but they do not share configuration. npm, pnpm, and Bun read .npmrc; Yarn 2 and later reads .yarnrc.yml and nothing else; Deno reads neither by default. Each is written out below.
npm and pnpm
Section titled “npm and pnpm”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=trueThe 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 2 and later
Section titled “Yarn 2 and later”Yarn uses .yarnrc.yml:
npmRegistryServer: "<proxy-url>/npm/"npmAlwaysAuth: truenpmAuthToken: "${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.
Bun reads .npmrc, both the project file and ~/.npmrc, so the npm configuration above already covers it and no separate file is needed.
What it does not read is .yarnrc.yml. A repository configured only for Yarn 2 leaves Bun resolving from the public registry, with nothing in the working tree to suggest it. If a project supports both, it needs both files.
bunfig.toml overrides .npmrc where the two disagree, so a stale registry there wins silently:
[install]registry = { url = "<proxy-url>/npm/", token = "YOUR_API_KEY_HERE" }Prefer .npmrc and keep bunfig.toml free of a registry line, so there is one place to change. Where bunfig.toml is unavoidable, note that the token sits in the file as plain text and the file must not be committed with a real key in it.
Deno resolves npm: specifiers through npm’s protocol, but it does not pick up a project .npmrc for the default registry the way the others do. Point it at the proxy through the environment:
export NPM_CONFIG_REGISTRY=https://_:YOUR_API_KEY_HERE@<proxy-host>/npm/The credential goes in the URL because the proxy accepts basic auth on this endpoint. Set the variable anywhere deno run, deno cache, or deno install runs, including CI, and treat it as a secret in logs.
Deno caches resolved modules in DENO_DIR, so a run that already resolved against the public registry keeps using what it cached. Force a re-resolve after switching:
deno cache --reload main.tsA committed deno.lock records integrity hashes rather than the registry it fetched from, so it does not need regenerating for the switch.
Two ways installs escape the proxy
Section titled “Two ways installs escape the proxy”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:
npm_config_userconfig="$PWD/.npmrc" npx create-react-app my-appCommitting the configuration
Section titled “Committing the configuration”.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=truenpm expands ${SHIELDEDSTACK_API_KEY} at read time, so the same committed file works on a workstation and on a build agent:
export SHIELDEDSTACK_API_KEY=your-api-key-hereVerify
Section titled “Verify”npm installpnpm installyarn installbun installdeno cache main.tsThe installed package appears under Packages in the Portal, attributed to the project name on the API key.
Names in package filters
Section titled “Names in package filters”npm package names are case-sensitive: JSONStream and jsonstream are two separately published packages. An allow rule or vulnerability exception therefore applies only to the exact spelling, scope included, so an allow for @types/* does not cover @Types/node. Deny rules match any casing, so a deny for JSONStream also blocks jsonstream. Separators are part of the name in every case: lodash.merge and lodash-merge are different packages. See Package names for how every ecosystem compares names.
Troubleshooting
Section titled “Troubleshooting”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:
npm config get //<proxy-host-and-port>/npm/:_authToken --location=projectnpm config get //<proxy-host-and-port>/npm/:_authToken --location=userIf both have values, make them identical or remove one.
Bun resolves from the public registry. Bun ignores .yarnrc.yml, so a Yarn-only project has nothing configured for it. Check for a bunfig.toml registry line overriding .npmrc.
Deno resolves from the public registry. NPM_CONFIG_REGISTRY is not set in the process that ran Deno, or DENO_DIR still holds modules cached before the switch. Re-run with deno cache --reload.
Stale cache. npm cache clean --force for npm, pnpm store prune for pnpm, yarn cache clean for Yarn, bun pm cache rm for Bun, and deno cache --reload for Deno.