Andrei Calazans

NPM & Yarn Private Package Registry Personal Mistakes

• • ☕️ 3 min read
  1. The Issue
  2. Things I Learned
    2.1. The Wrong Solution
    2.2. The Right Solution
  3. Conclusion
  4. Notes

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

1) 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 running yarn 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.