
发布npm包别再存长期Token:OIDC仍有三道配置门槛

GitHub Actions 发布 npm 包可以改用 OIDC 的短期凭据,无须在仓库 Secrets 中保存长期写入 Token;发布者身份、id-token: write 权限和 GitHub 托管运行器仍是三道配置门槛,npm 的 Trusted Publishing 配置说明列出了这些要求。
迁移的顺序是:先在 npm 为目标包登记准确的 GitHub 仓库与发布工作流,再让该工作流取得 OIDC 权限并执行 npm publish。发布步骤不要传入旧的写入 Token;如果安装阶段需要读取私有依赖,只给那个阶段单独提供只读凭据。
在 npm 侧登记实际发布身份
打开目标包的 Settings → Trusted publishing,选择 GitHub Actions。这里授权的是特定包与特定工作流的组合,因此应按真正发起发布的仓库填写,而不是照抄同一组织中测试或构建任务的配置。
- Organization or user:填写 GitHub 组织名或用户名。
- Repository:只填写仓库名,不加组织名前缀。
- Workflow filename:填写 .github/workflows/ 目录中的文件名,例如 publish.yml;不要填完整路径。扩展名和大小写都要与文件一致。
- Environment name:仅在发布任务使用 GitHub environment 时填写,并与任务中的环境名一致。
- Allowed actions:示例工作流直接运行 npm publish,绑定中就要允许 npm publish。npm stage publish 与管理 dist-tag 是不同操作,不能用它们的权限代替直接发布权限。
同时核对 package.json 的 repository.url,确保它指向本次运行所在的 GitHub 仓库。仓库改名、转移或改由 fork 发布后,这个字段可能仍指向旧地址;即使表单里的仓库名正确,发布也可能因此失败。npm 保存绑定时不会替你试运行身份校验,错误通常到首次发布才会显现。
新建绑定还须在两天内完成首次成功发布;成功发布会验证配置,并将其关联到仓库的不可变身份。过期的绑定需要删除后重建,现有绑定的必要字段也不能直接修改。这意味着建好绑定后应尽快运行发布任务,而不是把首次验证留到很久以后的版本发布。
给发布任务一份可执行的最小配置
GitHub 的 OIDC 权限说明要求工作流或发布任务设置 id-token: write,才能请求 OIDC JWT;这一项本身不会赋予仓库内容或其他资源的写权限。示例另设 contents: read,供 checkout 读取代码。若把 permissions 放在任务级别,必须放进实际运行 npm publish 的任务。
下面的三个列表项分别是一行 YAML,按顺序保存为 .github/workflows/publish.yml。示例采用手动触发和 GitHub 托管的 Ubuntu 运行器;仓库须已有可供 npm ci 使用的锁文件,package.json 中也须准备好待发布的版本。
- on: workflow_dispatch
- permissions: {contents: read, id-token: write}
- jobs: {publish: {runs-on: ubuntu-latest, steps: [{uses: actions/checkout@v6}, {uses: actions/setup-node@v6, with: {node-version: '24', registry-url: 'https://registry.npmjs.org', package-manager-cache: false}}, {run: 'npm install -g npm@^11.5.1'}, {run: 'npm ci'}, {run: 'npm publish'}]}}
示例显式安装符合 Trusted Publishing 要求的 npm CLI,并关闭 setup-node 的自动包管理器缓存。实际项目应在发布前加入自己的构建和测试步骤;首次发布公开的 scoped 包时,还须按包的访问设置处理公开权限。确认手动发布路径可用后,可以换成受保护的版本标签触发,但 npm 侧绑定的工作流身份仍要与实际调用链一致。
复用工作流要看调用方
如果一个工作流通过 workflow_call 调用另一个文件,由后者执行 npm publish,不能只登记包含发布命令的文件。GitHub 的 可复用工作流 OIDC 说明指出,令牌中的常规工作流属性描述调用方,job_workflow_ref 才标识被调用方;npm 对此类发布会核对调用方工作流身份。
因此要按实际调用方核对 npm 登记的工作流文件名,并让调用方与执行发布的被调用方都获得 id-token: write。跨组织或企业调用时,尤其要在调用方工作流或调用任务上明确授予该权限。若发布命令所在文件看起来完全正确,却仍出现身份不匹配,先回到发起调用的工作流核对仓库、文件名和 environment。
按失败发生的位置排查
先看失败停在 npm ci 还是 npm publish。npm ci 读取私有包失败属于安装凭据问题;npm publish 报 ENEEDAUTH 或无法认证,才应沿 OIDC 发布链检查。不要立刻生成新的写入 Token:那会绕开尚未修好的身份或权限配置。
- 确认发布任务运行在 GitHub 托管运行器上。Trusted Publishing 暂不支持 self-hosted 运行器。
- 确认实际发布任务有 id-token: write;使用可复用工作流时,同时核对调用方的权限。
- 逐项比较 npm 侧的组织或用户、仓库、工作流文件名和可选 environment,并检查 package.json 的 repository.url。
- 核对 Node、npm CLI 和 Allowed actions:工作流执行 npm publish,就必须允许直接发布;仅允许 npm stage publish 不够。
- 若绑定刚建立却始终无法验证,查看是否已超过首次成功发布期限;必要时删除旧绑定并重新创建。
清除发布任务中的旧 NODE_AUTH_TOKEN 或其他写入 Token 也有诊断价值:npm CLI 在 OIDC 不可用时可能回退使用传统 Token。留下旧凭据,即使一次发布成功,也无法据此判断迁移后的无写入 Token 路径是否真正可用。
私有依赖与来源证明的边界
Trusted Publishing 负责发布认证,不负责 npm ci 安装私有依赖。确实需要私有 npm 包时,可将只读的细粒度 Token 存为 GitHub secret,仅在 npm ci 步骤通过 NODE_AUTH_TOKEN 提供;运行 npm publish 的步骤不传这个变量。这样保留必要的读取权限,同时避免把长期写入凭据带进发布任务。
从公开仓库通过 Trusted Publishing 发布公开包时,npm 会自动生成来源证明,无须为这条路径额外添加 --provenance;私有仓库不会自动生成,即使发布的包本身是公开的。首次 OIDC 发布成功后,可撤销不再需要的旧写入 Token,并在包的 Publishing access 中按发布策略限制传统 Token 发布,关闭遗留的发布入口。
相关阅读:
相关文章
订阅我们的新闻通讯
将最新 Web3、AI 和加密货币新闻直接发送到您的邮箱。




