Skip to content

Commit c777894

Browse files
committed
Add docs for trusted publishing
1 parent 0cef75b commit c777894

File tree

11 files changed

+292
-4
lines changed

11 files changed

+292
-4
lines changed

content/integrations/integrating-npm-with-external-services/creating-and-viewing-access-tokens.mdx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ You can [create](#creating-access-tokens) and [view](#viewing-access-tokens) acc
1212

1313
<Note>
1414

15-
**Note:** For greater security, we recommend using [granular access tokens](#creating-granular-access-tokens-on-the-website) instead of legacy read-only tokens or legacy automation tokens.
15+
**Note:** For greater security, we recommend using [granular access tokens](#creating-granular-access-tokens-on-the-website) instead of legacy read-only tokens or legacy automation tokens. For CI/CD workflows, consider using [trusted publishing](/packages-and-modules/securing-your-code/trusted-publishers), which eliminates the need for long-lived tokens entirely.
1616

1717
</Note>
1818

@@ -29,7 +29,7 @@ You can [create](#creating-access-tokens) and [view](#viewing-access-tokens) acc
2929
4. Select the type of access token:
3030
- **Read-only**: A read-only token can only be used to download packages from the registry. It will have permission to read any private package that you have access to. This is recommended for automation and workflows where you are installing packages, but not publishing new ones.
3131

32-
- **Automation**: An automation token can download packages and publish new ones, but if you have two-factor authentication (2FA) configured on your account, it will **not** be enforced. You can use an automation token in continuous integration workflows and other automation systems to publish a package even when you cannot enter a one-time passcode.
32+
- **Automation**: An automation token can download packages and publish new ones, but if you have two-factor authentication (2FA) configured on your account, it will **not** be enforced. You can use an automation token in continuous integration workflows and other automation systems to publish a package even when you cannot enter a one-time passcode. For enhanced security in CI/CD workflows, consider using [trusted publishing](/packages-and-modules/securing-your-code/trusted-publishers) instead, which eliminates the need for long-lived tokens.
3333

3434
- **Publish**: A publish token can perform any action on your behalf, including downloading packages, publishing packages, and changing user settings or package settings. If you have two-factor authentication configured on your account, you will be required to enter a one-time passcode when using a publish token. This is recommended for interactive workflows such as a CLI.
3535

content/integrations/integrating-npm-with-external-services/using-private-packages-in-a-ci-cd-workflow.mdx

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,17 @@ redirect_from:
66

77
You can use access tokens to test private npm packages with continuous integration (CI) systems, or deploy them using continuous deployment (CD) systems.
88

9+
## Recommended: Use trusted publishing for package publishing
10+
11+
For publishing packages from CI/CD workflows, we recommend using [trusted publishing](/packages-and-modules/securing-your-code/trusted-publishers) instead of access tokens. Trusted publishing uses OpenID Connect (OIDC) to provide secure, token-free publishing that eliminates the security risks associated with long-lived tokens.
12+
13+
Trusted publishing is supported for:
14+
15+
- [GitHub Actions](https://github.com/features/actions) (GitHub-hosted runners)
16+
- [GitLab CI/CD](https://docs.gitlab.com/ci/pipelines/) (GitLab.com shared runners)
17+
18+
If you use a different CI/CD provider, or if you need to install private packages (not publish), you can use access tokens as described below.
19+
920
## Create a new access token
1021

1122
Create a new access token that will be used only to access npm packages from a CI/CD server.
@@ -24,7 +35,9 @@ For more information on creating access tokens, including CIDR-whitelisted token
2435

2536
### Continuous deployment
2637

27-
Since continuous deployment environments usually involve the creation of a deploy artifact, you may wish to create an [automation token][create-token] on the website. This will allow you to publish even if you have two-factor authentication enabled on your account.
38+
For publishing packages in continuous deployment environments, we strongly recommend using [trusted publishing](/packages-and-modules/securing-your-code/trusted-publishers) when available, as it provides enhanced security without requiring token management.
39+
40+
If trusted publishing is not available for your CI/CD provider, you may create an [automation token][create-token] on the website. This will allow you to publish even if you have two-factor authentication enabled on your account.
2841

2942
### Interactive workflows
3043

content/nav.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,8 @@
156156
url: /auditing-package-dependencies-for-security-vulnerabilities
157157
- title: Generating provenance statements
158158
url: /generating-provenance-statements
159+
- title: Trusted publishing with OIDC
160+
url: /trusted-publishers
159161
- title: About ECDSA registry signatures
160162
url: /about-registry-signatures
161163
- title: Verifying ECDSA registry signatures

content/packages-and-modules/contributing-packages-to-the-registry/creating-and-publishing-unscoped-public-packages.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ npm install path/to/my-package
7272

7373
<Note>
7474

75-
**Note:** If you use GitHub Actions to publish your packages, you can generate provenance information for each package you publish. For more information, see "[Generating provenance statements][provenance-how-to]."
75+
**Note:** If you use GitHub Actions or GitLab CI/CD to publish your packages, consider using [trusted publishing](/packages-and-modules/securing-your-code/trusted-publishers) for enhanced security. Trusted publishing automatically generates provenance information and eliminates the need for access tokens in your CI/CD workflows. For more information, see "[Generating provenance statements][provenance-how-to]."
7676

7777
</Note>
7878

content/packages-and-modules/securing-your-code/generating-provenance-statements.mdx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ Before you can publish your packages with provenance, you must:
4242
- GitHub Actions. For more information, see "[Publishing packages with provenance via GitHub Actions][github-provenance]."
4343
- GitLab CI/CD. For more information, see "[Publishing packages with provenance via GitLab CI/CD][gitlab-provenance]."
4444

45+
**Note:** If you use [trusted publishing](/packages-and-modules/securing-your-code/trusted-publishers), provenance attestations are automatically generated for your packages without requiring the `--provenance` flag. This provides enhanced security and eliminates the need for access tokens in your CI/CD workflows.
46+
4547
## Publishing packages with provenance via GitHub Actions
4648

4749
In order to establish provenance, you must use a supported cloud CI/CD provider and a cloud-hosted runner to publish your packages. GitHub Actions is a supported CI/CD platform that allows you to automate software development tasks. For more information, see [GitHub Actions][github-actions] in the GitHub documentation.

content/packages-and-modules/securing-your-code/requiring-2fa-for-package-publishing-and-settings-modification.mdx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ To protect your packages, as a package publisher, you can require everyone who h
88

99
You may also choose to allow publishing with either two-factor authentication _or_ with [automation tokens][creating-automation-token]. This lets you configure automation tokens in a CI/CD workflow, but requires two-factor authentication from interactive publishes.
1010

11+
For CI/CD workflows, consider using [trusted publishing](/packages-and-modules/securing-your-code/trusted-publishers), which provides secure, token-free publishing that automatically enforces strong authentication without requiring manual token management.
12+
1113
## Configuring two-factor authentication
1214

1315
1. <>{shared['user-login'].text}</>
Lines changed: 269 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,269 @@
1+
---
2+
title: Trusted publishing for npm packages
3+
---
4+
5+
Trusted publishing allows you to publish npm packages directly from your CI/CD workflows using [OpenID Connect (OIDC)](https://openid.net/developers/how-connect-works/) authentication, eliminating the need for long-lived npm tokens. This feature implements the [Trusted Publishers standard](https://repos.openssf.org/trusted-publishers-for-all-package-repositories) from the Open Source Security Foundation (OpenSSF), joining a growing ecosystem including [PyPI](https://docs.pypi.org/trusted-publishers/), [RubyGems](https://guides.rubygems.org/trusted-publishing/), and other major package registries in offering this security enhancement.
6+
7+
<Note>
8+
9+
**Note:** Trusted publishing requires [npm CLI](https://docs.npmjs.com/cli/v11) version 11.5.0 or later.
10+
11+
</Note>
12+
13+
## How trusted publishing works
14+
15+
Trusted publishing creates a trust relationship between npm and your CI/CD provider using OIDC. When you configure a trusted publisher for your package, npm will accept publishes from the specific workflow you've authorized, in addition to traditional authentication methods like npm tokens and manual publishes. The npm CLI automatically detects OIDC environments and uses them for authentication before falling back to traditional tokens.
16+
17+
This approach eliminates the security risks associated with long-lived write tokens, which can be compromised, accidentally exposed in logs, or require manual rotation. Instead, each publish uses short-lived, cryptographically-signed tokens that are specific to your workflow and cannot be extracted or reused.
18+
19+
## Supported CI/CD providers
20+
21+
Trusted publishing currently supports:
22+
23+
- [GitHub Actions](https://github.com/features/actions) (GitHub-hosted runners)
24+
- [GitLab CI/CD Pipelines](https://docs.gitlab.com/ci/pipelines/) (GitLab.com shared runners)
25+
26+
Self-hosted runners are not currently supported but are planned for future releases.
27+
28+
## Configuring trusted publishing
29+
30+
### Step 1: Add a trusted publisher on npmjs.com
31+
32+
Navigate to your package settings on [npmjs.com](https://www.npmjs.com) and find the "**Trusted Publisher**" section. Under "**Select your publisher**", choose your CI/CD provider by clicking either the GitHub Actions or GitLab CI/CD button.
33+
34+
<Screenshot src="/packages-and-modules/securing-your-code/trusted-publisher.png" alt="Screenshot showing the Trusted Publisher section with Select your publisher label and provider buttons" />
35+
36+
#### For GitHub Actions
37+
38+
Configure the following fields:
39+
40+
- **Organization or user** (required): Your GitHub username or organization name
41+
- **Repository** (required): Your repository name
42+
- **Workflow filename** (required): The filename of your workflow (e.g., `publish.yml`)
43+
- Enter only the filename, not the full path
44+
- Must include the `.yml` or `.yaml` extension
45+
- The workflow file must exist in `.github/workflows/` in your repository
46+
- **Environment name** (optional): If using [GitHub environments](https://docs.github.com/en/actions/deployment/targeting-different-environments/using-environments-for-deployment) for deployment protection
47+
48+
<Screenshot src="/packages-and-modules/securing-your-code/trusted-publisher-github-actions.png" alt="Screenshot of GitHub Actions trusted publisher configuration form" />
49+
50+
#### For GitLab CI/CD
51+
52+
Configure the following fields:
53+
54+
- **Namespace** (required): Your GitLab username or group name
55+
- **Project name** (required): Your project name
56+
- **Top-level CI file path** (required): The path to your CI file (e.g., `.gitlab-ci.yml`)
57+
- Must include the `.yml` extension
58+
- **Environment name** (optional): If using [GitLab environments](https://docs.gitlab.com/ee/ci/environments/)
59+
60+
<Screenshot src="/packages-and-modules/securing-your-code/trusted-publisher-gitlab.png" alt="Screenshot of GitLab CI/CD trusted publisher configuration form" />
61+
62+
<Note>
63+
64+
**Note:** Each package can only have one trusted publisher configured at a time.
65+
66+
</Note>
67+
68+
### Step 2: Configure your CI/CD workflow
69+
70+
#### GitHub Actions configuration
71+
72+
Add the required OIDC permissions to your workflow. Here's a complete example:
73+
74+
```yaml
75+
name: Publish Package
76+
77+
on:
78+
push:
79+
tags:
80+
- 'v*'
81+
82+
permissions:
83+
id-token: write # Required for OIDC
84+
contents: read
85+
86+
jobs:
87+
publish:
88+
runs-on: ubuntu-latest
89+
steps:
90+
- uses: actions/checkout@v4
91+
92+
- uses: actions/setup-node@v4
93+
with:
94+
node-version: '20'
95+
registry-url: 'https://registry.npmjs.org'
96+
97+
# Ensure npm 11.5.0 or later is installed
98+
- name: Update npm
99+
run: npm install -g npm@latest
100+
- run: npm ci
101+
- run: npm run build --if-present
102+
- run: npm test
103+
- run: npm publish
104+
```
105+
106+
The critical requirement is the `id-token: write` permission, which allows GitHub Actions to generate OIDC tokens. Learn more in [GitHub's OIDC documentation](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect).
107+
108+
#### GitLab CI/CD configuration
109+
110+
Configure the OIDC ID token in your pipeline:
111+
112+
```yaml
113+
stages:
114+
- test
115+
- build
116+
- publish
117+
118+
variables:
119+
NODE_VERSION: '20'
120+
121+
id_tokens:
122+
NPM_ID_TOKEN:
123+
aud: "npm:registry.npmjs.org"
124+
125+
test:
126+
stage: test
127+
image: node:${NODE_VERSION}
128+
script:
129+
- npm ci
130+
- npm test
131+
132+
publish:
133+
stage: publish
134+
image: node:${NODE_VERSION}
135+
script:
136+
# Ensure npm 11.5.0 or later is installed
137+
- npm install -g npm@latest
138+
- npm ci
139+
- npm run build --if-present
140+
- npm publish
141+
only:
142+
- tags
143+
```
144+
145+
The `id_tokens` configuration tells GitLab to generate an OIDC token for npm. Learn more in [GitLab's OIDC documentation](https://docs.gitlab.com/ee/ci/cloud_services/).
146+
147+
### Managing trusted publisher configurations
148+
149+
You can modify or remove your trusted publisher configuration at any time through your package settings on [npmjs.com](https://npmjs.com). Each package can only have one trusted publisher connection at a time, but this connection can be edited or deleted as needed. To change providers (for example, switching from GitHub Actions to GitLab CI/CD), simply edit your existing configuration and select the new provider. The change takes effect immediately for future publishes. To remove trusted publishing entirely and return to token-based authentication, delete the trusted publisher configuration from your package settings.
150+
151+
## Automatic provenance generation
152+
153+
When you publish using trusted publishing, npm automatically generates and publishes [provenance attestations](./generating-provenance-statements) for your package. This happens by default—you don't need to add the `--provenance` flag to your publish command.
154+
155+
<Screenshot src="/packages-and-modules/securing-your-code/trusted-publisher-provenance.png" alt="Screenshot showing provenance badge/information on a package page" />
156+
157+
Provenance provides cryptographic proof of where and how your package was built, allowing users to verify its authenticity. This automatic generation only applies when all of these conditions are met:
158+
159+
- Publishing via trusted publishing (OIDC)
160+
- Publishing from a public repository
161+
- Publishing a public package
162+
163+
<Note>
164+
165+
**Note:** Provenance generation is [not supported for private repositories](https://github.blog/changelog/2023-07-25-publishing-with-npm-provenance-from-private-source-repositories-is-no-longer-supported/), even when publishing public packages.
166+
167+
</Note>
168+
169+
### Disabling provenance generation
170+
171+
While we strongly recommend keeping provenance enabled, you can disable it if needed. Set the `provenance` option to `false` in any of these ways:
172+
173+
**Using environment variable:**
174+
175+
```bash
176+
NPM_CONFIG_PROVENANCE=false npm publish
177+
```
178+
179+
**In your `.npmrc` file:**
180+
181+
```ini
182+
provenance=false
183+
```
184+
185+
**In your `package.json`:**
186+
187+
```json
188+
{
189+
"publishConfig": {
190+
"provenance": false
191+
}
192+
}
193+
```
194+
195+
## Security best practices
196+
197+
### Prefer trusted publishing over tokens
198+
199+
When trusted publishing is available for your workflow, always prefer it over long-lived tokens. Traditional npm tokens pose several security risks:
200+
201+
- They can be accidentally exposed in CI logs or configuration files
202+
- They require manual rotation and management
203+
- If compromised, they provide persistent access until revoked
204+
- They often have broader permissions than necessary
205+
206+
Trusted publishing eliminates these risks by using short-lived, workflow-specific credentials that are automatically managed and cannot be extracted.
207+
208+
### Handling private dependencies
209+
210+
While trusted publishing handles the publish operation, you may still need authentication for installing private npm dependencies. For this scenario, we recommend:
211+
212+
```yaml
213+
# GitHub Actions example
214+
- uses: actions/setup-node@v4
215+
with:
216+
node-version: '20'
217+
registry-url: 'https://registry.npmjs.org'
218+
219+
# Ensure npm 11.5.0 or later for trusted publishing
220+
- run: npm install -g npm@latest
221+
222+
# Use a read-only token for installing dependencies
223+
- run: npm ci
224+
env:
225+
NODE_AUTH_TOKEN: ${{ secrets.NPM_READ_TOKEN }}
226+
227+
# Publish uses OIDC - no token needed
228+
- run: npm publish
229+
```
230+
231+
Always use [read-only granular access tokens](/integrations/integrating-npm-with-external-services/creating-and-viewing-access-tokens#creating-granular-access-tokens-on-the-website) for installing dependencies. This limits potential damage if the token is ever compromised.
232+
233+
### Additional security measures
234+
235+
Consider implementing these additional security practices:
236+
237+
- Use [deployment environments](https://docs.github.com/en/actions/deployment/targeting-different-environments/using-environments-for-deployment) to add approval requirements
238+
- Enable [tag protection rules](https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/managing-repository-settings/configuring-tag-protection-rules) to control who can create release tags
239+
- Regularly audit your trusted publisher configurations
240+
- Remove any unused publish tokens from your npm account
241+
242+
## Troubleshooting
243+
244+
If you encounter an "Unable to authenticate" error when publishing, first verify that the workflow filename matches exactly what you configured on [npmjs.com](https://npmjs.com), including the `.yml` extension. The filename is case-sensitive and must be exact. Also ensure you're using GitHub-hosted runners or GitLab.com shared runners, as self-hosted runners are not currently supported. For GitHub Actions specifically, check that the `id-token: write` permission is set in your workflow.
245+
246+
<Note>
247+
248+
**Note:** npm does not verify your trusted publisher configuration when you save it. Double-check that your repository, workflow filename, and other details are correct, as errors will only appear when you attempt to publish.
249+
250+
</Note>
251+
252+
If your package has private dependencies and `npm install` or `npm ci` is failing with authentication errors, remember that trusted publishing only applies to the `npm publish` command. You'll still need to provide a read-only token for installing private packages as shown in the examples above.
253+
254+
For packages in private repositories, provenance will not be generated even though you're using trusted publishing. This is a [known limitation](https://github.blog/changelog/2023-07-25-publishing-with-npm-provenance-from-private-source-repositories-is-no-longer-supported/) that applies regardless of whether your package itself is public or private.
255+
256+
## Limitations and future improvements
257+
258+
Trusted publishing currently supports only cloud-hosted runners. Support for self-hosted runners is intended for a future release. Each package can only have one trusted publisher configured at a time, though you can update this configuration as needed.
259+
260+
OIDC authentication is currently limited to the publish operation. Other npm commands such as `install`, `view`, or `access` still require traditional authentication methods. The `npm whoami` command will not reflect OIDC authentication status since the authentication occurs only during the publish operation.
261+
262+
We intend to expand trusted publishing support to additional CI/CD providers and enhance the feature based on community feedback.
263+
264+
## Learn more
265+
266+
- [About npm provenance](./generating-provenance-statements)
267+
- [OpenSSF Trusted Publishers specification](https://repos.openssf.org/trusted-publishers-for-all-package-repositories)
268+
- [GitHub Actions OIDC documentation](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect)
269+
- [GitLab CI/CD OIDC documentation](https://docs.gitlab.com/ee/ci/cloud_services/)
149 KB
Loading
155 KB
Loading
57.2 KB
Loading

0 commit comments

Comments
 (0)