Nullstead

npm

npm Trusted Publishing実践ガイド 2026: トークン断捨離で始める安全な自動公開

npm Trusted PublishingをGitHub Actionsで導入する実践手順を解説します。OIDCによる認証の仕組み、ハマりどころ、provenance検証、移行チェックリストまでをまとめ、個人開発でも回る安全な公開パイプラインを作る方法を紹介します。

約9分

「npm publish 用のトークン、どこに置いたっけ……」という記憶がある方は、もう立派な現代開発者です。私も同じです。トークンは便利ですが、便利なものほど流出した時の破壊力が高いです。そこで今、CIからの公開を OpenID Connect(OIDC)※1 で行う Trusted Publishing が現実解になっています。

この記事では、GitHub Actions を前提に、npm Trusted Publishing の考え方、導入手順、ハマりどころ、そして検証方法までをまとめます。結論から言うと、長寿命トークンを減らせるだけでも導入価値は高いです。セキュリティ担当の胃痛も、ほんの少し和らぎます。

※1 OIDC: 認証連携の標準仕様です。CI ジョブごとに短命なトークンを払い出し、恒久的な秘密情報に依存しない構成を作れます。

なぜ今 Trusted Publishing なのか

npm の Trusted Publishing は、CI ワークフローからの公開元を「このリポジトリ、このワークフロー」という単位で信頼設定し、OIDC を使って公開を認証する仕組みです。npm 公式ドキュメントでは、長寿命トークンの管理コストや漏えいリスクを減らせる点が明確に示されています。

従来の公開フローはだいたい次のような課題を抱えます。

  • NPM_TOKEN をシークレットに保存し、ローテーションを忘れがち
  • fork や権限設定のミスで、公開可能トークンの露出面が広がる
  • チーム異動時の権限棚卸しが遅れやすい

Trusted Publishing にすると、ジョブ実行時に短命な資格情報を都度取得します。つまり「秘密を長く持たない」方向に寄せられます。これはゼロトラストの文脈でも筋が良いです。

ざっくり動作原理: 誰が、どのワークフローで公開したかを結びつける

GitHub Actions 側では id-token: write を許可し、実行中ジョブが OIDC トークンを取得します。npm はそのトークンのクレーム※2 を検証し、npmjs.com 側で事前に設定した Trusted Publisher の条件と一致した場合のみ公開を受け付けます。

※2 クレーム: JWT に含まれる属性情報です。例として repository、workflow、ref、runner_environment などがあり、どの文脈で発行されたトークンかを検証できます。

ポイントは次の3つです。

  1. 認証情報が短命で再利用しづらい
  2. 公開元をワークフローファイル単位で縛れる
  3. 監査時に「この実行が出した公開」を追跡しやすい

GitHub Docs の OIDC 解説でも、長寿命シークレットを減らし、ジョブ単位の短命トークンでアクセスする設計が推奨されています。npm 側の Trusted Publishing は、これを公開パイプラインに適用した形です。

導入手順(GitHub Actions + npm)

ここから実務向けの最短手順です。まず npmjs.com の対象パッケージ設定画面で Trusted Publisher を追加します。入力するのは主に以下です。

  • Organization or user
  • Repository
  • Workflow filename(例: publish.yml)
  • 必要なら Environment name

次に GitHub Actions を設定します。最小構成は次の通りです。

name: Publish Package
on:
  push:
    tags:
      - "v*"

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"
      - run: npm ci
      - run: npm test --if-present
      - run: npm publish

Trusted Publishing では npm CLI が OIDC 環境を検出して認証を行います。npm 公式情報では、利用要件として npm CLI 11.5.1 以上、Node 22.14.0 以上が示されています。古いランタイムで粘ると、地味に時間を失います。ここは素直に上げましょう。

つまずきポイントと回避策

導入そのものは短時間ですが、失敗パターンはだいたい決まっています。

1. workflow filename 不一致

npm 側に release.yml を設定したのに、実際は publish.yml で実行しているケースです。ファイル名の一致が条件なので、ここがズレると公開に失敗します。パスではなくファイル名を確認するのがコツです。

2. id-token: write を忘れる

これがないと OIDC トークンが発行できません。エラーログが親切ではないこともあるので、最初に疑うべき項目です。

3. runner 条件の違い

