Skip to content

ci: authenticate the npm publish with NPM_TOKEN again - #307

Merged
ralyodio merged 1 commit into
mainfrom
ci/npm-token-auth
Aug 5, 2026
Merged

ci: authenticate the npm publish with NPM_TOKEN again#307
ralyodio merged 1 commit into
mainfrom
ci/npm-token-auth

Conversation

@ralyodio

@ralyodio ralyodio commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Summary

Reverts the publish workflow to a stored npm automation token (NPM_TOKEN).

Trusted publishing needs a trusted publisher registered against this workflow's filename on npmjs.com, and that can only be done through the web UI. Until it exists npm rejects the publish as E404 / no permission — which is exactly how v0.24.1 failed after the release itself cut cleanly.

What changed

  • NPM_TOKEN guard restored, so a missing secret says which secret is missing instead of leaving an E404 to be read as "the package does not exist"
  • --provenance restored, and id-token: write stays with it — the attestation is signed with a short-lived OIDC token even though the publish authenticates with the stored one
  • the npm-upgrade step is gone; it existed only because Node 22 bundles an npm too old for trusted publishing, which is no longer the mechanism

Everything else from #304 is untouched: tests first, tag/version match, skip-if-already-published, post-publish registry confirmation.

Worth knowing

npm is restricting tokens that bypass 2FA for direct publishing, so this path has a horizon — noted in the workflow header for whoever revisits it. Trusted publishing remains the eventual destination; it just needs that one web-UI step.

Verification

  • YAML parses; 11 steps; permissions contents: read + id-token: write
  • token wired in both places it belongs: the guard and NODE_AUTH_TOKEN
  • v0.24.1 is still unpublished and its version number is not burned, so the next run publishes it

🤖 Generated with Claude Code

Trusted publishing needs a trusted publisher registered against this
workflow's filename on npmjs.com, and that can only be done through the web
UI. Until it exists npm rejects the publish as E404/no-permission, which is
how v0.24.1 failed after the release itself cut cleanly.

So: back to a stored automation token in the repository secret NPM_TOKEN,
with the explicit check that says which secret is missing rather than leaving
an E404 to be read as "the package does not exist".

`--provenance` is back too, and `id-token: write` stays with it — the
attestation is signed with a short-lived OIDC token even though the publish
authenticates with the stored one.

The npm upgrade step goes: it existed only because Node 22 bundles an npm too
old for trusted publishing, which is no longer the mechanism.

Noted in the header for whoever revisits this: npm is restricting tokens that
bypass 2FA for direct publishing, so this path has a horizon.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown

ThreatCrush Security Scan

92 finding(s)

HIGH/CRITICAL: 50 | MEDIUM: 42

Severity Rule Location
HIGH manifest-typosquat apps/pwa/package.json:19
HIGH js-ssrf-outbound-request apps/pwa/public/sw.js:45
HIGH secret-generic-credential apps/pwa/test/apikey-bearer-scheme.test.mjs:30
HIGH secret-generic-credential apps/pwa/test/apikey-mask.test.mjs:38
HIGH secret-generic-credential apps/pwa/test/apikey-reveal.test.mjs:35
HIGH secret-generic-credential apps/pwa/test/approvals-context.test.mjs:28
HIGH secret-generic-credential apps/pwa/test/approvals-credits.test.mjs:28
HIGH secret-generic-credential apps/pwa/test/approvals-notify.test.mjs:26
HIGH secret-generic-credential apps/pwa/test/approvals-resolve-race.test.mjs:20
HIGH secret-generic-credential apps/pwa/test/auth-form-email.test.mjs:29
HIGH secret-generic-credential apps/pwa/test/auth-form-email.test.mjs:33
HIGH secret-generic-credential apps/pwa/test/auth-page-error.test.mjs:36
HIGH secret-generic-credential apps/pwa/test/cli-device-token.test.mjs:28
HIGH secret-generic-credential apps/pwa/test/cli-pages-balance.test.mjs:32
HIGH secret-generic-credential apps/pwa/test/cli-token.test.mjs:28
HIGH secret-generic-credential apps/pwa/test/credits-pack.test.mjs:51
HIGH secret-generic-credential apps/pwa/test/credits-webhook-event-match.test.mjs:35
HIGH secret-generic-credential apps/pwa/test/credits-webhook.test.mjs:28
HIGH secret-generic-credential apps/pwa/test/csrf-input-escaping.test.mjs:31
HIGH secret-generic-credential apps/pwa/test/csrf-input-escaping.test.mjs:101
HIGH secret-generic-credential apps/pwa/test/logout-csrf.test.mjs:29
HIGH secret-generic-credential apps/pwa/test/moshpit-api-key.test.mjs:28
HIGH secret-generic-credential apps/pwa/test/moshpit-bulk-claim.test.mjs:23
HIGH secret-generic-credential apps/pwa/test/moshpit-claim-full-name.test.mjs:29
HIGH secret-generic-credential apps/pwa/test/moshpit-crawlable.test.mjs:28
HIGH secret-generic-credential apps/pwa/test/moshpit-ending-page.test.mjs:28
HIGH secret-generic-credential apps/pwa/test/moshpit-pins.test.mjs:22
HIGH secret-generic-credential apps/pwa/test/moshpit-pit-page.test.mjs:33
HIGH secret-generic-credential apps/pwa/test/moshpit-records-page.test.mjs:23
HIGH secret-generic-credential apps/pwa/test/moshpit-records.test.mjs:23
HIGH secret-generic-credential apps/pwa/test/moshpit-registry.test.mjs:20
HIGH secret-generic-credential apps/pwa/test/moshpit-related-endings.test.mjs:28
HIGH secret-generic-credential apps/pwa/test/moshpit-sales.test.mjs:16
HIGH secret-generic-credential apps/pwa/test/moshpit-search.test.mjs:74
HIGH secret-generic-credential apps/pwa/test/moshpit-terms.test.mjs:19
HIGH secret-generic-credential apps/pwa/test/moshpit-tlds-pagination.test.mjs:28
HIGH secret-generic-credential apps/pwa/test/passkey-register-duplicate.test.mjs:38
HIGH secret-generic-credential apps/pwa/test/require-auth-next.test.mjs:31
HIGH secret-generic-credential apps/pwa/test/require-auth-next.test.mjs:35
HIGH secret-generic-credential apps/pwa/test/sessions-output-seq.test.mjs:30
HIGH secret-generic-credential apps/pwa/test/sessions-paste.test.mjs:24
HIGH secret-generic-credential apps/pwa/test/sessions-stream-replay.test.mjs:34
HIGH secret-generic-credential apps/pwa/test/sessions.test.mjs:24
HIGH secret-generic-credential apps/pwa/test/signature.test.mjs:6
HIGH secret-generic-credential test/auth.test.mjs:13
HIGH secret-generic-credential test/auth.test.mjs:63
HIGH secret-generic-credential test/console-cookie-malformed.test.mjs:15
HIGH secret-generic-credential test/console.test.mjs:12
HIGH secret-generic-credential test/mirror.test.mjs:37
HIGH secret-generic-credential test/mirror.test.mjs:77

…and 42 more. Full results in the Security tab.

Snippets are redacted; ThreatCrush never prints matched credential material.

@ralyodio
ralyodio merged commit d3e64bd into main Aug 5, 2026
4 checks passed
@ralyodio
ralyodio deleted the ci/npm-token-auth branch August 5, 2026 13:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant