Skip to content

Conversation

@azu
Copy link
Member

@azu azu commented Oct 12, 2025

Setup npm OIDC Trusted Publisher for monorepo

Summary

This PR implements npm OIDC (OpenID Connect) Trusted Publisher authentication for secure, automated package publishing in this monorepo. OIDC eliminates the need for long-lived npm tokens, reduces security risks through provenance attestation, and enables verifiable supply chain integrity for all 7 public packages.

What's Changed

Added comprehensive OIDC infrastructure including automated release workflows with provenance generation, provenance monitoring system, and security controls through CODEOWNERS protection. Updated Lerna configuration to match current tooling (pnpm) and enable proper monorepo release management.

Key Changes

New: .github/workflows/release.yml

Automated release workflow with OIDC authentication and security hardening:

  • 3-job security architecture: Separates permissions across check/release/comment jobs to minimize attack surface
  • OIDC authentication: Uses id-token: write permission with environment: npm for trusted publishing
  • Provenance generation: Enables NPM_CONFIG_PROVENANCE: true for supply chain attestation
  • Security hardening:
    • persist-credentials: false prevents credential leakage
    • No setup-node cache to prevent cache poisoning attacks
    • Minimal permissions per job (principle of least privilege)
  • Automatic notifications: Posts PR comments on release success/failure with package details

Trigger: Manual workflow dispatch only (no automatic releases)

New: .github/workflows/check-provenance.yml

Proactive monitoring system for OIDC provenance configuration:

  • 2-job permission isolation: Separates read-only check from comment permissions
  • Fast registry queries: Uses npm registry fetch API instead of slow CLI commands
  • Automated guidance: Posts PR comments with setup instructions when packages lack OIDC configuration
  • Monorepo-aware: Checks all 7 public packages in workspace

Trigger: Runs on PR open/synchronize to validate OIDC setup before releases

Packages monitored:

  • @textlint/config-inliner
  • @textlint/config-partial-parser
  • @textlint/runtime-helper
  • @textlint/script-compiler
  • @textlint/script-parser
  • @textlint/website-generator
  • textchecker-element

New: .github/CODEOWNERS

Security control to prevent unauthorized release workflow modifications:

  • Protected files: Requires @textlint/admin team review for:
    • .github/workflows/release.yml
    • .github/workflows/check-provenance.yml
    • .github/workflows/create-release-pr.yml (reserved for future)
    • .github/CODEOWNERS (self-protection)
  • Rationale: Release workflows have elevated npm publishing permissions and must be protected against supply chain attacks

Modified: lerna.json

Configuration updates for accurate release management:

  • npmClient: Changed from "yarn" to "pnpm" (matches actual package manager used in repository)
  • includeMergedTags: Added true to properly detect merged releases in monorepo history
  • ignoreChanges: Added patterns to exclude test/markdown files from version bumps:
    • "**/*.md"
    • "**/*.test.ts"
    • "**/*.test.js"
    • "**/test/**"
    • "**/__tests__/**"

Manual Setup Required

After merging this PR, repository administrators must complete the following one-time setup:

1. Configure GitHub Environment

Create a new GitHub Environment named npm with protection rules:

Settings > Environments > New environment
Name: npm
Protection rules:
  - Required reviewers: @textlint/admin (recommended)
  - Deployment branches: Selected branches > master

Why: The release workflow requires environment: npm for OIDC token issuance. Environment protection prevents unauthorized releases.

2. Enable Branch Protection (if not already configured)

Ensure master branch has protection rules:

Settings > Branches > Branch protection rules
Branch: master
Required:
  - Require pull request reviews before merging
  - Require status checks to pass
  - Enable CODEOWNERS review requirement

Why: Protects release workflows from unauthorized modifications via CODEOWNERS enforcement.

3. Configure npm.js OIDC Trusted Publisher (per package)

For each of the 7 public packages, add the GitHub Actions publisher:

Access Settings:

  1. Visit: https://www.npmjs.com/package/<package-name>/access
  2. Navigate to "Publishing access" > "Trusted publishers"
  3. Click "Add a trusted publisher"

Configuration (same for all packages):

Repository owner: textlint
Repository name: editor
Workflow name: release.yml
Environment name: npm

Packages requiring setup:

Note: The check-provenance.yml workflow will automatically verify this setup and post PR comments if any package is missing OIDC configuration.

Test Plan

Manual Verification Steps

  1. Verify GitHub Environment creation:

    • Navigate to repository Settings > Environments
    • Confirm npm environment exists with correct protection rules
    • Verify deployment branch restriction points to master
  2. Verify npm.js OIDC configuration:

    • For each package, visit npm access page
    • Confirm "Trusted publishers" section shows GitHub Actions publisher
    • Verify publisher configuration matches:
      • Repository: textlint/editor
      • Workflow: release.yml
      • Environment: npm
  3. Test release workflow (dry-run):

    • Navigate to Actions > Release workflow
    • Click "Run workflow" button
    • Monitor job execution for OIDC token acquisition
    • Verify no errors in check/release/comment jobs
  4. Test provenance check workflow:

    • Open any PR after merge
    • Verify check-provenance.yml runs automatically
    • Check PR comments for OIDC setup status
    • Confirm all 7 packages show as properly configured
  5. Verify CODEOWNERS protection:

    • Create test PR modifying .github/workflows/release.yml
    • Confirm GitHub requires @textlint/admin team review
    • Verify PR cannot be merged without required review

Expected Results

  • Release workflow successfully acquires OIDC token from GitHub
  • Published packages include provenance attestation in npm registry
  • Provenance check workflow reports all packages as properly configured
  • CODEOWNERS enforcement blocks unauthorized release workflow changes

Breaking Changes

None. This PR adds new infrastructure without modifying existing package code or breaking existing workflows.

Additional Notes

Security Improvements

  • No long-lived tokens: Eliminates NPM_TOKEN secret from repository (can be removed after OIDC verification)
  • Provenance attestation: Every published package includes cryptographically signed build provenance
  • Supply chain transparency: Users can verify packages were built from official source repository
  • Minimal permissions: Each workflow job has least-privilege permissions
  • Protected workflows: CODEOWNERS prevents unauthorized release modifications

Documentation References

Implementation Pattern

This implementation follows the proven pattern from textlint/textlint repository, which successfully uses OIDC Trusted Publisher for its monorepo releases.


🤖 Generated with Claude Code

- Add release.yml workflow with OIDC authentication
- Add check-provenance.yml workflow to monitor OIDC status
- Add CODEOWNERS to protect release workflows
- Update lerna.json to use pnpm as npmClient

This implements npm OIDC Trusted Publisher following textlint's proven pattern.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@github-actions
Copy link
Contributor

github-actions bot commented Oct 12, 2025

📦 NPM Package Status

Published Packages Missing OIDC Configuration

Configure OIDC for these packages:

Setup Instructions:

  1. Click each package link above
  2. Click "Add trusted publisher"
  3. Configure with:
    • Repository: textlint/editor
    • Workflow: .github/workflows/release.yml
    • Environment: npm

@azu azu added the Type: CI Changes to CI configuration files and scripts label Oct 12, 2025
@azu azu changed the title feat: setup npm OIDC Trusted Publisher for monorepo CI(release): setup npm OIDC Trusted Publisher for monorepo Oct 12, 2025
@azu azu merged commit 48ab5af into master Oct 12, 2025
6 checks passed
@azu azu deleted the oidc branch October 12, 2025 04:06
This was referenced Oct 12, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Type: CI Changes to CI configuration files and scripts

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants