npm
Configure npm, yarn, pnpm, and Bun to install through your firewall. Registry setup, authentication, CI, publishing, and troubleshooting.
An npm firewall implements the npm registry protocol. Anything that speaks it can install through the firewall: npm, yarn, pnpm, and Bun.
The examples use <namespace-id> and <firewall-id> placeholders. Replace them with IDs, not with namespace or firewall names. The firewall's Setup tab shows a ready-to-copy npm snippet with both values already filled in. This page also covers yarn, pnpm, and Bun, whose configuration is not generated in the dashboard.
Registry endpoint
https://eu-sov-1.bytesafecloud.eu/v1/<namespace-id>/npm/<firewall-id>/The namespace ID and firewall ID are part of the URL, so one machine can use different firewalls per project.
Configure the project
Commit a .npmrc at the project root:
registry=https://eu-sov-1.bytesafecloud.eu/v1/<namespace-id>/npm/<firewall-id>/
//eu-sov-1.bytesafecloud.eu/v1/<namespace-id>/npm/<firewall-id>/:_authToken=${BYTESAFE_TOKEN}Yarn 1 reads the same .npmrc as npm. Yarn Berry (2+) uses its own config:
npmRegistryServer: "https://eu-sov-1.bytesafecloud.eu/v1/<namespace-id>/npm/<firewall-id>/"
npmAuthToken: "${BYTESAFE_TOKEN}"pnpm reads the same .npmrc as npm:
registry=https://eu-sov-1.bytesafecloud.eu/v1/<namespace-id>/npm/<firewall-id>/
//eu-sov-1.bytesafecloud.eu/v1/<namespace-id>/npm/<firewall-id>/:_authToken=${BYTESAFE_TOKEN}Bun reads .npmrc, or its own config:
[install]
registry = { url = "https://eu-sov-1.bytesafecloud.eu/v1/<namespace-id>/npm/<firewall-id>/", token = "$BYTESAFE_TOKEN" }Each developer exports a personal access token:
export BYTESAFE_TOKEN=<your token>Committing the registry config, with the token read from an environment variable, gives every clone of the repository the firewall by default and keeps credentials out of git.
Verify
npm install lodashyarn add lodashpnpm add lodashbun add lodashA successful install confirms the firewall is serving the package, and every request through that registry is evaluated against your rules.
Do not expect a log entry from this. A request is logged only when it matches a
rule with log: true or a logging exception, so an install that breaks no rule
leaves no trace. An empty log is not evidence that the client bypassed the
firewall. To see the requests while verifying setup, add a log-only rule that
matches all packages. See What is logged when.
CI
Use a Service Access Token (SAT) instead of a PAT. Set it as a secret in your CI system and export it as BYTESAFE_TOKEN before install steps. The committed registry config does the rest.
To correlate all requests from one pipeline run, append an interaction ID to the token:
export BYTESAFE_TOKEN="${BYTESAFE_TOKEN}::${CI_PIPELINE_ID}"The ID shows up on every log entry from that run.
npm audit
npm audit works through the firewall. The audit endpoints are proxied, so vulnerability reports keep working without a direct connection to npmjs.org.
Publishing
A firewall can also receive npm publish. First set a publish target: the upstream that should receive published packages. Then publish as usual with the firewall as the registry. Upload rules run against the publish before it is forwarded.
Without a publish target the firewall is install-only and rejects publishes. That is a deliberate setting, not a limitation: leave it unset on firewalls that should only pull packages in.
What a blocked install looks like
Rules on the versions phase filter versions out of the metadata npm sees. Dist-tags pointing at a filtered version are removed. The effect depends on how the dependency is declared:
- A range like
^4.0.0resolves to the newest version that passed the rules. The install succeeds, possibly with an older version than the public latest. - An exact pin to a filtered version fails with npm's
No matching version founderror (ETARGET). - A named tag spec like
some-package@canaryfails the same way when the tag points at a filtered version, because the tag is removed from the metadata. The default tag is the exception:npm install some-package(implicitly@latest) falls back and resolves to the newest version that passed the rules, like a range.
Rules on the download phase block the tarball fetch instead. The blocked version is often a transitive dependency that a range resolved to, not the package on the command line. npm fails with a 404 from the firewall and a message like:
lodash@4.17.20 is blocked. Check firewall log entries for request <request-id> for detailsTake the request ID to the logs to see which rule fired. See Investigate a blocked install.
Troubleshooting
BYTESAFE_TOKEN is unset, expired, or revoked. Confirm the variable is set in the shell that runs the install, and that the token is still listed and unexpired in the dashboard.
Most likely a versions rule filtered it. Check the firewall logs before assuming an upstream problem.
No log entry does not by itself mean the client bypassed the firewall. Approved
packages that match no logging rule pass through without an entry. First test
with a log-only rule matching the package or all packages. If that rule still
does not produce an entry, check for overriding config in ~/.npmrc or a
NPM_CONFIG_REGISTRY environment variable, and confirm lockfile resolved
URLs point at the firewall, not registry.npmjs.org.
If you route only certain scopes through the firewall (@acme:registry=...), everything outside the scope still goes to the public registry unchecked. Route the whole registry through the firewall unless you have a reason not to.