
はじめに
こんにちは。サービス開発部の木村です。
この記事は GameWith アドベントカレンダー2025 9日目の記事です。
2025年は「Shai-Hulud」と呼ばれる大規模なサプライチェーン攻撃が発生し、人気OSSでも採用されている有名なnpmパッケージが乗っ取られる事件が発生しました。この出来事は、多くのエンジニアがnpmエコシステムの安全性やパッケージ管理のあり方を改めて考えるきっかけにもなったと感じています。
こうしたセキュリティリスクが高まる中、Node.jsのパッケージマネージャーであるpnpmは今年にリリースされたv10以降セキュリティ機能も積極的に強化しており、これまでの高速なパッケージマネージャーという立ち位置から、セキュリティ面でも優れたパッケージマネージャーに進化しています。
今回は、今年pnpmに追加された主要なセキュリティ機能を紹介します。他パッケージマネージャーからpnpmへの移行や、pnpmのアップデートを検討する機会になれば幸いです!
デフォルトでライフサイクルスクリプトの実行を禁止
pnpm v10.0.0 における最も重要な変更点の一つとして、npmパッケージのインストール時にライフサイクルスクリプトを自動実行しない仕様への変更がありました。
過去に報告されたnpm関係の脆弱性では、npmのpostinstall コマンドを悪用したケースが多く、pnpmでは開発者が意図しないタイミングで悪意あるスクリプトが実行されるのを防ぐため、デフォルトでこれらをブロックする仕様になりました。
pnpm install時にライフサイクルスクリプトを持つパッケージが含まれていると、下記のように警告が表示されます。

ignoredBuiltDependenciesでライフサイクルスクリプトの実行をしないまま警告を消す
よほど必須では無い限りライフサイクルスクリプトは実行すべきではないですが、毎回上記の警告が表示されるのが邪魔な場合は、ignoredBuiltDependenciesで警告を非表示にできます。次はpnpm-workspace.yamlに記載する例です。
# pnpm-workspace.yaml ignoredBuiltDependencies: - fsevents - sharp
onlyBuiltDependenciesでライフサイクルスクリプトの実行を許可する
開発運用上ライフサイクルスクリプトの実行を許可したい場合は、onlyBuiltDependenciesオプションで許可したいパッケージ名を明示的に指定することが可能です。
# pnpm-workspace.yaml onlyBuiltDependencies: - fsevents - esbuild
また、組織やチームで許可リストを統一したい場合は、onlyBuiltDependenciesFile オプションでJSONファイルベースでの管理も可能です。下記は一例です。
# pnpm-workspace.yaml onlyBuiltDependenciesFile: node_modules/.pnpm-config/@my-org/pnpm-trusted-deps/allow.json
// node_modules/.pnpm-config/@my-org/pnpm-trusted-deps/allow.json [ "fsevents", "esbuild" ]
minimumReleaseAgeでリリース直後のバージョンをインストールしない
pnpm v10.18.0 でminimumReleaseAgeという設定が追加されました。これはパッケージの新規バージョンが公開されてから、指定した時間が経過していない場合はインストールをブロックする機能です。
もしnpmパッケージが乗っ取られてしまった時に、コミュニティによる対応までどうしてもタイムラグは発生してしまうため、リリースから一定期間経過したバージョンのみを許容することで、攻撃の初動に巻き込まれるリスクを低減できます。
公式の設定例では minimumReleaseAge: 1440 となっており、リリースから1440分(24時間)経過していないバージョンはインストール対象から除外されます。コミュニティやメンテナーによる検知や対応が遅くなる可能性もあるので、この時間待てば安全という絶対的な数値は存在しないため、自己責任で設定しましょう。
minimumReleaseAgeでどうインストールがブロックされるのか
具体的な挙動を確認してみます。執筆時点の3日前に react のバージョン 19.2.1 がリリースされていたので、minimumReleaseAge を 5760(4日)に設定してインストールを試してみます。

