The Saga of Private Registries
Authentication to a private NPM registry made easy
Have you ever had to use private NPM packages? If you have, you probably know how big of a bother it can be if they’re not hosted on the default NPM registry. Setting up NPM to point to the registry; handling authentication; making sure everyone has the right access… It can take a while, and you have to start over every time someone new needs access or you’re using a new device.
I almost gave up on trying to use a registry outside NPM, until I found out that you can use Google Artifact Registry as an NPM registry, and decided to give it another shot, as I’m an absolute fan of GCP products.
After setting up a registry, I was presented with a step-by-step instruction on how to authenticate and point our scope to this registry. “Not again…”, I thought to myself as I started imagining all the complaints from my co-workers having to go through the same setup just to use our internal packages. “Why don’t we just use git submodules?”; “I don’t have an .npmrc file in my repo!”; “Why isn’t there a Confluence page for this?”.
With the gruesome forecast in mind, I started looking into automating this, as it’s basically just running an NPM config command and copy-pasting a token from a gcloud command. We use Yarn at my workplace, Computas Denmark, so I started looking at the yarn configuration file to get rid of the scope setup. It didn’t take long before I found a way to do this:
npmScopes: <org>: npmAlwaysAuth: true npmPublishRegistry: "https://<location>-npm.pkg.dev/<org>/<repository>/" npmRegistryServer: "https://<location>-npm.pkg.dev/<org>/<repository>/"
That’s one thing out of the way and it requires minimal documentation.
Now to the authentication. I tried looking for a way to use Google’s authentication through configuration, but found nothing. I scoured through the Google documentation for Artifact Registry in hopes of finding that one golden nugget that would push me the last mile and bring it home. Alas, come Christmas time, I still hadn’t found a way to do this.
It was nagging me every day that I still hadn’t figured out how to automate the authentication to the point where I couldn’t enjoy Christmas. While my family was playing in the snow, baking gingerbread cookies and drinking hot chocolate by the fireplace, I was glued to the screen with two things on my mind: gravy, and the authentication problem. In that order.
So anyways, I wrote a plugin: https://github.com/andyclausen/yarn-plugin-gcp-auth. You can use it too by running:
yarn plugin import https://github.com/AndyClausen/yarn-plugin-gcp-auth/releases/latest/download/plugin-gcp-auth.js
It will authenticate using a token from gcloud, or from the Google metadata server if you’re running from GCP.
Finally, with this setup, we only need to make configurations once per repository, and the plugin will take care of the rest. We can control who has access to our internal packages with Google’s IAM policies, be it nagging co-workers or quiet service accounts.