Files
pnpm/pnpm11/docs/npmrc.md
Zoltan KochanandClaude Opus 5.5 6beecb0bf0 docs: rewrite the authentication settings page in plain language (#17043)
* docs: rewrite the authentication settings page in plain language

A reader reported that pnpm.io/npmrc was hard to follow. The page opened
with a long security-migration section before it described any setting,
packed several rules into each sentence, and mixed pnpm 11 and pnpm 12
history into the v12 page.

- Add a quick start for `pnpm login` and CI.
- Move the environment-variable restriction and the migration options
  after the settings, as a list of alternatives.
- Split the `_auth` rules and its routing priority into lists.
- Drop version history from the prose; "Added in" markers remain.
- Fix the `<URL>:keyfile` code span, which rendered an HTML entity
  literally.
- Group each certificate setting with its per-registry variant.

Each page keeps its own version's behavior: where `pnpm login` saves
tokens, the `_auth` routing priority, and `${NAME?}` support on v11.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs: drop _auth validation details from the auth settings page

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs: drop version history from the auth settings page

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs: group auth settings by the file they go in

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs: limit the _auth repository note to _auth

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 16:28:13 +02:00

10 KiB

id, title
id title
npmrc Authentication Settings

This page covers registry credentials and client certificates. These settings hold secrets. Keep them out of your repository.

For other settings, such as proxies and registries, see Settings (pnpm-workspace.yaml).

Quick start

On your machine, log in to the registry:

pnpm login

pnpm saves the token in <pnpm config>/auth.ini. See Auth file locations.

In CI, pass the token through an environment variable:

export pnpm_config__auth='{"https://registry.npmjs.org":{"@":{"authToken":"${NPM_TOKEN}"}}}'

Auth file locations

pnpm reads auth settings from two kinds of files.

INI files in npm's .npmrc format hold the .npmrc and auth.ini settings and the certificate settings. If a key is set in more than one file, the first file in this list wins:

  1. <workspace root>/.npmrc, the project file. Add it to .gitignore.
  2. <pnpm config>/auth.ini. pnpm login and pnpm config set write auth keys here.
  3. ~/.npmrc, so credentials you set up for npm keep working. To read a different file, use the npmrcAuthFile setting.

The global <pnpm config>/config.yaml can hold the _auth setting.

The <pnpm config> directory is:

  • $XDG_CONFIG_HOME/pnpm/, if XDG_CONFIG_HOME is set
  • ~/AppData/Local/pnpm/config/ on Windows
  • ~/Library/Preferences/pnpm/ on macOS
  • ~/.config/pnpm/ on Linux

Settings in .npmrc and auth.ini

Set these in one of the INI files listed in Auth file locations.

<URL>:_authToken

The bearer token for a registry:

//registry.npmjs.org/:_authToken=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

In a user-level auth file, the value can reference an environment variable:

//registry.npmjs.org/:_authToken=${NPM_TOKEN}

See Environment variables in auth settings.

Scope-specific auth tokens

Some registries, such as GitHub Packages, issue a separate token for each scope. Put the scope after the registry URL in the key:

@org-a:registry=https://npm.pkg.github.com/
@org-b:registry=https://npm.pkg.github.com/

//npm.pkg.github.com/:@org-a:_authToken=ORG_A_TOKEN
//npm.pkg.github.com/:@org-b:_authToken=ORG_B_TOKEN

//npm.pkg.github.com/:_authToken=FALLBACK_TOKEN

pnpm sends ORG_A_TOKEN for @org-a/* packages and ORG_B_TOKEN for @org-b/* packages. Other packages from that registry get FALLBACK_TOKEN, if it is set.

pnpm login --registry=https://npm.pkg.github.com --scope=@org-a saves the token under the same scoped key.

<URL>:tokenHelper

The path to a program that prints a token. Use it for tokens that expire, so a script can fetch a fresh one.

pnpm runs the program and sends its output as Authorization: Bearer <output>. If the output already starts with a word and a space, such as Bearer abc, Basic abc, or Token abc, pnpm sends it unchanged.

The path must be absolute and take no arguments. pnpm reads tokenHelper only from user-level auth files. A project .npmrc could otherwise make pnpm run any program. Environment variables cannot set it either.

For the default registry:

tokenHelper=/home/ivan/token-generator

For a specific registry:

//registry.corp.com:tokenHelper=/home/ivan/token-generator

Settings in config.yaml

_auth

All registry tokens in one value, keyed by registry URL. Use it in CI, where the //host/:_authToken key cannot be an environment variable name on some runners.

pnpm reads _auth from two places only:

  • the global config.yaml
  • the pnpm_config__auth environment variable, as JSON

pnpm ignores _auth in pnpm-workspace.yaml and .npmrc.

In the global config.yaml:

_auth:
  https://registry.npmjs.org:
    "@":
      authToken: npm-token
    "@org":
      authToken: org-token

The same value as an environment variable:

export pnpm_config__auth='{"https://registry.npmjs.org":{"@":{"authToken":"npm-token"},"@org":{"authToken":"org-token"}}}'

pnpm also reads PNPM_CONFIG__AUTH, the all-caps name some CI runners use. If both are set, the lowercase one wins unless it is empty.

The value follows these rules:

  • Each top-level key is an http or https registry URL, with no credentials, query string, or fragment.
  • Under a URL, "@" holds the token for the whole registry. "@org" holds the token for packages in the @org scope.
  • authToken is the only credential field. It is a bearer token.
  • authToken can reference an environment variable as ${NAME}.

Each entry also routes packages to its URL. "@" makes the URL the default registry, and "@org" sends @org/* packages there. This routing has the following priority, highest first:

  1. --registry and --@scope:registry on the command line
  2. pnpm_config__auth or PNPM_CONFIG__AUTH
  3. _auth in the global config.yaml
  4. pnpm-workspace.yaml

Environment variables in auth settings

User-level auth files, <pnpm config>/auth.ini and ~/.npmrc, can reference environment variables as ${NAME}:

//registry.npmjs.org/:_authToken=${NPM_TOKEN}

npm's ${NAME?} form works too. It expands to an empty string when NAME is unset, without a warning. If an empty variable removes an auth token, pnpm prints a warning that names the key.

pnpm does not expand environment variables in the project .npmrc for:

  • registry and proxy URLs: registry, @scope:registry, proxy, https-proxy, http-proxy
  • keys that start with //
  • credentials: _authToken, _auth, _password, username, tokenHelper, cert, key

pnpm ignores such a setting and prints a warning. The project .npmrc comes with the repository, so a malicious repository could otherwise send your CI tokens to a registry it controls (GHSA-3qhv-2rgh-x77r).

Moving a token out of the project .npmrc

If your repository commits a line such as //registry.npmjs.org/:_authToken=${NPM_TOKEN}, use one of these instead.

Pass the token in an environment variable named after the key:

env "pnpm_config_//registry.npmjs.org/:_authToken=$NPM_TOKEN" pnpm install

Shells cannot export this name, because it contains /, :, and .. Use env as above, or set the variable in your CI provider's settings. It overrides the project .npmrc, and a command-line option overrides it.

Or use _auth, as in the quick start.

Or save the token in <pnpm config>/auth.ini in a CI step:

pnpm config set //registry.npmjs.org/:_authToken "$NPM_TOKEN"

Or move the ${NPM_TOKEN} line to ~/.npmrc, or to the file that npmrcAuthFile names.

In GitHub Actions, actions/setup-node with the registry-url input already works. It writes a user-level .npmrc and points NPM_CONFIG_USERCONFIG at it. pnpm reads that file, so NODE_AUTH_TOKEN keeps working.

If you cannot change every CI pipeline, mark the project .npmrc as trusted with one variable in the CI environment:

PNPM_CONFIG_NPMRC_AUTH_FILE=.npmrc

This sets npmrcAuthFile. pnpm then reads the project .npmrc as the user-level auth file and expands its variables. A relative path is resolved against the working directory. A repository cannot set this variable, because it comes from the environment. pnpm also reads npm's NPM_CONFIG_USERCONFIG if this variable is unset.

:::danger

Use this only where every repository you build is trusted. It turns off this protection for the checked-out repository, including the rule that only user-level files can set tokenHelper.

:::

The same applies to a registry URL built from an environment variable. Move it to ~/.npmrc or set it with pnpm config set "<key>" <value>. A URL that is not secret can be written out in the project .npmrc. For registries in pnpm-workspace.yaml, see registries.

Certificate settings

Like the token settings, these go in .npmrc or auth.ini.

ca

  • Default: The npm CA certificate
  • Type: String, Array or null

The certificate authority (CA) certificate to trust for TLS connections to the registry, in PEM format:

ca="-----BEGIN CERTIFICATE-----\nXXXX\nXXXX\n-----END CERTIFICATE-----"

To trust several CAs, use an array:

ca[]="..."
ca[]="..."

Set it to null to trust only the well-known CAs.

See also strictSsl.

cafile

  • Default: null
  • Type: path

The path to a file with one or more CA certificates. Use it instead of ca to keep the certificates in a file.

<URL>:ca

A CA certificate in PEM format, trusted only for the given registry:

//registry.example.com/:ca=-----BEGIN CERTIFICATE-----...-----END CERTIFICATE-----

<URL>:cafile

The path to a CA certificate file for the given registry:

//registry.npmjs.org/:cafile=ca-cert.pem

cert

  • Default: null
  • Type: String

The client certificate to send to the registry, in PEM format. The value is the certificate itself, not a path:

cert="-----BEGIN CERTIFICATE-----\nXXXX\nXXXX\n-----END CERTIFICATE-----"

<URL>:cert

The client certificate to send to the given registry:

//registry.example.com/:cert=-----BEGIN CERTIFICATE-----...-----END CERTIFICATE-----

<URL>:certfile

The path to a client certificate file for the given registry:

//registry.npmjs.org/:certfile=server-cert.pem

key

  • Default: null
  • Type: String

The client key to send to the registry, in PEM format. The value is the key itself, not a path. To read the key from a file, use <URL>:keyfile.

key="-----BEGIN PRIVATE KEY-----\nXXXX\nXXXX\n-----END PRIVATE KEY-----"

<URL>:key

The client key for the given registry:

//registry.example.com/:key=-----BEGIN PRIVATE KEY-----...-----END PRIVATE KEY-----

<URL>:keyfile

The path to a client key file for the given registry:

//registry.npmjs.org/:keyfile=server-key.pem