Help: CI/CD Pipeline Failing with npm Staged Publishing 2FA Requirement?
Hey everyone,
With the general availability of npm's new staged publishing, we're trying to adopt it to hard our supply chain against dependency confusion attacks. However, the mandatory 2FA challenge for maintainers to approve the release is blocking our automated CI/CD pipeline.
We've updated our package. and enabled the feature in the org settings, but now our GitHub Actions workflow fails when attempting to publish because it can't complete the 2FA step.
Here is the step we are currently using:
- name: Publish to npm
run: npm publish --provenance
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
Has anyone successfully implemented the approval step in an automated environment? I'm trying to figure out if we need to split our workflow into a 'Stage' job and a separate 'Approve/Publish' job that requires a manual trigger, or if there's a way to configure a CI-specific 2FA method (like an OIDC token) that npm accepts for the approval.
If you've tackled this, I'd love to hear how you balanced the security requirement of 2FA with the need for automation.
The explicit human approval is the primary security control here, designed to prevent compromised CI/CD secrets from instantly publishing malicious packages. You can't fully automate the final approval without defeating the purpose.
The recommended workflow is to separate the stages. Your CI can run the npm publish command, which will push the package to the 'staged' state. Then, you configure a GitHub Environment that requires manual review. Once approved, a second job (or a local maintainer) runs the approval command using their 2FA credential.
We ran into this last week. You definitely need to treat the 'staged' version as a pending state. We set up a Slack notification via a webhook when the publish step completes successfully but waits for approval.
Be careful not to try to pass your personal OTP/2FA seed to the CI runner—that defeats the entire security model. We ended up writing a small script that queries the npm registry to check the version status, so we know when it's pending vs. live.
Verified Access Required
To maintain the integrity of our intelligence feeds, only verified partners and security professionals can post replies.
Request Access