Conversation
Replace token-based authentication with OpenID Connect (OIDC) for enhanced security: - Remove NPM_TOKEN from changesets action environment - Enable automatic provenance generation (NPM_CONFIG_PROVENANCE) - Set NODE_AUTH_TOKEN to empty string to force OIDC authentication - Keep diagnostic step for troubleshooting auth issues This requires configuring npm Trusted Publisher on npmjs.com for the repository.
Split changesets/action into versioning-only step and separate publish step to avoid .npmrc token mutation that would block OIDC. This ensures npm uses Trusted Publisher authentication instead of legacy token-based auth. Key changes: - changesets/action now only runs version step (no publish input) - Added OIDC preflight step to scrub any auth tokens from .npmrc before publishing - Separated publish into dedicated step with pnpm changeset-publish - Added post-mortem diagnostics for troubleshooting publish failures The id-token: write permission remains enabled for OIDC token generation. Registry setup and package.json publish script already include provenance.
Address three critical risks identified during code review: 1. Gate publish step to run only when no changesets exist - Prevents wasteful runs and log noise when version PR is created - Ensures publish only runs on merge commits (when hasChangesets == 'false') - .github/workflows/publish.yaml:74 2. Harden preflight to scrub all .npmrc locations and auth forms - Iterate over all potential locations: NPM_CONFIG_USERCONFIG, ~/.npmrc, .npmrc - Remove both registry-scoped (_authToken, _auth=) and global (always-auth) forms - Prevents stray .npmrc from blocking OIDC authentication - .github/workflows/publish.yaml:45-52 3. Make whoami check robust with exit code instead of grep - Check npm whoami exit code (0 = logged in, non-zero = not logged in) - Avoids reliance on fragile message matching across npm versions - Verify registry config (including @openrouter scope) - .github/workflows/publish.yaml:62-71 4. Enhance post-mortem diagnostics - Log registry configuration for both global and @openrouter scope - Redact .npmrc contents to aid forensics without exposing secrets - Check all three potential .npmrc locations - .github/workflows/publish.yaml:92-101 With these changes, the workflow is hardened against OIDC authentication failures.
…rubbing Improve sed patterns to handle edge cases in token removal: - Registry-scoped tokens: Allow optional whitespace around = sign sed -i -E '/\/\/registry\.npmjs\.org\/:(_authToken|_auth)\s*=/d' - Global tokens: Match _authToken or _auth anywhere on a line with leading whitespace sed -i -E '/^\s*(_authToken|_auth)\s*=/d' - Global always-auth: Case-insensitive with optional spacing sed -i -E '/^\s*[Aa]lways-[Aa]uth\s*=/d' This closes the gap where npm could treat whitespace-padded or variant token lines as a signal to use legacy token auth instead of OIDC. Extended regex (-E) enables more flexible matching without sacrificing readability. Addresses edge case identified during workflow review.
There was a problem hiding this comment.
Pull Request Overview
This PR migrates the npm publishing workflow from using a manual NPM_TOKEN secret to OIDC (OpenID Connect) authentication. This enhances security by eliminating the need to store long-lived npm tokens as GitHub secrets, instead leveraging GitHub's built-in OIDC token provider for authenticated npm publishing.
Key Changes:
- Separated changesets
versionandpublishsteps for better control over the release process - Implemented OIDC preflight step that scrubs legacy auth tokens from
.npmrcfiles to ensure OIDC is used - Configured publishing to use npm provenance with
--provenanceflag for supply chain security - Updated diagnostic steps to focus on OIDC-specific validation and post-mortem analysis
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if [ -n "$npmrc" ] && [ -f "$npmrc" ]; then | ||
| echo " $npmrc:" | ||
| echo " Lines: $(wc -l < "$npmrc")" | ||
| echo " Auth lines: $(grep -c "_auth\|_token" "$npmrc" || echo "0")" |
There was a problem hiding this comment.
[nitpick] The grep -c command will exit with status 1 when no matches are found, but the pattern "_auth\|_token" uses BRE (Basic Regular Expression) syntax. When using grep without -E, the pipe character | needs to be escaped as \| which is correct here. However, for better portability and clarity, consider using grep -E (or egrep) with unescaped |:
echo " Auth lines: $(grep -cE "_auth|_token" "$npmrc" || echo "0")"Alternatively, to match the pattern more precisely (matching the actual config key names), consider:
echo " Auth lines: $(grep -cE "(_authToken|_auth|_token)\s*=" "$npmrc" || echo "0")"| echo " Auth lines: $(grep -c "_auth\|_token" "$npmrc" || echo "0")" | |
| echo " Auth lines: $(grep -cE '(_authToken|_auth|_token)\s*=' "$npmrc" || echo "0")" |
| echo " Lines: $(wc -l < "$npmrc")" | ||
| echo " Auth lines: $(grep -c "_auth\|_token" "$npmrc" || echo "0")" | ||
| echo " Content (redacted):" | ||
| sed 's/\(_auth[^=]*=\).*/\1***REDACTED***/g; s/\(_token[^=]*=\).*/\1***REDACTED***/g' "$npmrc" | sed 's/^/ /' |
There was a problem hiding this comment.
[nitpick] The sed pattern matching on line 100 is inconsistent with the cleanup patterns used earlier (lines 49-53). The cleanup patterns match _authToken and _auth as distinct keys, but this redaction pattern uses a more generic approach with _auth[^=]* which would match both.
For consistency and accuracy, consider aligning the redaction pattern with the cleanup patterns:
sed 's/\(_authToken\s*=\).*/\1***REDACTED***/g; s/\(_auth\s*=\).*/\1***REDACTED***/g' "$npmrc" | sed 's/^/ /'This ensures you're redacting the same patterns you're cleaning up.
| sed 's/\(_auth[^=]*=\).*/\1***REDACTED***/g; s/\(_token[^=]*=\).*/\1***REDACTED***/g' "$npmrc" | sed 's/^/ /' | |
| sed 's/\(_authToken\s*=\).*/\1***REDACTED***/g; s/\(_auth\s*=\).*/\1***REDACTED***/g' "$npmrc" | sed 's/^/ /' |
Their comments: Latest commit: Upgrade npm to support OIDC Trusted Publishing (OpenRouterTeam#231) npm v10.8.2 (bundled with Node 20.x) predates Trusted Publishing support. npm CLI v11.5.1+ is required for OIDC authentication with --provenance flag. Evidence: CI publish failed with ENEEDAUTH despite id-token: write and correct workflow setup. npm fell back to token auth and found none. Add explicit npm upgrade step before publish to ensure OIDC works. Previous: Migrate npm OIDC (OpenRouterTeam#230) * refactor: migrate to OIDC for npm package publishing Replace token-based authentication with OpenID Connect (OIDC) for enhanced security: - Remove NPM_TOKEN from changesets action environment - Enable automatic provenance generation (NPM_CONFIG_PROVENANCE) - Set NODE_AUTH_TOKEN to empty string to force OIDC authentication - Keep diagnostic step for troubleshooting auth issues This requires configuring npm Trusted Publisher on npmjs.com for the repository. * refactor: restructure publish workflow to support OIDC properly Split changesets/action into versioning-only step and separate publish step to avoid .npmrc token mutation that would block OIDC. This ensures npm uses Trusted Publisher authentication instead of legacy token-based auth. Key changes: - changesets/action now only runs version step (no publish input) - Added OIDC preflight step to scrub any auth tokens from .npmrc before publishing - Separated publish into dedicated step with pnpm changeset-publish - Added post-mortem diagnostics for troubleshooting publish failures The id-token: write permission remains enabled for OIDC token generation. Registry setup and package.json publish script already include provenance. * fix: harden OIDC workflow with publish gate and comprehensive preflight Address three critical risks identified during code review: 1. Gate publish step to run only when no changesets exist - Prevents wasteful runs and log noise when version PR is created - Ensures publish only runs on merge commits (when hasChangesets == 'false') - .github/workflows/publish.yaml:74 2. Harden preflight to scrub all .npmrc locations and auth forms - Iterate over all potential locations: NPM_CONFIG_USERCONFIG, ~/.npmrc, .npmrc - Remove both registry-scoped (_authToken, _auth=) and global (always-auth) forms - Prevents stray .npmrc from blocking OIDC authentication - .github/workflows/publish.yaml:45-52 3. Make whoami check robust with exit code instead of grep - Check npm whoami exit code (0 = logged in, non-zero = not logged in) - Avoids reliance on fragile message matching across npm versions - Verify registry config (including @openrouter scope) - .github/workflows/publish.yaml:62-71 4. Enhance post-mortem diagnostics - Log registry configuration for both global and @openrouter scope - Redact .npmrc contents to aid forensics without exposing secrets - Check all three potential .npmrc locations - .github/workflows/publish.yaml:92-101 With these changes, the workflow is hardened against OIDC authentication failures. * refine: use extended regex patterns for comprehensive .npmrc token scrubbing Improve sed patterns to handle edge cases in token removal: - Registry-scoped tokens: Allow optional whitespace around = sign sed -i -E '/\/\/registry\.npmjs\.org\/:(_authToken|_auth)\s*=/d' - Global tokens: Match _authToken or _auth anywhere on a line with leading whitespace sed -i -E '/^\s*(_authToken|_auth)\s*=/d' - Global always-auth: Case-insensitive with optional spacing sed -i -E '/^\s*[Aa]lways-[Aa]uth\s*=/d' This closes the gap where npm could treat whitespace-padded or variant token lines as a signal to use legacy token auth instead of OIDC. Extended regex (-E) enables more flexible matching without sacrificing readability. Addresses edge case identified during workflow review.
* refactor: migrate to OIDC for npm package publishing Replace token-based authentication with OpenID Connect (OIDC) for enhanced security: - Remove NPM_TOKEN from changesets action environment - Enable automatic provenance generation (NPM_CONFIG_PROVENANCE) - Set NODE_AUTH_TOKEN to empty string to force OIDC authentication - Keep diagnostic step for troubleshooting auth issues This requires configuring npm Trusted Publisher on npmjs.com for the repository. * refactor: restructure publish workflow to support OIDC properly Split changesets/action into versioning-only step and separate publish step to avoid .npmrc token mutation that would block OIDC. This ensures npm uses Trusted Publisher authentication instead of legacy token-based auth. Key changes: - changesets/action now only runs version step (no publish input) - Added OIDC preflight step to scrub any auth tokens from .npmrc before publishing - Separated publish into dedicated step with pnpm changeset-publish - Added post-mortem diagnostics for troubleshooting publish failures The id-token: write permission remains enabled for OIDC token generation. Registry setup and package.json publish script already include provenance. * fix: harden OIDC workflow with publish gate and comprehensive preflight Address three critical risks identified during code review: 1. Gate publish step to run only when no changesets exist - Prevents wasteful runs and log noise when version PR is created - Ensures publish only runs on merge commits (when hasChangesets == 'false') - .github/workflows/publish.yaml:74 2. Harden preflight to scrub all .npmrc locations and auth forms - Iterate over all potential locations: NPM_CONFIG_USERCONFIG, ~/.npmrc, .npmrc - Remove both registry-scoped (_authToken, _auth=) and global (always-auth) forms - Prevents stray .npmrc from blocking OIDC authentication - .github/workflows/publish.yaml:45-52 3. Make whoami check robust with exit code instead of grep - Check npm whoami exit code (0 = logged in, non-zero = not logged in) - Avoids reliance on fragile message matching across npm versions - Verify registry config (including @openrouter scope) - .github/workflows/publish.yaml:62-71 4. Enhance post-mortem diagnostics - Log registry configuration for both global and @openrouter scope - Redact .npmrc contents to aid forensics without exposing secrets - Check all three potential .npmrc locations - .github/workflows/publish.yaml:92-101 With these changes, the workflow is hardened against OIDC authentication failures. * refine: use extended regex patterns for comprehensive .npmrc token scrubbing Improve sed patterns to handle edge cases in token removal: - Registry-scoped tokens: Allow optional whitespace around = sign sed -i -E '/\/\/registry\.npmjs\.org\/:(_authToken|_auth)\s*=/d' - Global tokens: Match _authToken or _auth anywhere on a line with leading whitespace sed -i -E '/^\s*(_authToken|_auth)\s*=/d' - Global always-auth: Case-insensitive with optional spacing sed -i -E '/^\s*[Aa]lways-[Aa]uth\s*=/d' This closes the gap where npm could treat whitespace-padded or variant token lines as a signal to use legacy token auth instead of OIDC. Extended regex (-E) enables more flexible matching without sacrificing readability. Addresses edge case identified during workflow review.
No description provided.