GitHubの「npm install-time security and GAT bypass2fa deprecation」は、npmを使うすべての環境に同じ対応を求める変更ではありません。対応が必要なのは、主にnpm v12で依存関係をインストールする環境と、2FA回避を有効にしたnpm Granular Access Token(GAT)を自動処理に使っている環境です。
2026年7月9日時点の公式情報では、npm v12のインストール時セキュリティはすでに有効です。一方、2FA回避GATは、2026年8月上旬からアカウント・パッケージ・組織の管理操作に使えなくなり、2027年1月頃にはパッケージの直接公開にも使えなくなる予定です。GitHub Personal Access TokenやGitHub ActionsのGITHUB_TOKENが廃止される変更ではありません。(The GitHub Blog)
GitHub「npm install-time security and GAT bypass2fa deprecation」の結論
まず、自分の環境に対応が必要かを次の表で確認してください。
| 現在の環境 | 対応要否 | 最初に行うこと |
|---|---|---|
npm 12.xでnpm installまたはnpm ciを実行している | 必要 | 未承認スクリプトとGit・リモートURL依存を確認する |
CIでnpm@latestや更新されるコンテナイメージを使っている | 必要 | npmの実行バージョンを固定し、npm v12でクリーンインストールを試す |
| npm 11.16.0以上を使っている | 準備推奨 | 警告を確認し、allowScriptsの許可リストを作成する |
| 2FA回避GATでアカウントやパッケージ設定を変更している | 至急 | 2026年8月上旬までに対話型2FAへ切り替える |
2FA回避GATでnpm publishを自動実行している | 必要 | 2027年1月頃までにOIDCまたはStaged publishingへ移行する |
GitHub PAT、GitHub App Token、GITHUB_TOKENだけを使っている | GAT変更は対象外 | npmのバージョン変更だけを確認する |
| 読み取り専用GATでプライベートパッケージを取得している | 直接公開の変更は原則対象外 | 読み取り専用・最小権限になっているか確認する |
GATの変更対象は、npmのGranular Access Tokenのうち、書き込み権限があり「Bypass two-factor authentication」を有効にしたトークンです。名称に「GitHub」が付くトークンを一律に置き換える必要はありません。(npm ドキュメント)
変更内容と期限を時系列で整理
公式発表で示された変更時期は次のとおりです。2026年8月上旬と2027年1月頃は、特定の日付が確定した期限ではなく、現時点での導入予定です。(The GitHub Blog)
| 時期 | 変更内容 | 主な影響 |
|---|---|---|
| npm v12への更新時点 | 依存パッケージのインストールスクリプトが初期状態で無効 | ネイティブモジュールのビルド、バイナリのダウンロード、セットアップ処理が実行されない可能性がある |
| npm v12への更新時点 | allow-gitの初期値がnone | 直接・間接のGit依存を取得できなくなる |
| npm v12への更新時点 | allow-remoteの初期値がnone | URLで直接指定されたtarballなどを取得できなくなる |
| 2026年8月上旬予定 | 2FA回避GATによる重要な管理操作を停止 | トークン作成、パスワード変更、メンテナー変更、組織管理などに対話型2FAが必要 |
| 2027年1月頃予定 | 2FA回避GATによる直接公開を停止 | GATを使った無人のnpm publishが失敗する |
| 2027年1月頃以降 | 2FA回避GATの用途を縮小 | プライベートパッケージの読み取りと公開のステージングは残る予定 |
npm install-time securityには、カレンダー上の猶予期限がありません。CIや開発端末でnpm v12が実行された時点で挙動が変わるため、npm@latestや更新されるビルドイメージを使っている環境では、意図しないタイミングで影響が出る可能性があります。
npm install-time securityで変わった3つのデフォルト
依存パッケージのインストールスクリプトが自動実行されない
npm v12では、依存パッケージ側の次のライフサイクルスクリプトが、明示的に許可されていない限り実行されません。
preinstallinstallpostinstall- Git、file、link依存などに含まれる
prepare binding.gypがあるパッケージに対してnpmが暗黙的に実行するnode-gyp rebuild
影響を受けやすいのは、インストール中にネイティブコードをビルドするパッケージや、ブラウザ・実行ファイルをダウンロードするツールです。公式の移行案内では、sharp、better-sqlite3、canvas、bcrypt、Cypress、Playwright、Puppeteer、Electron、Huskyなどが例として挙げられています。(The GitHub Blog)
特に注意したいのは、npm v12の標準動作では、未承認スクリプトがあってもインストール自体は成功する場合があることです。スクリプトはスキップされ、警告が表示されますが、問題がビルド時や実行時まで表面化しない可能性があります。
例えば、次のような状態です。
npm ciは成功したが、ネイティブアドオンを読み込めない- Playwrightのブラウザが取得されず、E2Eテストだけ失敗する
- Electronのバイナリが存在せず、起動時にエラーになる
- Huskyのセットアップが実行されず、Gitフックが有効にならない
未承認スクリプトがあればインストールを失敗させたい場合は、strict-allow-scriptsを有効にします。これはnpm v12の標準設定ではないため、CIでは明示的に指定するのが安全です。(GitHub)
Gitリポジトリを参照する依存関係が取得されない
npm v12では、allow-gitの初期値がnoneです。package.jsonや推移的依存関係に次のような指定がある場合、明示的な許可が必要です。
{
"dependencies": {
"example-package": "git+https://github.com/example/example-package.git"
}
}
設定値には次の選択肢があります。
| 値 | 動作 |
|---|---|
none | Git依存を取得しない。npm v12の初期値 |
root | ルートのpackage.jsonに直接記載されたGit依存だけを許可 |
all | 推移的依存を含むすべてのGit依存を許可 |
直接依存だけがGitリポジトリを参照している場合は、原則としてallではなくrootを検討します。allを指定すると、依存ツリーの深い位置に追加されたGit依存も許可されるためです。(GitHub)
リモートURLの依存関係が取得されない
allow-remoteもnpm v12ではnoneが初期値です。これは、レジストリ上のバージョンではなく、HTTPSなどのURLでtarballを直接参照する依存関係を制限します。
{
"dependencies": {
"example-package": "https://example.com/packages/example-package.tgz"
}
}
allow-remoteにもnone、root、allがあります。直接参照だけを許可する場合は、次のように.npmrcへ設定できます。
allow-git=root
allow-remote=root
package-lock.jsonのresolvedにnpmレジストリのHTTPS URLが書かれているだけで、リモートURL依存と判断してはいけません。npmレジストリから通常取得するtarballは、この制限の対象となる直接URL依存とは扱いが異なります。package.jsonの指定方法と、npm v12でクリーンインストールした際の警告を合わせて確認してください。(npm ドキュメント)
なお、allow-fileとallow-directoryの初期値は、npm v12では変更されていません。(The GitHub Blog)
npm v12の影響を受けやすい環境
CI/CDとコンテナビルド
GitHub Actions、Docker、デプロイサービスなどで毎回npm ciを実行する環境は、影響を最も発見しやすい一方、キャッシュによって問題が隠れることがあります。
検証時は、少なくとも次を実施してください。
node_modulesを再利用しない- npmやパッケージマネージャーのキャッシュを一度無効化する
- ロックファイルからクリーンインストールする
- ビルド、単体テスト、E2Eテストまで実行する
- npmの警告をCIログに残す
ネイティブモジュールを使うアプリケーション
node-gypや事前ビルド済みバイナリを使うパッケージは、package.jsonに明示的なinstallスクリプトがなくても影響を受けることがあります。binding.gypが存在すると、npmが暗黙的にビルド処理を実行するためです。(The GitHub Blog)
npmパッケージの公開者
自分が公開しているパッケージがインストールスクリプトに依存している場合、利用者がnpm v12へ移行するとセットアップが実行されなくなる可能性があります。
パッケージ公開者は、次の対策を検討します。
- READMEに必要な承認操作を記載する
- インストール後に利用者が明示的に実行するコマンドへ分離する
- 可能であれば事前ビルド済みバイナリを配布する
- インストール時のネットワークアクセスを減らす
- スクリプトが実行されなくても、理解しやすいエラーを表示する
GitHubの公式案内でも、インストールスクリプトへの依存を減らし、明示的なセットアップコマンドや事前ビルド済み成果物へ移行することが推奨されています。(GitHub)
グローバルインストールとnpx
npm approve-scriptsとnpm deny-scriptsは、package.jsonがあるプロジェクト内で使うコマンドです。グローバルインストールやnpxでは、コマンドラインの--allow-scriptsまたはユーザー設定を使います。
npm install -g --allow-scripts=trusted-package target-package
継続的に許可する場合は、次のように設定できます。
npm config set allow-scripts=trusted-package --location=user
プロジェクト内のnpm installやnpm ciに--allow-scriptsを直接付ける使い方は想定されていません。プロジェクトでは、package.jsonのallowScriptsを管理してください。(npm ドキュメント)
モノレポとWorkspaces
npm approve-scriptsとnpm deny-scriptsは、公式ドキュメント上ではWorkspacesを認識しないコマンドとされています。複数のpackage.jsonを持つ構成では、ルートだけを確認して完了と判断せず、各プロジェクト境界と実際のインストール起点を確認してください。(npm ドキュメント)
npm install-time securityへの移行手順
Node.jsとnpmのバージョンを確認する
最初に、開発端末とCIの両方で実行バージョンを記録します。
node --version
npm --version
npm 11.16.0以上では、npm v12へ移行する前に未確認のインストールスクリプトを警告として確認できます。
npm 12.0.0が対応するNode.jsは、公式リリース情報上では次の範囲です。
^22.22.2 || ^24.15.0 || >=26.0.0
古いNode.js環境でnpmだけをv12へ更新すると、インストール時セキュリティを確認する前にバージョン要件で実行できなくなる可能性があります。Node.jsとnpmはセットで検証してください。(GitHub)
未確認のインストールスクリプトを一覧化する
既存プロジェクトでは、まず通常のインストールを行い、未確認のスクリプトを一覧表示します。
npm install
npm approve-scripts --allow-scripts-pending
--allow-scripts-pendingは確認用であり、許可リストを変更しません。各パッケージについて、次の基準で判断します。
- ビルドや実行にスクリプトが本当に必要か
- スクリプトがネットワークからファイルを取得していないか
- 実行されるコードとパッケージの配布元を確認できるか
- バージョン更新後も自動的に許可してよいか
- 明示的なセットアップコマンドに置き換えられないか
許可するパッケージは、次のように登録します。
npm approve-scripts package-name
実行させないパッケージは、明示的に拒否できます。
npm deny-scripts package-name
結果はpackage.jsonのallowScriptsに書き込まれるため、チームで共有するにはリポジトリへコミットします。
git add package.json
git commit -m "chore: define npm install-script policy"
標準では、承認したパッケージはインストール済みバージョンに固定されます。--no-allow-scripts-pinを使うと将来のバージョンも名前だけで許可できますが、更新後のスクリプトまで自動承認することになるため、通常はバージョン固定を維持する方が安全です。(GitHub)
既存ツリーを一括承認するnpm approve-scripts --allも用意されています。ただし、ロックファイルが固定され、現在の依存ツリーを信頼できることを確認してから使ってください。一括承認後も、不要なスクリプトはnpm deny-scriptsで絞り込む必要があります。
許可後にクリーンインストールする
npm v12で一度スクリプトがスキップされた後に許可した場合は、クリーンインストールするか、対象パッケージを再構築します。
npm rebuild package-name
CIでは、許可リストをコミットした後に次のような検証を行います。
npm ci --strict-allow-scripts
npm run build --if-present
npm test
strict-allow-scriptsを使うと、未確認スクリプトを警告だけで見逃さず、CIを失敗させられます。新しい依存パッケージが追加された際に、レビューなしでインストールスクリプトがスキップされる事故も検出しやすくなります。(npm ドキュメント)
ignore-scripts=trueを使っている場合
.npmrcや環境変数でignore-scripts=trueを設定している場合、allowScriptsよりもignore-scriptsが優先されます。許可リストを作っても、ignore-scriptsが残っている間はスクリプトが実行されません。
移行時は、次の順序が安全です。
ignore-scripts=trueを維持したまま未確認パッケージを一覧化する- 必要なパッケージだけを承認する
- クリーンな検証環境で動作を確認する
- ポリシーを切り替える場合のみ
ignore-scriptsを削除する
dangerously-allow-all-scriptsは許可ポリシーを全面的に回避する移行用の逃げ道です。恒久的なCI設定として使うと今回のセキュリティ強化を無効化するため、常用すべきではありません。(npm ドキュメント)
GAT bypass 2FAの廃止対象と期限
今回縮小されるのは、npmのGranular Access Tokenのうち、2FA回避を有効にしたトークンです。GAT自体が2026年8月にすべて廃止されるわけではありません。
2026年8月上旬からできなくなる操作
2FA回避GATでは、次のような重要操作が実行できなくなる予定です。
- トークンの作成・削除
- リカバリーコードの生成
- パスワード、メールアドレス、プロフィールの変更
- 2FA設定の変更
- パッケージのアクセス設定変更
- メンテナーの追加・削除
- Trusted publishing設定の変更
- 組織やチームのメンバー管理
- チームへのパッケージ権限付与
これらの操作は、WebまたはCLIから人間が操作し、2FA認証を完了する方式へ切り替える必要があります。(The GitHub Blog)
2027年1月頃から直接公開できなくなる
次のような自動公開は、移行しなければ失敗する可能性があります。
- run: npm publish
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
ここでNPM_TOKENが、書き込み権限と2FA回避を持つGATであれば対象です。
変更後も、2FA回避GATには次の用途が残る予定です。
- プライベートパッケージの読み取り
npm stage publishによる公開候補のステージング
ただし、GitHubは長期的には2FA回避GATを削除し、Trusted publishingまたはStaged publishingへ移行することを推奨しています。(GitHub)
自分の環境で2FA回避GATを使っているか確認する方法
npmのアクセストークンを棚卸しする
npmのWebサイトで、プロフィールメニューから「Access Tokens」を開きます。各トークンについて、少なくとも次を確認してください。
- Bypass two-factor authenticationの有無
- Read-onlyかRead and writeか
- 対象パッケージとスコープ
- 対象組織
- 有効期限
- IPアドレス制限
- 実際に利用しているワークフロー
CLIからトークンを一覧化する場合は、次のコマンドを使えます。
npm token list
CLIの一覧では表示される属性が限定されるため、2FA回避設定や詳細な権限はWeb画面と併せて確認してください。(npm ドキュメント)
GitHub Actions内の利用箇所を確認する
リポジトリ、Environment、OrganizationのSecretsを確認し、ワークフロー内で次のような名前が参照されていないか検索します。
NPM_TOKEN
NODE_AUTH_TOKEN
NPM_AUTH_TOKEN
ただし、Secret名だけでは権限や2FA回避の有無は分かりません。次のように用途まで分類してください。
| 利用目的 | 移行判断 |
|---|---|
npm ciでプライベートパッケージを取得 | 読み取り専用GATに分離する |
npm publishを実行 | OIDCまたはStaged publishingへ移行する |
| パッケージのメンテナーやアクセス権を変更 | 対話型2FAへ移行する |
| 組織やチームを管理 | 対話型2FAへ移行する |
| 用途が分からない | Secretの利用元と所有者を特定するまで削除しない |
2FA回避GATの代替手段を比較
主な移行先は、Trusted publishing、Staged publishing、対話型の手動公開です。(npm ドキュメント)
| 方法 | 自動化 | 人による2FA | 適した環境 | 主な制約 |
|---|---|---|---|---|
| Trusted publishingで直接公開 | 可能 | 公開ごとには不要 | GitHub-hosted runnerで自動公開したい | OIDC設定が必要。現時点では1パッケージにつき1設定 |
| Trusted publishingでステージのみ | ステージまで可能 | 最終承認で必要 | 自動ビルドと人の承認を両立したい | 承認操作が追加される |
| 2FA回避なしGATでステージ | ステージまで可能 | 最終承認で必要 | OIDC非対応のCIやセルフホスト環境 | 長期トークンの保管が必要 |
手動のnpm publish | 原則手動 | 公開時に必要 | 公開頻度が低い、小規模な運用 | 無人公開には向かない |
GitHub Actionsを利用しているなら、第一候補はOIDCによるTrusted publishingです。長期間有効な公開トークンをSecretsに保存せず、ワークフロー実行時だけ有効な短期認証情報を利用できます。
セルフホストランナーは、2026年7月時点ではTrusted publishingの対応対象ではありません。今後の対応予定は示されていますが、導入日が確定していない機能を前提に移行期限を決めるべきではありません。(npm ドキュメント)
GitHub ActionsをTrusted publishingへ移行する手順
npm側でTrusted Publisherを登録する
npmの対象パッケージ設定で「Trusted Publisher」を開き、GitHub Actionsを選択します。
登録時には次の情報が必要です。
- GitHubのOrganization名またはユーザー名
- リポジトリ名
- ワークフローファイル名
- GitHub Environment名
- 許可する操作
ワークフロー名はフルパスではなく、publish.ymlのようなファイル名だけを登録します。拡張子を含め、大文字と小文字も一致させてください。
許可する操作は、次のいずれかです。
npm publishnpm stage publish- 両方
人の承認を必須にしたい場合は、npm stage publishだけを許可する構成が適しています。(npm ドキュメント)
GitHub ActionsへOIDC権限を追加する
基本的なワークフローは次のようになります。
name: Publish package
on:
push:
tags:
- "v*"
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 ci
- run: npm run build --if-present
- run: npm test
- run: npm publish
重要なのはid-token: writeです。この権限がないと、GitHub Actionsがnpm向けのOIDCトークンを取得できません。Trusted publishingにはnpm CLI 11.5.1以上とNode.js 22.14.0以上が必要です。npm v12を同時に使用する場合は、npm v12側のNode.js要件も満たす必要があります。(npm ドキュメント)
プライベート依存用のトークンは分離する
Trusted publishingが置き換えるのは、npm publishまたはnpm stage publishの認証です。プライベートパッケージをnpm ciで取得する認証までは置き換えません。
プライベート依存がある場合は、読み取り専用GATをインストール処理だけに渡します。
- run: npm ci
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_READ_TOKEN }}
- run: npm publish
公開処理にはNPM_READ_TOKENを渡さず、OIDCを使わせることがポイントです。読み取り専用GATでは、Bypass 2FAを有効にする必要はありません。(npm ドキュメント)
移行テストで確認する項目
Trusted publishingは、npm側で設定を保存した時点では構成内容が検証されません。誤りは実際の公開時に判明します。
特に次を確認してください。
- GitHub-hosted runnerを使用している
id-token: writeが設定されている- npmに登録したワークフローファイル名が完全一致している
package.jsonのrepository.urlが対象GitHubリポジトリと一致している- npm CLIとNode.jsのバージョン要件を満たしている
- 再利用ワークフローでは親・子双方に必要なOIDC権限がある
- プライベート依存用の読み取りトークンが公開ステップへ渡っていない
npm whoamiはOIDC認証の成功確認には使えません。OIDC認証は公開またはステージ操作の実行時に行われるためです。旧トークンを削除する前に、実際のリリース経路で検証してください。(npm ドキュメント)
移行成功後に旧トークンを無効化する
安全な順序は次のとおりです。
- Trusted Publisherを登録する
- GitHub ActionsのOIDC公開を成功させる
- パッケージ設定で「Require two-factor authentication and disallow tokens」を有効にする
- 不要になった公開用GATを失効させる
- GitHub Secretsから旧トークンを削除する
先にGATを失効させると、OIDC設定に誤りがあった場合に公開手段を失います。公式ドキュメントでも、Trusted publishingを検証してからトークン制限と失効を行う順序が推奨されています。(npm ドキュメント)
Staged publishingへ移行する手順
Staged publishingでは、CIがパッケージを非公開のステージ領域へ送信し、メンテナーが内容を確認して2FAで承認した後に公開します。
利用条件は次のとおりです。
- npm CLI 11.15.0以上
- Node.js 22.14.0以上
- 対象パッケージへの書き込み権限
- npmアカウントで2FAが有効
- 対象パッケージがすでにnpmレジストリに存在する
新規パッケージの初回公開にはStaged publishingを利用できません。(npm ドキュメント)
CIまたはローカル環境で、次のコマンドを実行します。
npm stage publish
ステージ済みパッケージは、次のコマンドで確認できます。
npm stage list
npm stage view stage-id
npm stage download stage-id
内容に問題がなければ、メンテナーが2FAを使って承認します。
npm stage approve stage-id
npm stage publishには2FAが不要ですが、npm stage approveには2FAが必要です。GitHub ActionsのTrusted Publisherにnpm stage publishだけを許可すれば、長期トークンを保管せず、公開前に人の確認を必須にできます。(npm ドキュメント)
モノレポ向けの一括承認や、複数OIDC設定などは将来計画として案内されています。ただし、公式コミュニティ投稿では確定日が示されていません。現在利用できる機能だけで、2027年1月頃までに成立する移行計画を作る必要があります。(GitHub)
移行前に確認すべきチェックリスト
- [ ] 開発端末、CI、DockerイメージのNode.jsとnpmのバージョンを確認した
- [ ]
npm@latestなど、意図せずnpm v12へ更新される設定を特定した - [ ] npm 11.16.0以上またはnpm v12でクリーンインストールを実行した
- [ ]
npm approve-scripts --allow-scripts-pendingの結果を確認した - [ ] 必要なスクリプトだけを承認し、
package.jsonへコミットした - [ ] Git依存とリモートURL依存を直接依存・推移的依存に分けて確認した
- [ ]
allow-git=allやallow-remote=allを安易に設定していない - [ ] CIで
strict-allow-scriptsを使うか判断した - [ ] npmのAccess Tokensから2FA回避GATを洗い出した
- [ ] GitHub Secrets内のトークンについて、読み取り・公開・管理の用途を分類した
- [ ] GitHub-hosted runnerかセルフホストランナーか確認した
- [ ] Trusted Publisherのリポジトリ名とワークフロー名を照合した
- [ ] プライベート依存用トークンを読み取り専用に分離した
- [ ] OIDCまたはStaged publishingを実際の公開経路で検証した
- [ ] 移行成功後に旧GATを失効させる手順を決めた
移行で失敗しやすいポイント
npm installが成功したため問題なしと判断する
npm v12では、未承認スクリプトがスキップされても標準ではインストールが成功する場合があります。CIログの警告だけでなく、ビルド、テスト、実行確認まで行ってください。
すべてのスクリプトを恒久的に許可する
dangerously-allow-all-scriptsや無条件の一括承認を恒久設定にすると、インストール時の任意コード実行を抑える目的が失われます。現在の依存ツリーを初期登録する場合でも、後から個別の許可・拒否へ絞り込んでください。
allow-git=allでエラーだけを消す
必要なのがルートの直接依存だけなら、rootで足りる可能性があります。推移的依存まで許可するallは、依存パッケージの更新によって新しいGit取得経路が追加される点を考慮する必要があります。
OIDCへ移行した直後にすべてのnpmトークンを削除する
プライベートパッケージの取得には、引き続き読み取り用トークンが必要な場合があります。公開用トークンと取得用トークンを分離し、OIDCで置き換えられたものだけを削除してください。
セルフホストランナーでTrusted publishingを設定する
2026年7月時点では、GitHub ActionsのTrusted publishingはGitHub-hosted runnerが対象です。セルフホスト環境では、Staged publishingや対話型公開を含む別の経路を準備してください。
将来追加される機能を移行計画の前提にする
複数OIDC設定、スコープ単位の設定、一括ステージ承認、任意プロバイダー向けOIDCなどはロードマップに含まれていますが、確定した提供日はありません。2026年8月上旬と2027年1月頃の予定を基準に、現在使える機能で対応を進める必要があります。
今すぐ行うべき対応
最初に行うべきことは、開発端末とCIでnpm --versionを確認することです。npm v12を使っている、または自動更新される可能性がある場合は、クリーンインストールを行い、未承認スクリプト、Git依存、リモートURL依存を洗い出してください。
次に、npmのAccess TokensとGitHub Secretsを確認します。2FA回避GATで管理操作を自動化している場合は、2026年8月上旬までに対話型2FAへ切り替えます。npm publishに使っている場合は、2027年1月頃を待たず、GitHub ActionsのOIDCまたはStaged publishingを検証してください。
移行は、新しい認証経路を設定する、実際に動作確認する、パッケージ側でトークン公開を禁止する、旧GATを失効させるという順序で進めるのが安全です。(The GitHub Blog)

コメント