Repository navigation
Consider adopting npm trusted publishing #164
Description
Activity
Same response here as on eslint :-)
Same reply as on eslint 😉
parseargs/.github/workflows/release.yml
Lines 26 to 28 in bb2c69c
- run: npm publish --access=public env: NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}} Yup, we should definitely use a more secure approach. Unfortunately, "trusted publishing" isn't it :-/ npm's plan has a lot of issues, and the overwhelming feedback from OpenJS was unfortunately largely ignored.
It's a little difficult to keep track of all the discussions, but setting TOTP 2FA deprecation and limiting token lifetime aside, it seemed like there was generally support of trusted publishing. The main concern I could see was lack of support for an additional 2FA prompt when triggering workflows on GitHub Actions in free plans outside of something like
step-security/wait-for-secrets.It looks like this is going to be a big topic at JSConf NA in a few weeks. So I'll wait and see what the outcomes of that are.
Well, currently this project doesn't have any publishing at all, really. It's an undocumented process using a deprecated GitHub action and it was last triggered in 2022 despite several useful things landing since then.
I agree that using trusted publishing would be better than this. @ljharb I don't know what eslint thread you're referring to so I can't comment on whatever arguments were raised there, but trusted publishing would be a strict improvement in security over the current flow, so I don't see a reason not to adopt it? Other improvements can be made later if you have something in mind.
Local publishing with 2fa remains the best choice, and will continue to work moving forward with npm’s current plans, so I’d rather just delete that workflow entirely.
@bakkot apologies, here's the other thread we were talking about: eslint/eslintrc#196
@ljharb Local publishing can't generate provenance statements, which means users have no cryptographic proof that the published package actually matches the GitHub source code. The recent supply chain attacks involved tampered releases that didn't match their repos, and provenance provides a verification layer that local publishing (even with 2FA) can't offer.
@JamieMagee "cryptographic proof that the published package actually matches the GitHub source code" is significantly overstating what provenance statements actually give you. Almost all npm packages (including this one) have at least one dependency which is installed during the build process prior to publishing, and a compromise of any of those (or a new malicious dependency added by an attacker, or a new malicious action, or any number of other things) could transform the package that gets published to contain something not present in the GitHub source code while still having a valid provenance statement. I think it does a disservice to the community to overstate what provenance statements actually provide. They have nonzero value in that they require the attacker to do (marginally) more work in order to hide malicious activity, and if trusted publishing could be enforced then getting such a package published would require a compromise of a maintainer's GitHub account rather than their npm account, but they are very far from providing actual proof that the published package matches the GitHub source.
@ljharb Despite the above, I don't think relying on local publishing with 2fa is a good option - for collaborative projects there should be a documented, automated publish process which is triggered by something on GitHub, ideally creation of a release, rather than it being something individual developers do manually at their own discretion. Our current publish job does that (well, except for the "documented" part), but requires having a stored secret for use in CI. Getting rid of that secret is a strict improvement.
@bakkot that's a fair point. It's more accurate to say that it proves a package was built from a specific commit in a specific workflow. Yes, it's not a silver bullet, but I agree it raises the effort required by attackers and makes those attacks much more visible.
@bakkot i totally agree that would be ideal, but unfortunately until there's a native way in github actions to "pause" so a maintainer can input a token or visit an auth URL, there won't be any practical way to use true 2FA with npm from nonlocal publishes. ("staged publishes" in npm would also solve this, but npm elected not to implement that a number of years ago)
Yeah I just don't actually think 2fa during publish is that important. The marginal extra security vs having publishing gated by GitHub actions is not worth the maintenance burden.
That's certainly a security take :-)
Recent supply chain attacks on npm have highlighted the need for stronger package publishing security. The September 2025 Shai-Hulud worm compromised 500+ packages through stolen maintainer tokens, showing the risks of token-based publishing.
Trusted publishing helps by eliminating long-lived tokens that can be stolen or accidentally exposed; generating automatic provenance provides cryptographic proof of where/how packages are built; and is an industry standard adopted by PyPI, RubyGems, crates.io, NuGet, etc.
Here's the short version:
id-token: writepermission to your workflowNODE_AUTH_TOKENfrom your workflownpm is planning to deprecate legacy tokens and make trusted publishing the preferred method.
Would you consider adopting trusted publishing to help secure the npm ecosystem?
References: