Before exposing a Verdaccio npm registry beyond localhost, review the listen address, the API token signature, CORS, proxy trust, password rules and publish settings. Several defaults suit a quick local start rather than a shared service. This list comes from the Verdaccio configuration documentation.
Network and exposure
listendefaults tolocalhost:4873. That is safe for a laptop. To serve a team you must change it, and from that moment the registry is a network service that needs TLS and access rules in front of it.server.cors: when omitted, responses sendAccess-Control-Allow-Origin: *. If your web interface should not be called from arbitrary pages, set it deliberately.server.trustProxyhas no stated default. The docs recommend setting it when a proxy sits in front, so that client addresses in logs and rate limits are correct.server.dotfilesdefaults toignore, which returns404for dotfile paths. Leave it.
Tokens and sessions
security.api.legacyis enabled by default, even if the section is not defined. If thesecurity.api.jwtblock is absent, the olderaes-256-ctrsignature is used for the API. Defining the JWT block is the modern route.security.web.expiresIndefaults to one hour.security.api.basicLoginis enabled by default and accepts Basic auth only on the login routes. Other routes answer401to Basic headers.- The storage secret must be exactly 32 characters. On 7.x a wrong length prevents startup. On 6.x, a setting called
migrateToSecureLegacySignaturedefaults to true and silently replaces the secret, which invalidates existing tokens. Know which major version you run before upgrading.
Users and passwords
auth.htpasswd.max_users: the docs example uses1000. The page does not state a default, so check how your version handles new user sign up and decide on purpose whether strangers can register.server.passwordValidationRegex: the docs say it defaults to three characters, though their example enforces ten. Check the effective value, and set a stronger rule.
Publishing
publish.allow_offlineisfalse, which is the safer setting.publish.check_ownersisfalse, so only package access rules restrict publishing. Rely on explicit rules.max_body_sizedefaults to10mb, which can block large packages. Raise it only if you need to.
Logging and limits
logdefaults to stdout, pretty format, levelhttp. Ship it to central storage in JSON if your tooling prefers.userRateLimit: the prose says 100 requests per 15 minutes, but the example differs. Test your effective limit instead of trusting either.middlewares.audit.enabledis true in the default config.
A quick review pass
| Area | Question |
|---|---|
| Exposure | Is it behind TLS and a proxy, with trustProxy set? |
| Tokens | Is the JWT block defined, and is the secret 32 characters? |
| Users | Can anyone register? Is the password rule strong? |
| Publishing | Do access rules cover every internal package name? |
| Logs | Are logs shipped and kept? |
Try it yourself
Click through it at your own pace, or open it full screen.
Watch how monitoring turns a one time review into a habit. Settings drift, so recheck them on a schedule.
Safeguard can monitor your dependencies continuously and generate SBOMs, with a free scan at gold.safeguard.sh/scan.
Quick check
Is the default listen address safe?
On a single machine, yes, since it is localhost. Once you open it to a network, add TLS and access rules.
Why should I define the JWT security block?
Without it, the legacy aes-256-ctr signature is used for the API. The docs show a JWT block as the alternative.
Sources
Last reviewed: 19 October 2026.