npm Trusted Publishing 配置教程:GitHub Actions 发布 npm 包不再需要 NPM_TOKEN
一份可直接落地的 npm Trusted Publishing 配置教程,介绍如何用 GitHub Actions、OIDC 和 npm provenance 替代长期保存的 NPM_TOKEN。
本文是一份可直接落地的 npm Trusted Publishing 配置教程,介绍如何用 GitHub Actions、OpenID Connect (OIDC) 和 npm provenance 安全发布 npm 包,替代长期保存的 NPM_TOKEN。
如果你遇到 npm publish E404 Not Found、Access token expired or revoked、npm token 过期、GitHub Actions 发布 npm 包失败、scoped package 发布 404 等问题,可以按本文的配置和检查清单逐项排查。
核心结论
从 GitHub Actions 发布 npm 包时,推荐使用 npm Trusted Publishing,而不是把长期 NPM_TOKEN 存进 GitHub Secrets。
正确配置需要同时满足四个条件:
- 在 npm 包设置中添加 Trusted Publisher,并精确填写 GitHub organization/user、repository 和 workflow filename。
- GitHub Actions workflow 使用 GitHub-hosted runner,不能使用自托管 runner。
- workflow 配置
permissions: id-token: write,让 GitHub Actions 可以签发 OIDC 身份令牌。 - 使用支持 OIDC 发布流程的新版 Node/npm,推荐 Node 24 + npm latest。
本文基于 n2n-memory 从 token 发布迁移到 Trusted Publishing 的真实排错经历整理而成。文中的技术配置已经验证可用。
适用场景
如果你正在排查下面任意问题,本文的方案适用:
- npm Trusted Publishing 怎么配置
- GitHub Actions 如何发布 npm 包
- 如何不用
NPM_TOKEN发布 npm package - npm OIDC publishing 配置步骤
npm publish E404 Not Found - PUT怎么解决Access token expired or revoked怎么解决- npm token 过期后 GitHub Actions 发布失败
- npm provenance 怎么开启
- scoped package 发布时报 404
npm publish --access public什么时候需要
为什么应该用 Trusted Publishing 替代 NPM_TOKEN
传统发布方案是在 GitHub 仓库 Secret 中保存 NPM_TOKEN,然后在 CI 里设置 NODE_AUTH_TOKEN 执行 npm publish。这个方案能工作,但长期维护成本和安全风险都比较高:
- Token 会过期、被撤销或需要人工轮换。
- Token 一旦泄露,风险范围难以控制。
- 开启 2FA 后,自动发布还需要额外处理 bypass 或 automation token。
- 多仓库、多包维护时,Secret 管理容易混乱。
Trusted Publishing 的思路不同:npm 不再依赖长期 token,而是信任某个 GitHub 仓库中的特定 workflow。当这个 workflow 执行 npm publish 时,GitHub Actions 通过 OIDC 提供短期身份凭证,npm 验证 workflow 身份后允许发布,并自动生成 provenance 供应链证明。
一句话理解:Trusted Publishing 让 npm 信任“哪个 GitHub workflow 正在发布”,而不是信任一个长期保存的 token。
npm 端配置:添加 Trusted Publisher
打开 npm 包的权限页面:
https://www.npmjs.com/package/<package-name>/access
例如:
https://www.npmjs.com/package/n2n-memory/access
进入 Settings,找到 Trusted Publishers,选择 GitHub Actions,按如下方式填写:
| 字段 | 填写内容 |
|---|---|
| Organization or user | n2ns,即 GitHub 账号或组织名 |
| Repository | n2n-memory,即 GitHub 仓库名 |
| Workflow filename | publish.yml,只填写文件名 |
| Environment name | 留空,除非你使用 GitHub Environment |
注意事项:
Workflow filename只填文件名本身,例如publish.yml。- 不要填写完整路径
.github/workflows/publish.yml。 Organization or user、Repository、Workflow filename都必须与 GitHub 上的实际值完全一致。- 这些字段大小写敏感。
- 填写完成后必须点击 Save changes,否则配置不会生效。
GitHub Actions workflow 推荐配置
下面是一个经过验证、可直接使用的 .github/workflows/publish.yml:
name: Publish Package
on:
push:
tags:
- 'v*'
workflow_dispatch:
permissions:
id-token: write
contents: read
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '24'
registry-url: 'https://registry.npmjs.org'
- name: Upgrade npm
run: npm install -g npm@latest
- run: npm ci
- run: npm run check
- run: npm publish --access public
关键点说明:
permissions: id-token: write是 OIDC 发布的必要权限。runs-on: ubuntu-latest使用 GitHub-hosted runner。npm Trusted Publishing 不支持自托管 runner。node-version: '24'可以避免旧版 npm CLI 对 Trusted Publishing OIDC 流程支持不完整的问题。npm install -g npm@latest确保 npm CLI 版本满足发布要求。registry-url必须显式指定为https://registry.npmjs.org。- scoped public 包建议显式执行:
npm publish --access public
否则可能被当作私有包处理。
- 不要给
npm publish设置NODE_AUTH_TOKEN,否则 npm CLI 可能走旧 token 认证路径,而不是 OIDC Trusted Publishing。
package.json 推荐配置
建议在 package.json 中包含真实仓库地址和公开发布配置:
{
"name": "n2n-memory",
"version": "1.2.2",
"repository": {
"type": "git",
"url": "git+https://github.com/n2ns/n2n-memory.git"
},
"publishConfig": {
"access": "public",
"provenance": true
}
}
说明:
repository.url必须指向真实 GitHub 仓库。- npm provenance 会校验发布来源,仓库信息不匹配可能导致发布失败或 provenance 信息异常。
- scoped 包默认可能按私有包处理,公开包应保留
publishConfig.access: "public"。 publishConfig.provenance: true可以明确开启 npm provenance 供应链证明。
完整发布流程
完成配置后,按下面流程发布:
- 在 npm 包 Settings 中添加并保存 Trusted Publisher。
- 提交并推送
.github/workflows/publish.yml:
git add .github/workflows/publish.yml package.json
git commit -m "chore: configure npm trusted publishing"
git push
- 确认
package.json的版本号尚未发布过。 - 打 tag 触发发布:
git tag v1.2.2
git push origin v1.2.2
- 等待 GitHub Actions 中的
Publish Packagejob 完成。 - 验证 npm 发布结果:
npm view n2n-memory dist-tags.latest
npm view n2n-memory versions --json
如果 dist-tags.latest 已更新到新版本,说明发布成功。
常见错误排查
npm publish E404 Not Found 是什么原因?
典型错误如下:
npm error code E404
npm error 404 Not Found - PUT https://registry.npmjs.org/@scope%2fpackage - Not found
npm error 404 '@scope/[email protected]' is not in this registry.
这通常不是“包真的不存在”,而是 npm publish 没有拿到正确发布权限,或 Trusted Publisher 信任关系匹配失败。按顺序检查:
- npm Trusted Publisher 是否已经保存,是否点击了 Save changes
-
Organization or user是否与 GitHub owner 完全一致 -
Repository是否与 GitHub 仓库名完全一致 -
Workflow filename是否只填写了publish.yml,不包含路径 - workflow 文件是否实际位于
.github/workflows/publish.yml - workflow 是否使用 GitHub-hosted runner
- workflow 是否包含
permissions: id-token: write - Node 是否为 24,npm 是否升级到最新版
- scoped public 包是否使用
npm publish --access public
Access token expired or revoked 怎么解决?
如果迁移到 Trusted Publishing 后仍看到:
Access token expired or revoked
说明 npm CLI 很可能仍在走旧 token 认证路径。检查:
npm publish步骤是否设置了NODE_AUTH_TOKEN,如果有,删掉。- workflow 是否写入了带 token 的
.npmrc。 - Node/npm 版本是否过旧。
- 是否仍在使用旧的 publish action 或封装脚本注入 token。
Trusted Publishing 的目标是完全不依赖长期 npm token。配置正确后,发布 workflow 不需要 NPM_TOKEN。
为什么 npm whoami 不能验证 OIDC?
npm whoami 依赖传统认证方式,它不能证明 Trusted Publishing 的 OIDC 配置是否正确。
Trusted Publishing 的 OIDC 认证发生在 npm publish 执行时。正确验证方式是直接运行发布 workflow,并观察 npm publish 是否成功完成。
workflow_dispatch 手动触发为什么可能失败?
npm 会校验实际触发发布的 workflow 身份。推荐在同一个 publish.yml 中直接执行 npm publish,避免通过嵌套 workflow 或 reusable workflow 间接发布。
如果 npm Trusted Publisher 中登记的是 publish.yml,但实际执行发布的是另一个 workflow,npm 可能因为匹配不到可信发布者而拒绝发布。
包转移 owner 后为什么仍然发布失败?
npm 包 owner 转移只解决包权限归属,不会自动同步 Trusted Publisher 配置。转移后需要重新确认:
- 当前 npm 账号对该包有写权限。
- Trusted Publisher 指向正确 GitHub owner 和 repository。
- workflow filename 与 npm 设置完全一致。
package.json中的repository.url已更新为当前仓库。
最小检查清单
发布前逐项确认:
- npm 包已添加 Trusted Publisher 并保存
-
Workflow filename等于publish.yml,只包含文件名 - workflow 文件路径为
.github/workflows/publish.yml - workflow 包含
permissions: id-token: write - workflow 使用 GitHub-hosted runner,例如
ubuntu-latest - workflow 使用
node-version: '24' - workflow 执行
npm install -g npm@latest -
npm publish没有设置NODE_AUTH_TOKEN -
package.json的repository.url指向当前 GitHub 仓库 -
package.json包含publishConfig.access: "public" -
package.json的版本号尚未发布过
FAQ
npm Trusted Publishing 还需要 NPM_TOKEN 吗?
不需要。Trusted Publishing 的目的就是用 GitHub Actions OIDC 短期身份替代长期 NPM_TOKEN。
npm Trusted Publishing 支持自托管 runner 吗?
不支持。发布 npm 包的 workflow 需要使用 GitHub-hosted runner,例如 ubuntu-latest。
Workflow filename 应该填什么?
只填写文件名,例如 publish.yml。不要填写 .github/workflows/publish.yml。
scoped package 发布时为什么要加 --access public?
scoped 包默认可能被 npm 当作私有包处理。如果你发布的是公开 scoped package,应显式使用:
npm publish --access public
也建议在 package.json 中配置:
"publishConfig": {
"access": "public",
"provenance": true
}
Trusted Publishing 和 provenance 是一回事吗?
不是。Trusted Publishing 负责让 npm 通过 GitHub Actions OIDC 验证发布者身份;provenance 负责生成供应链来源证明。二者通常一起使用,可以减少长期 token 风险,并让包的发布来源更可追溯。