npm recently changed their security protocol as a mitigation to a disastrous supply chain attack. This is good, though due to a combination of factors I was rendered unable to publish npm packages and documentation on the issue is sparse and opaque. To spare others in a similar position the headache this is a documentation of that experience and how I resolved it.
//registry.npmjs.org/:_authToken=YOUR_TOKEN into ~/.npmrcnpm eliminated their "legacy" long-lived tokens in favor of 2FA and granular short-lived tokens. The recommended best practice is to enable 2FA on your account, but the only 2FA they seem to support is WebAuthn. You are presented with a QR code Passkey to scan from your phone which should enable you to use your phone as your second factor. I actually really like WebAuthn in principle, but it is frustratingly brittle in practice. My Pixel 7 just hangs when I scan the QR code on npm and webauthn.io due to the fact that I run Chromium and never log into any Google accounts at the browser level. Testing webauthn.io in Chrome after logging in and turning on data synchronization did work, but its intolerable to expect me to rework my entire digital existence in order log into a service.1
So the 2FA is a non-starter for me, which sucks because it's a good idea. Instead I opted for the granular tokens, which can be set up following these instructions. I gave mine limited scope and a short expiration date. You are presented with a token value, but it wasn't clear where I should put it.
I publish to npm infrequently and maybe this is obvious to people more experienced, but there is a .npmrc file you are supposed to populate with
//registry.npmjs.org/:_authToken=YOUR_TOKEN
replacing YOUR_TOKEN with the value of the token you received in the previous step. The documentation says this file can be in your project root or your home directory. Putting it in my project root did not work because it turned out that I had an old one (containing my now-revoked legacy tokens I believe) in my home directory which seemed to take precedence. Putting this new token in the .npmrc in my home directory did the trick. I will have to replace it whenever I want to publish, which is annoying but survivable.
And that's it! Stay safe out there everybody.
I also do not appreciate being nudged in the direction of capitulation to the walled garden of Google in order for software to function properly. This is a part of the larger trend wherein modern networked software does not "work" for any meaningful definition of the word "work" unless everyone involved is in the same walled garden or, at the very least, each in a walled garden stewarded by corporations who have some B2B relationship with each other. If I wanted feudalism I would have stayed in Lebanon where at least the food and music are better. ↩︎