The Issue 😅
While working on a client project, I ran into an issue with their private registry. I kept seeing the unauthorized error when I ran yarn install
. It was a weird issue especially because I had all of the correct keys. After some investigation I found out I was using the wrong _auth
value.
Things I Learned
- When you run
yarn install
it searches for.npmrc
and.yarnrc
from your directory all the way up to your~
. You can see this happen by runningyarn install --verbose
.
Logs from yarn install --verbose
yarn install v1.19.1
verbose 0.18514658 Checking for configuration file "/Users/andrei/youi/sky-native-app/.npmrc".
verbose 0.185477195 Found configuration file "/Users/andrei/youi/sky-native-app/.npmrc".
verbose 0.185915158 Checking for configuration file "/Users/andrei/.npmrc".
verbose 0.186127856 Found configuration file "/Users/andrei/.npmrc".
verbose 0.186508633 Checking for configuration file "/usr/local/etc/npmrc".
verbose 0.186738535 Checking for configuration file "/Users/andrei/youi/sky-native-app/.npmrc".
verbose 0.186919433 Found configuration file "/Users/andrei/youi/sky-native-app/.npmrc".
verbose 0.187329545 Checking for configuration file "/Users/andrei/youi/.npmrc".
verbose 0.18754202 Checking for configuration file "/Users/andrei/.npmrc".
verbose 0.18771867 Found configuration file "/Users/andrei/.npmrc".
verbose 0.188084114 Checking for configuration file "/Users/.npmrc".
verbose 0.190795222 Checking for configuration file "/Users/andrei/youi/sky-native-app/.yarnrc".
verbose 0.190968545 Checking for configuration file "/Users/andrei/.yarnrc".
verbose 0.191117478 Found configuration file "/Users/andrei/.yarnrc".
verbose 0.191446104 Checking for configuration file "/usr/local/etc/yarnrc".
verbose 0.191626166 Checking for configuration file "/Users/andrei/youi/sky-native-app/.yarnrc".
verbose 0.191789006 Checking for configuration file "/Users/andrei/youi/.yarnrc".
verbose 0.191952116 Checking for configuration file "/Users/andrei/.yarnrc".
verbose 0.192109197 Found configuration file "/Users/andrei/.yarnrc".
verbose 0.192409632 Checking for configuration file "/Users/.yarnrc".
By doing this yarn composes all of the configuration values from .npmrc
and .yarnrc
into a single global dictionary which you can verify by running yarn config list
.
info yarn config
{
'version-tag-prefix': 'v',
'version-git-tag': true,
'version-commit-hooks': true,
'version-git-sign': false,
'version-git-message': 'v%s',
'init-version': '1.0.0',
'init-license': 'MIT',
'save-prefix': '^',
'bin-links': true,
'ignore-scripts': false,
'ignore-optional': false,
registry: 'https://registry.yarnpkg.com',
'strict-ssl': true,
'user-agent': 'yarn/1.19.1 npm/? node/v13.6.0 darwin x64',
lastUpdateCheck: 1597857181992
}
info npm config
{
'@your_company:registry': 'https://your_company.jfrog.io/your_company/api/npm/jspkg/',
'//your_company.jfrog.io/your_company/api/npm/jspkg/:_auth' : 'some_secret_token',
'//your_company.jfrog.io/your_company/api/npm/jspkg/:always-auth' : true,
python: '/usr/bin/python'
}
The interesting part about this is the overriding behavior of the deeper configs. If you are currently in ~/projects/cool_app/
, the .npmrc
file in this directory will take priority over the one in ~
.
2) Variables Can Be Global And Scoped
Private registries require a _password
or _auth
token to authentiticate. When you set the value to these tokens you can set it globally as follows:
_auth=${REPLACE_WITH_YOUR_AUTH_TOKEN}
always-auth=true
By doing the above, these values are globally set and every private registry you use will use that _auth
token.
And this is when I thought I had a solution since I technically had fixed the issue I was seeing after I set the _auth
token per scope as follows:
@your_company:registry=https://your_company.jfrog.io/your_company/api/npm/jspkg/
//your_company.jfrog.io/your_company/api/npm/jspkg/:_auth =${REPLACE_WITH_YOUR_AUTH_TOKEN}
//your_company.jfrog.io/your_company/api/npm/jspkg/:always-auth=true
what I didn’t realize, I was making another mistake previously, which was using the wrong values for the _auth
token.
How to provide credentials to NPM private packages
While working on this, Jarek pointed out to me that NPM private packages have two ways of receiving credentials, either with _auth
or with _password
and _username
tokens.
The _auth
value is composed of the your username
and API Key
encoded as base64 in the following format: username:API_Key
.
I made the mistake of copyng the _password
value and setting it as the _auth
value on one of my private registries. And thus I kept getting unauthorized.
Conclusion
Make sure you are scoping these config variables to your registry. You can that by setting as //${your_company_registry}/:${variable} = ${value}
. And always double check you have the correct credentials format if you use either _auth
or _password
plus _username
.
Notes
The money sign plus curly braces($) is meant to serve as a placeholder for your values.