npm Docs ではクラウドホストランナー前提の制約があります。セルフホスト運用が前提の組織は、導入前に対応可否を確認した方が安全です。

4. 既存トークン運用との二重管理

移行直後に token 公開と OIDC 公開が混在すると、統制が曖昧になります。移行完了後は package の publishing access 設定を見直し、トークン経路を絞る運用が推奨です。

Provenance まで含めて初めて守りが固くなる

Trusted Publishing の良いところは、公開時の Provenance※3 生成が自然につながる点です。GitHub Changelog の GA 発表では、Trusted Publishing 利用時は --provenance フラグ不要で attestation が生成される運用が案内されています。

※3 Provenance: その成果物が「どこで」「何から」「どう作られたか」を示す来歴情報です。サプライチェーン防御で重要な手がかりになります。

npm Docs では以下が確認できます。

  • provenance attestation と publish attestation の2種類がある
  • Sigstore※4 と透明性ログで検証可能性を担保する
  • 利用者側は npm audit signatures で検証できる

※4 Sigstore: ソフトウェア署名を短命証明書で扱うための仕組み群です。証明書とログを組み合わせて改ざん検知をしやすくします。

実際に導入後は、利用者の視点でもチェック可能です。

# 依存関係の署名と provenance を検証
npm audit signatures

加えて npmjs.com のパッケージページで、Provenance 情報(Build Environment、Source Commit、Build File、Public Ledger)を辿れるか確認しておくと、監査資料としても強くなります。

実務向けの移行プレイブック

私がこの手の移行で意識するのは、「一気に理想へ」より「事故なく切り替える」です。おすすめは次の段取りです。

  1. まず1パッケージで検証
  2. タグ公開のみ許可する workflow に限定
  3. 失敗時ロールバック手順を README に明記
  4. 2週間ほど運用してから横展開

簡単なチェックリストを置いておくと、運用が安定します。

[ ] npmjs.com 側の Trusted Publisher 設定が本番 workflow と一致
[ ] GitHub Actions で id-token: write を設定
[ ] Node / npm バージョンが要件を満たす
[ ] 公開トリガーをタグに限定
[ ] npm audit signatures で検証可能
[ ] 従来トークン経路の縮退方針を決定

CI のセキュリティは「強い設定を一つ作る」より「壊れず続く設定を運用する」方が大事です。運用設計は地味ですが、ここが最終的に差になります。

まとめ: トークンの寿命を縮めると、チームの寿命が延びる

Trusted Publishing は、派手な新機能というより「公開作業の当たり前を安全側に寄せる」改善です。特に個人開発や小規模チームでは、セキュリティ専任がいない前提で回る設計が重要です。

  • 長寿命トークン依存を減らす
  • 公開元をワークフロー単位で固定する
  • provenance を含めて検証可能性を上げる

この3点だけでも、攻撃面と運用不安の両方を減らせます。公開は頻繁に行うほど事故確率が積み上がるので、早めに土台を固める価値があります。

「セキュリティ強化は開発速度を落とす」と思われがちですが、実際には逆です。毎回トークン周りでヒヤヒヤしないだけで、心理的スループットが上がります。人間の集中力は有限です。怖がる対象は減らしていきましょう。


参考リンク

おまけ: 既存のsemantic-release運用に組み込む場合

すでに semantic-release を使っている場合も、基本方針は同じです。大切なのは「公開するジョブだけ」に id-token: write を付与し、必要以上に権限を広げないことです。例えば test ジョブには不要ですし、lint にも不要です。権限最小化※5 は、派手さはないですが最も再現性が高い防御です。

※5 権限最小化: タスク遂行に必要な最小限の権限だけを与える設計原則です。

また、運用時にありがちなのが「CIが通ったら全部公開したい」誘惑です。気持ちは分かりますが、公開経路だけは保守的で良いです。タグベース、または保護ブランチ + 承認付きリリースのように、一本化された経路を維持した方が後から効きます。

最後に、チームへの説明は技術より心理です。「トークンをなくすため」よりも「漏えい時の影響範囲を小さくするため」と伝えると合意が早いです。セキュリティ施策は、正しさだけでなく、納得される言葉選びまで含めて実装だと思っています。

Tags #npm #GitHub Actions #OIDC #Supply Chain Security #Automation