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 the global config.yaml, under _auth.
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:
<workspace root>/.npmrc, the project file. Add it to.gitignore.<pnpm config>/auth.ini.pnpm config setwrites auth keys here.~/.npmrc, so credentials you set up for npm keep working. To read a different file, use thenpmrcAuthFilesetting.
The global <pnpm config>/config.yaml holds the _auth setting.
pnpm login saves tokens there.
The <pnpm config> directory is:
$XDG_CONFIG_HOME/pnpm/, ifXDG_CONFIG_HOMEis 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 a
scoped token under _auth in the global config.yaml.
<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__authenvironment 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
httporhttpsregistry 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@orgscope. authTokenis the only credential field. It is a bearer token.authTokencan 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. The priority of this
routing depends on where the entry comes from:
--registryand--@scope:registryon the command line win.- Entries from
pnpm_config__authoverride theregistryandregistriessettings. CI can use this to force a proxy registry. - Entries from the global
config.yamlapply only where noregistryorregistriessetting chooses a registry. The token is still sent to its own URL.
pnpm login writes here:
- An unscoped login adds an
"@"entry. It does not change theregistrysetting. - A scoped login adds an
"@org"entry and adds the scope to that URL in the globalregistriessetting. Logging the same scope in to another registry moves both. pnpm logoutremoves the tokens pnpm wrote toconfig.yamlandauth.ini. It keeps the registry settings.
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}
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