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
When publishing with trusted publishing enabled:
- Your CI system generates an OIDC token containing metadata about your workflow and repository (this "ambient identity" is automatically provided by the CI environment)
- The publishing job uses this token to authenticate with the package repository
- The package repository verifies the token against your configured trusted publisher settings
- A temporary API token is issued for publishing your package
- No long-lived secrets are stored in your repository
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
- NuGet.org - .NET packages with trusted publishing
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
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.
NuGet Trusted Publishing
Setup
To enable NuGet trusted publishing in your projen project:
const project = new CsharpProject({
// ... other options
publishToNuget: {
trustedPublishing: true,
},
});
NuGet Configuration
Before using trusted publishing, you must configure your NuGet.org project:
- Go to NuGet.org: Navigate to your account settings on NuGet.org
- Add Publisher: Under "Trusted Publishing", click "Add a new trusted publisher"
- Configure GitHub Actions:
- Repository Owner: Your GitHub username or organization
- Repository: Your repository name
- Workflow File:
release.yml
(filename only, not the full path) - Environment: Leave empty unless using GitHub environments
Or follow the official NuGet documentation.
GitHub Secrets
You must configure the NUGET_USERNAME
secret (or a different secret name if customized) with your NuGet.org username (profile name, not email address).
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
For NuGet packages
-
Update your projen configuration:
publishToNuget: {
trustedPublishing: true,
// Remove nugetApiKeySecret if present
} -
Configure NuGet trusted publisher (see NuGet Configuration above)
-
Add GitHub secret:
- Add
NUGET_USERNAME
secret with your NuGet.org username (profile name, not email)
- Add
-
Remove old secrets from GitHub:
- You can safely remove
NUGET_API_KEY
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
-
Clean up:
- Delete old API keys in NuGet.org once you are confident with the new setup