CIに保存したnpmトークンが漏れたとき、攻撃者が新しいパッケージ版をそのまま公開できる。そんな権限を、本当に自動化へ渡し続ける必要があるでしょうか。
GitHubは2026年9月18日、npmのgranular access tokenでRead and write(stage only)を選べるようになったと発表しました。CIはパッケージをステージング領域へ提出できますが、そのトークンによる直接公開は拒否されます。公開には保守担当者のレビューと2要素認証(2FA)が入ります。GitHub Changelog
<style> .st-summary,.st-note,.st-flow{padding:1.2rem;margin:1.5rem 0;border:1px solid #cbd8e7;border-radius:16px;background:#eef5ff;color:#162e47}.st-summary p:last-child,.st-note p:last-child{margin-bottom:0}.st-cards,.st-pipeline{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,205px),1fr));gap:12px;margin:1.5rem 0}.st-card,.st-step{padding:1.1rem;border:1px solid #cbd8e7;border-radius:14px;background:#fff;color:#162e47}.st-step strong{display:block;font-size:1.6rem;color:#12667b}.st-step.safe{background:#e8f8ef;border-color:#91cfaa}.st-step.stop{background:#fff0ec;border-color:#e4a392}.st-card h3{margin-top:0}.st-table{overflow-x:auto;margin:1.5rem 0}.st-table table{border-collapse:collapse;width:100%;min-width:650px}.st-table th,.st-table td{padding:.85rem;border:1px solid #cbd8e7;text-align:left}.st-table th{background:#e7effa;color:#162e47}.st-note{background:#fff6e6;border-left:5px solid #9a5c00}.st-flow ol{padding-left:1.3rem}.st-flow li{margin:.7rem 0} </style>① stage-onlyトークンで、CIから公開前レビューまでを自動化できます。
② 公開は2FAを使う人の承認へ分離。トークン漏えい時の直接公開リスクを下げます。
③ 書き込み権限がゼロになるわけではないため、対象パッケージと保管範囲は絞ります。
npmのstaged publishingは、npm publishで即時公開する代わりに、npm stage publishで版をステージング領域へ送る仕組みです。保守担当者は内容を確認し、CLIまたはnpmjs.comで2FAを使って明示承認します。npm公式ドキュメント
ビルド・試験・パッケージ作成
トークンでレビュー待ちへ提出
内容をレビューし2FAで承認
承認後にレジストリへ反映
stage-onlyトークンを使ってnpm publishを直接実行すると、npmが拒否します。自動化側に侵害が起きても、新しい版を即時公開する権限を持たせないことが今回の重要な変化です。
「stage only」は読み取り専用ではありません。 公式発表によると、dist-tagの移動や版の非推奨化など、ほかのパッケージ書き込み権限は残ります。通常の書き込みトークンと同じように保護し、対象パッケージを必要最小限にしてください。[残る権限の注意](https://github.blog/changelog/2026-09-18-stage-only-npm-tokens-for-safer-automation/)
最優先で検討したいのは、長期間使うnpmトークンをCIからなくせるtrusted publishing(OIDC)です。npmは、承認したワークフローと信頼関係を結び、実行ごとの短命な認証情報を使う仕組みと説明しています。npm:trusted publishing
一方、対応CIや実行環境などの事情ですぐOIDCへ移れない場合に、stage-onlyトークンは直接公開できる長期トークンより権限を狭める移行経路になります。staged publishingはOIDCと組み合わせることもできます。
| 方式 | CIの認証 | 公開前の人の承認 | 主な検討点 |
|---|---|---|---|
| 直接公開トークン | 長期トークン | 構成次第でなし | 漏えい時に直接公開され得る。 |
| stage-onlyトークン | 長期トークンだが直接公開不可 | 2FAで必要 | ほかの書き込み権限は残る。 |
| OIDC+直接公開 | ワークフロー固有の短命認証 | 公開方式による | 対応プロバイダーとワークフロー設定を確認。 |
| OIDC+staged publishing | ワークフロー固有の短命認証 | 2FAで必要 | トークン削減とレビューを両立。 |
この表は「どれが常に正解か」ではなく、認証情報の寿命と公開承認を分けて比較するための整理です。人の承認を追加すると公開までの時間や当番設計も変わるため、緊急修正版の経路も試験します。
npm Docsで確認できる主な前提は次の通りです。
11.15.0以上
22.14.0以上
npm registryに既に存在するパッケージ
publish権限と2FAが必要
新規パッケージの初回版はステージできません。また、stage-onlyトークンの作成手順と、staged publishing自体の前提を両方満たす必要があります。前提条件
次は概念を示す最小例です。本記事制作時にnpmへ提出・公開していません。実在パッケージへそのまま適用せず、ブランチ保護、環境承認、対象パッケージ、スクリプトの副作用を確認してください。
name: Stage npm package
on:
workflow_dispatch:
permissions:
contents: read
jobs:
stage:
runs-on: ubuntu-24.04
environment: npm-staging
timeout-minutes: 15
steps:
- uses: actions/checkout@v6
with:
persist-credentials: false
- uses: actions/setup-node@v7
with:
node-version: '22.14.0'
registry-url: 'https://registry.npmjs.org'
- run: npm ci
- run: npm test
- run: npm stage publish
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_STAGE_TOKEN }}
ここで指定した22.14.0は最低条件を見せるための例で、利用中ライブラリのサポート期間や組織標準に合わせて選びます。Actionのバージョン、ランナーOS、Node.js、npm CLIは別の更新対象です。必要なnpm CLI版が同梱されているかを実行時に確認し、足りなければ信頼できる方法で明示導入してください。
移行テストで本物の公開用トークンを使わないでください。 対象を限定したstage-onlyトークンと検証用パッケージを使い、`npm publish`が拒否されること、承認前は公開されないこと、2FA承認後だけ公開されることを確認します。
開発者は、ステージされたtarballをダウンロードし、想定外のファイルやビルド生成物が入っていないか確認できます。保守担当は、版番号・変更履歴・テスト結果・provenanceを承認条件として明文化します。
運用担当は、承認待ちの滞留、却下理由、緊急公開の所要時間を観測します。企業では「CI担当者がレビュー担当者も兼ねる」状態を避けるだけでなく、不在時の代替承認者と2FA復旧手順も決めます。
stage-onlyトークンは、CIで任意コードが実行される問題や、ビルド成果物の改ざんを解決するものではありません。攻撃者がステージした版を、人が十分に確認せず承認するリスクも残ります。依存Actionの固定、権限縮小、保護された環境、成果物の照合など、ほかの防御と組み合わせます。
今回の機能は既存トークンを自動変更しないオプトインです。GitHubの発表では、npmはbypass-2FAトークンによる直接公開を2027年1月に廃止する目標も示しています。これは本稿確認時点の目標であり、実施状況は移行時に公式情報を再確認してください。移行に関する発表
OIDC対応環境の拡大、staged publishingの監査情報、組織向けポリシー、承認の自動通知を注視します。まずは「長期トークンをなくせるか」、難しければ「直接公開権限だけでも外せるか」の順で検討すると、目的が明確になります。
今日の一歩は、npmへ直接公開できるトークンがどこに残っているかを棚卸しすること。 新しいトークンを追加する前に、古い強い権限を確実に撤去する計画を作りましょう。
最終確認日:2026年9月19日(日本時間)。機能・条件・日程は公式資料、ワークフロー例と移行手順は本稿の提案です。