Yarn v4.10.0で追加されたnpmMinimalAgeGateを使って公開直後のパッケージをブロックしてみた
クラスメソッド株式会社データ事業本部所属のニューシロです。
今回はYarn v4.10.0で追加されたnpmMinimalAgeGateという設定を検証してみました。
公開されたばかりのパッケージのインストールを防ぐことで、サプライチェーン攻撃のリスクを軽減できる機能です。
前提
npmMinimalAgeGateとは
npmMinimalAgeGateは、Yarn v4.10.0で追加されたセキュリティ機能です。npmレジストリのパッケージ公開日時を参照し、「公開からの経過時間が設定値に満たないバージョン」をインストール候補から除外します。
参考:
公開から21日以上経過したパッケージのみ許可したい場合、.yarnrc.ymlに以下のように記述します。
npmMinimalAgeGate: "21d"
背景:サプライチェーン攻撃とは
報告されている事例では、ソフトウェアサプライチェーン攻撃は悪意あるパッケージが公開されてから短時間のうちに被害が拡大するパターンをとります。
npmMinimalAgeGateを設定することで、「公開されたばかりのバージョン」を自動的に除外することができ、より安全な状態に近づけます。
npmにも同様の設定がある
npmにも同様のセキュリティ機能としてmin-release-ageが存在します。
参考: npm v11でmin-release-ageが追加された
同様の機能がYarnにもないかな、と思ったのが今回の記事を作成したきっかけでした。
やりたいこと
以下の2点を検証します。
npmMinimalAgeGateの設定の有無で、インストールされるバージョンが変わるか?npmMinimalAgeGateは間接的な依存パッケージにも適用されるか?
検証環境
Node.jsとYarn v4.10.0以上が必要です。インストールは以下リンクを参考にしてください。
以下コマンドで作業用の環境を作成しておきます。
mkdir yarn-age-gate-test && cd yarn-age-gate-test
yarn init -2
Yarnのバージョンを確認しておきます。
$ yarn --version
4.14.1
v4.10.0以上なので問題ないです。
上記コマンドを使用すると、以下のようなディレクトリが作成されました。
こちらの環境で検証を行なっていきます。(表記以外にもファイルが作成されましたが、使用するファイルのみ記載しています)
yarn-age-gate-test/
├── .yarn/
│ └── ...
├── .yarnrc.yml
├── package.json
├── yarn.lock
└── ...
検証
検証1: npmMinimalAgeGateの設定の有無でインストールバージョンが変わるか確認する
今回は検証パッケージにdotenvを使います。dotenvを選んだ理由は以下の2点です。
- 依存関係がゼロ:依存パッケージがないため、ゲートの影響を
dotenv単体で確認できる - 最新バージョンが直近ではない:最新の
17.4.2は2026-04-12公開(約18日前)で、公開直後ではないため、ゲートなしのインストールを行っても問題ない状態です
以下のような状況です。
※ 記事執筆時点(2026年4月30日)
| バージョン | 公開日時 | 経過時間 | "21d"ゲートの結果 |
|---|---|---|---|
| 17.4.2 | 2026-04-12 | 約18日 | ブロックされる |
| 17.4.1 | 2026-04-05 | 約25日 | 通過する |
ゲートなしでyarn installを実行する
package.jsonのdependenciesにdotenvを追加します。
{
"name": "yarn-age-gate-test",
"packageManager": "yarn@4.14.1",
"dependencies": {
"dotenv": "^17.0.0"
}
}
^17.0.0と記載することで、v17の中で最新のバージョンが選択されます。
yarn installを実行します。
yarn install
インストールされたバージョンを確認します。
$ yarn info
├─ dotenv@npm:17.4.2
│ └─ Version: 17.4.2
│
└─ yarn-age-gate-test@workspace:.
├─ Version: 0.0.0
│
└─ Dependencies
└─ dotenv@npm:^17.0.0 → npm:17.4.2
最新の17.4.2がインストールされています。ゲートを設定していない状態では、^17.0.0の範囲で最新のバージョンが選ばれます。
ゲートを設定してyarn installを実行する
作業ディレクトリを削除して再度作成し、次は.yarnrc.ymlにnpmMinimalAgeGateを追記します。
yarnPath: .yarn/releases/yarn-4.14.1.cjs
npmMinimalAgeGate: "21d"
設定が反映されているか確認します。
$ yarn config get npmMinimalAgeGate
30240
30240が返ってきました。.yarnrc.ymlに"21d"と記述しましたが、21日 × 24時間 × 60分 = 30240分として認識されているようです。設定が有効であることが確認できました。
ゲートの設定値が"21d"なので、17.4.2(公開から約18日)ではなく、21日以上経過している17.4.1(公開から約25日)がインストールされると予想されます。
yarn installを実行して確認します。
yarn install
インストールされたバージョンを確認します。
$ yarn info
├─ dotenv@npm:17.4.1
│ └─ Version: 17.4.1
│
└─ yarn-age-gate-test@workspace:.
├─ Version: 0.0.0
│
└─ Dependencies
└─ dotenv@npm:^17.0.0 → npm:17.4.1
17.4.1(公開から約25日)がインストールされました。最新の17.4.2ではなく、ゲートを通過できるバージョンが自動選択されています。
ゲートが無事機能していることが確認できました!
検証2: ゲートが間接的な依存パッケージにも適用されるか確認する
依存先にも、このゲートが適用されるか確認します。
作業ディレクトリを作り直し、.yarnrc.ymlのゲート値を"5d"に設定します。
yarnPath: .yarn/releases/yarn-4.14.1.cjs
npmMinimalAgeGate: "5d"
設定を確認します。
$ yarn config get npmMinimalAgeGate
7200
今回は検証にbrowserslistを使用します。browserslistを選んだ理由は、依存先のcaniuse-liteが直近に更新されているためです。
また、今回の検証では依存先の最新アップデート日も調査しながら行ったため、browserslistの依存パッケージが少ないのも理由の一つです。
依存先を調べます。
$ npm info browserslist dependencies
{
'baseline-browser-mapping': '^2.10.12',
'caniuse-lite': '^1.0.30001782',
'electron-to-chromium': '^1.5.328',
'node-releases': '^2.0.36',
'update-browserslist-db': '^1.2.3'
}
依存パッケージのうちcaniuse-liteが直近に更新されており、ゲートの動作確認に適しています。
$ npm view caniuse-lite time --json | tail -5
"1.0.30001787": "2026-04-08T03:42:23.735Z",
"1.0.30001788": "2026-04-14T04:31:53.726Z",
"1.0.30001790": "2026-04-22T06:22:41.840Z",
"1.0.30001791": "2026-04-26T07:11:17.952Z"
}
| バージョン | 公開日時 | 経過時間 | "5d"ゲートの結果 |
|---|---|---|---|
| 1.0.30001791 | 2026-04-26 | 約4日 | ブロックされる |
| 1.0.30001790 | 2026-04-22 | 約8日 | 通過する |
browserslist自体は設定に関わらず最新バージョンの4.28.2がインストールされます。4.28.2は2026-03-31公開(約30日前)であり、"5d"ゲートを通過します。
$ npm view browserslist time --json | tail -5
"4.27.0": "2025-10-22T13:44:51.330Z",
"4.28.0": "2025-11-10T20:45:32.708Z",
"4.28.1": "2025-12-03T16:22:25.708Z",
"4.28.2": "2026-03-31T10:24:52.545Z"
}
それでは、package.jsonのdependenciesにbrowserslistを追加します。
{
"name": "yarn-age-gate-test",
"packageManager": "yarn@4.14.1",
"dependencies": {
"browserslist": "^4.0.0"
}
}
yarn installを実行します。
yarn install
yarn infoでcaniuse-liteのバージョンを確認します。
$ yarn info
├─ browserslist@npm:4.28.2
│ ├─ Version: 4.28.2
│ │
│ ├─ Exported Binaries
│ │ └─ browserslist
│ │
│ └─ Dependencies
│ ├─ baseline-browser-mapping@npm:^2.10.12 → npm:2.10.21
│ ├─ caniuse-lite@npm:^1.0.30001782 → npm:1.0.30001790
│ ├─ electron-to-chromium@npm:^1.5.328 → npm:1.5.344
│ ├─ node-releases@npm:^2.0.36 → npm:2.0.38
│ └─ update-browserslist-db@npm:^1.2.3 → npm:1.2.3 [8923c]
│
└─ yarn-age-gate-test@workspace:.
├─ Version: 0.0.0
│
└─ Dependencies
└─ browserslist@npm:^4.0.0 → npm:4.28.2
抜き出します。
caniuse-lite@npm:^1.0.30001782 → npm:1.0.30001790
caniuse-liteのバージョンが1.0.30001790となっており、最新の1.0.30001791ではないことが確認できました。
npmMinimalAgeGateは直接依存だけでなく、間接的な依存パッケージにも適用されることが確認できました!
所感
こういった設定周りは念の為の検証が必要かなと思っていますので、実際の挙動の確認が取れて良かったです。