まずバージョンを指定せずに pnpm add reactを実行すると、最新の 19.2.1 はリリースから4日経過の条件を満たさないため無視され、一つ前の 19.2.0 がインストールされました。
$ pnpm get minimumReleaseAge 5760 $ pnpm add react Packages: +1 + Progress: resolved 1, reused 1, downloaded 0, added 1, done dependencies: + react 19.2.0 (19.2.1 is available) Done in 219ms using pnpm v10.24.0
また、pnpm add react@19.2.1 のように条件を満たさないバージョンを明示的に指定した場合は、次のようにエラーとなりインストールが中断しました。
$ pnpm get minimumReleaseAge 5760 $ pnpm add react@19.2.1 ERR_PNPM_NO_MATCHING_VERSION No matching version found for react@19.2.1 published by Tue Dec 02 2025 18:46:31 GMT+0900 (Japan Standard Time) while fetching it from https://registry.npmjs.org/. Version 19.2.1 satisfies the specs but was released at Thu Dec 04 2025 00:28:21 GMT+0900 (Japan Standard Time) This error happened while installing a direct dependency of /Users/username/projects/pnpm-test The latest release of react is "19.2.1". Published at 12/4/2025 Other releases are: * beta: 19.0.0-beta-26f2496093-20240514 published at 5/15/2024 * rc: 19.0.0-rc.1 published at 11/15/2024 * experimental: 0.0.0-experimental-378973b3-20251205 published at 12/5/2025 * next: 19.3.0-canary-378973b3-20251205 published at 12/5/2025 * canary: 19.3.0-canary-378973b3-20251205 published at 12/5/2025 If you need the full list of all 2629 published versions run "$ pnpm view react versions". If you want to install the matched version ignoring the time it was published, you can add the package name to the minimumReleaseAgeExclude setting. Read more about it: https://pnpm.io/settings#minimumreleaseageexclude
minimumReleaseAgeExcludeによる例外管理
特定のnpmパッケージではリスク承知で常に最新版を利用したい場合や、セキュリティパッチが出たバージョンのインストールを一時的に優先したい場合などは、minimumReleaseAgeExcludeでホワイトリスト形式で例外を指定することが可能です。
# pnpm-workspace.yaml minimumReleaseAge: 1440 minimumReleaseAgeExclude: - vite - react
trustPolicyで信頼レベルが下がったバージョンをインストールしない
pnpm v10.21.0 で導入された trustPolicyは、no-downgradeを指定することで以前のバージョンよりも信頼レベル (Trust Level) が低下したパッケージのインストールを禁止する機能です。
# pnpm-workspace.yaml trustPolicy: no-downgrade
ここでの「信頼レベルの低下」とは、npmのTrusted Publishing (OIDC認証を用いた公開) の状態変化を指しています。npmには、GitHub ActionsなどのCI/CDワークフローからOIDC(OpenID Connect)を用いて認証を行い、パッケージを公開する仕組みがあります。これにより、パッケージが正当なソースから公開されたことを証明でき、証明されたパッケージバージョンにはnpmjs.com上で緑色のバッジが表示されます。


trustPolicy: no-downgrade がインストールをブロックするのは、「前回まではOIDC認証経由で公開されていたのに、最新版ではOIDC認証を使わずに公開されている」というケースです。このような状況は、npmパッケージが乗っ取られている可能性が高いと判断できるため、出所が不明瞭になったバージョンの混入を防ぐことができます。
trustPolicyExcludeによる例外管理
もし正当な理由で認証方式が変更され、インストールがブロックされてしまう場合は、trustPolicyExclude を使用して特定のパッケージを除外設定することも可能です。
# pnpm-workspace.yaml trustPolicy: no-downgrade trustPolicyExclude: - chokidar@4.0.3
さいごに
2025年のアップデートで追加されたpnpmのセキュリティ機能を紹介しました。これらと同様のアプローチは他のパッケージマネージャーでは現状まだ実装されていない物がほとんどです。pnpmはセキュリティ面でも先進的な進化をしているため、セキュリティの観点でpnpmを採用するという判断も有力だと考えています。
是非この機会に、pnpmの採用やpnpmのアップデートの検討をしてみてください!
GameWithではエンジニアを絶賛募集中です。ご興味ありましたら是非カジュアル面談をお申し込みください! github.com