npm / GitHub Actions のサプライチェーン対策チェックリスト(使う側・公開する側)
azu さんのメモ(2025-09 公開、2026-04 に「もうデフォルトでやるべき水準」と追記)を、使う側・公開する側に分けて実行できるチェック項目にした。個別の手順は既存記事にリンク。
使う側
- [ ] ロックファイルをコミットし、CI は
npm ci/pnpm install --frozen-lockfileで入れる。 - [ ] GitHub Actions は SHA 固定(GitHub Actions: pinact で uses: をコミット SHA に固定する)。リポジトリ設定の「Require actions to be pinned to a full-length commit SHA」も有効にする。Renovate / Dependabot は
@<sha> # v5.0.0形式のまま更新してくれる。 - [ ] workflow の
permissionsを最小に(例:contents: readのみ)。zizmor や ghalint で付け忘れを検出できる。 - [ ] install スクリプトを既定で止める(npm/pnpm/bun/deno: 依存パッケージの install スクリプトを既定で止める)。pnpm 10 は既定でブロックし、必要なものだけ
pnpm approve-buildsで許可。 - [ ] 公開直後のバージョンを入れない(npm/pnpm: minimum-release-age でサプライチェーン攻撃を避けつつ、緊急パッチだけ一時的に解除する)。更新 PR は Renovate の
minimumReleaseAge/ Dependabot のcooldownで 7 日ほど待つ。pnpm のminimumReleaseAgeはインストール全体に効くので 1 日程度が現実的。 - [ ] Dependabot の PR は
@dependabot mergeコメントでマージする。偽の Dependabot PR なら権限がなくマージできないので見分けられる。lockfile の改ざんは lockfile-lint でも検出できる。 - [ ]
npxはバージョン指定(npx [email protected])。繰り返し使うものは devDependencies に入れてロックする。Socket のsocket npxや 開発環境: DataDog Supply Chain Firewall (scfw) で npm / PyPI の危険パッケージ導入を止める のようなラッパーで事前スキャンするのも手。 - [ ] エージェントや怪しいツールはサンドボックスで動かす(macOS の
sandbox-exec、Dev Containers など)。
公開する側
- [ ] secretlint をコミット時に通す。private リポジトリでも秘密情報は入れない(漏れたら Git/GitHub: 秘密情報を push してしまったら、最初にやるのは「無効化」。rebase+force push だけでは足りない)。
- [ ] ローカルに生のトークンを置かない。
.envや~/.configに平文で置かず、1Password のopなどで実行時に取得する(Infostealer 対策)。 - [ ] トークンは最小スコープ(npm は Granular access token、GitHub は Fine-grained PAT / GitHub App)。そもそも発行しないのが一番。
- [ ] workflow を変える PR はセキュリティチェックしてからマージ。
run: echo "${{ github.event.issue.title }}"のような式展開はスクリプトインジェクションになる。zizmor / actionlint で検出。GitHub Actions: pull_request_target で PR のコードを checkout してビルドしない も参照。 - [ ] npm Trusted Publishing(OIDC)で CI から公開し、publish 用トークンを持たない。来歴は GitHub Actions: actions/attest で成果物に provenance 証明書を付け、SLSA Level 3 に近づける でも付けられる。
- [ ] パッケージ設定で「Require two-factor authentication and disallow tokens」を有効化。トークンだけでは publish できなくなり、盗んだトークンで自動 publish して広がるタイプのワームを止められる。
- [ ] MFA はセキュリティキー / パスキー(SMS・TOTP はフィッシングに弱い)。
- [ ] 公開物は npm: package.json の files を必ず設定し、npm pack --dry-run で公開内容を確かめる で絞る。
追記(2026-10-14): npm の Granular Access Token は 2FA を回避できなくなる
azu さんの 2026-07-12 の投稿によると、npm の予定は次のとおり(投稿時点の告知)。
- 2026年8月から: 2FA を回避する設定の Granular Access Token でも、アカウントやパッケージの管理操作では 2FA を省略できなくなる。
- 2027年1月ごろから: トークンで直接 publish できなくなり、Trusted Publishing(CI の OIDC で公開)か Staged Publishing のどちらかでないと公開できなくなる。
やること: CI でトークンを使って npm publish しているパッケージは、上の「Trusted Publishing で CI から公開」へ早めに移す。npm 側の最新の告知で日付を確認しておく。
- 出典: @azu_re 2026-07-12: @azu_re · 2026-07-12
全体像(多層防御)
ロック → 事前スキャン → インストール時の制限 → 更新の待機 → 署名・checksum・lockfile 整合性の検証、の順に重ねる。
出典
- @azu_re 2026-04-04: @azu_re · 2026-04-04
- 元記事(Zenn): zenn.dev