Trusted Publishers
Trusted Publishers is a modern authentication method that helps you publish packages more securely by eliminating the need for long-lived API tokens. Instead of managing sensitive credentials, it uses OpenID Connect (OIDC) to generate short-lived tokens from your CI system (like GitHub Actions or GitLab Pipelines). This means less security risk and easier maintenance, as you don't need to regularly rotate or protect long-lived tokens. Trusted Publishers ensures packages come from specific CI systems or build pipelines, reducing the risk of token theft and unauthorized publications.
How Trusted Publishers Work
Trusted Publishers leverage OpenID Connect (OIDC) to establish trust between your CI/CD system and package repositories:
- Identity Provider: Your CI system (GitHub Actions) acts as an OIDC identity provider
- Token Exchange: The CI system generates a short-lived OIDC token containing metadata about the workflow
- Verification: The package repository verifies the token and checks it against configured trusted publishers
- API Token: If verification succeeds, the repository issues a temporary API token for publishing
This eliminates the need to store long-lived secrets in your repository.
Supported Package Repositories
Projen currently supports trusted publishing for:
- npmjs.com - Node.js packages with trusted publishing and provenance statements
- PyPI - Python Package Index with attestations
npm Trusted Publishing
Setup
To enable npm trusted publishing in your projen project:
const project = new NodeProject({
// ... other options
publishToNpm: true,
npmPublishOptions: {
trustedPublishing: true,
},
});
Or for JSII projects:
const project = new JsiiProject({
// ... other options
publishToNpm: {
trustedPublishing: true,
},
});
Meeting the npm Version Requirement
Trusted publishing requires npm CLI version 11.5.1 or later. By default, this is available with Node.js 24+. You have two options to meet this requirement:
Option 1: Update Node.js version for all workflows
const project = new NodeProject({
// ... other options
workflowNodeVersion: "24.x",
publishToNpm: true,
npmPublishOptions: {
trustedPublishing: true,
},
});
Option 2: Manual workflow patching (advanced)
For more granular control, you can manually patch the workflow:
// Update Node.js version for npm publishing job only
project.github?.tryFindWorkflow("release")?.file?.patch(
JsonPatch.replace("/jobs/release_npm/steps/0/with/node-version", "24.x")
);
// Or add a step to update npm
project.github?.tryFindWorkflow("release")?.file?.patch(
JsonPatch.add("/jobs/release_npm/steps/1", {
name: "Update npm",
run: "npm i -g npm@latest",
})
);
Recommendation: Option 1 is recommended for most users. Option 2 provides more granular control if you need to keep other workflows on an older Node.js version.
npm Configuration
Before using trusted publishing, you must configure your npm package:
- Go to npm: Navigate to your package's settings on npmjs.com
- Add Publisher: Under "Publishing access", click "Require two-factor authentication or automation tokens"
- Configure GitHub Actions:
- Subject:
repo:owner/repository:ref:refs/heads/main
- Issuer:
https://token.actions.githubusercontent.com
- Replace
owner/repository
with your GitHub username/organization and repository name - Adjust the branch name if different from
main
- Subject:
Or follow the official npm documentation.
Requirements
- npm CLI version 11.5.1 or later (this is NOT ensured automatically by projen)
- Available by default with Node.js 24+
- See "Meeting the npm Version Requirement" section above for solutions
- Package must be configured for trusted publishing on npmjs.com
- GitHub Actions workflow must run from the configured repository and branch
How It Works
When publishing with trusted publishing enabled:
- GitHub Actions generates an OIDC token containing workflow metadata
- The publishing job uses this token to authenticate with npm
- npm verifies the token against your configured trusted publisher settings
- No long-lived NPM_TOKEN secrets are needed in your repository
Provenance Statements
By default, when using trusted publishing, npm will generate provenance statements that:
- Provide cryptographic proof of where and how your package was built
- Are automatically displayed on the npm package page
- Help users verify package integrity and authenticity
- Work with tools like
npm audit signatures
PyPI Trusted Publishing
Setup
To enable PyPI trusted publishing in your projen project:
const project = new PythonProject({
// ... other options
publishToPypi: {
trustedPublishing: true,
},
});
PyPI Configuration
Before using trusted publishing, you must configure your PyPI project:
- Go to PyPI: Navigate to your project's settings on PyPI
- Add Publisher: Under "Publishing", click "Add a new publisher"
- Configure GitHub Actions:
- Owner: Your GitHub username or organization
- Repository name: Your repository name
- Workflow name:
release.yml
(or your release workflow filename) - Environment name: Leave empty unless using GitHub environments
Or follow the official PyPI documentation.
How It Works
When publishing with trusted publishing enabled:
- GitHub Actions generates an OIDC token containing workflow metadata
- The publishing job exchanges this token for a PyPI API token
- The temporary API token is used to publish your package
- No long-lived secrets are stored in your repository
Migration Guide
From Token-Based to Trusted Publishing
For npm packages
-
Update your projen configuration:
publishToNpm: {
trustedPublishing: true,
// Remove npmTokenSecret if present
} -
Configure npm trusted publisher (see npm Configuration above)
-
Remove secrets from GitHub:
- You can safely remove
NPM_TOKEN
secrets - Keep them temporarily during transition for rollback capability
- You can safely remove
-
Test the setup:
- Create a test release to verify trusted publishing works
- Monitor the workflow logs for successful authentication
- Check that provenance statements appear on npm (if enabled)
-
Clean up:
- Delete old API tokens in npm once you are confident with the new setup
For PyPI packages
-
Update your projen configuration:
publishToPypi: {
trustedPublishing: true,
// Remove twinePasswordSecret if present
} -
Configure PyPI trusted publisher (see PyPI Configuration above)
-
Remove secrets from GitHub:
- You can safely remove
TWINE_PASSWORD
andTWINE_USERNAME
secrets - Keep them temporarily during transition for rollback capability
- You can safely remove
-
Test the setup:
- Create a test release to verify trusted publishing works
- Monitor the workflow logs for successful token minting
-
Clean up:
- Delete old API tokens in PyPI once you are confident with the new setup