technical 9 min read

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 FoundAccess token expired or revoked、npm token 过期、GitHub Actions 发布 npm 包失败、scoped package 发布 404 等问题,可以按本文的配置和检查清单逐项排查。

核心结论

从 GitHub Actions 发布 npm 包时,推荐使用 npm Trusted Publishing,而不是把长期 NPM_TOKEN 存进 GitHub Secrets。

正确配置需要同时满足四个条件:

  1. 在 npm 包设置中添加 Trusted Publisher,并精确填写 GitHub organization/user、repository 和 workflow filename。
  2. GitHub Actions workflow 使用 GitHub-hosted runner,不能使用自托管 runner。
  3. workflow 配置 permissions: id-token: write,让 GitHub Actions 可以签发 OIDC 身份令牌。
  4. 使用支持 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 userRepositoryWorkflow 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 供应链证明。

完整发布流程

完成配置后,按下面流程发布:

  1. 在 npm 包 Settings 中添加并保存 Trusted Publisher。
  2. 提交并推送 .github/workflows/publish.yml
git add .github/workflows/publish.yml package.json git commit -m "chore: configure npm trusted publishing" git push
  1. 确认 package.json 的版本号尚未发布过。
  2. 打 tag 触发发布:
git tag v1.2.2 git push origin v1.2.2
  1. 等待 GitHub Actions 中的 Publish Package job 完成。
  2. 验证 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.jsonrepository.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 风险,并让包的发布来源更可追溯。

参考链接

我们使用 Cookie

我们使用 Cookie 来提升您的浏览体验、分析网站流量和个性化内容。点击"接受"即表示您同意我们使用 Cookie。 了解更多