こんにちは、Ruby コミッタの柴田です。最近は暖かくなり、ガーデニングで栽培しているバラや藤の新芽や花芽が出てくる時期になってきたので、しっかり花を咲かせるように薬剤や肥料の準備をしなければ〜と必要なものの買い物計画を立てている真っ最中です。
今回はサプライチェーンセキュリティの対策として他のエコシステムで導入が進んでいる「Cooldown(クールダウン)」機能を紹介し、私がメンテナンスしている RubyGems と Bundler でも導入するべきか検討した背景と、今後の方向性についてお話しします。
Cooldown とは何か
Cooldown とは、パッケージの新しいバージョンがリリースされてから一定期間が経過するまで、そのバージョンへの更新を行わないようにする仕組みです。
この機能の主な目的はサプライチェーン攻撃の緩和です。悪意のあるコードが含まれたパッケージがリリースされた場合、待機期間を設けることでセキュリティ研究者やコミュニティがその問題を発見・報告するまでの時間を確保できます。William Woodruff 氏の調査 によれば、検証した10件のサプライチェーン攻撃のうち8件が1週間未満の悪用期間であったとされており、7日間の Cooldown でもほとんどの攻撃を防げた可能性があります。
Andrew Nesbitt 氏の記事「Package Managers Need to Cool Down」でもまとめられているように、2025年後半から2026年にかけて、この Cooldown 機能を言語パッケージマネージャ本体に組み込む動きが急速に広がっています。
プログラミング言語のエコシステムにおける Cooldown 機能
Cooldown に相当する仕組みは、まず依存関係の更新ツールで導入され、その後パッケージマネージャ本体へと広がっています。なお、ツールごとに設定名が異なり(minimumReleaseAge、min-release-age、npmMinimalAgeGate、exclude-newer、uploaded-prior-to など)、少なくとも10種類以上の名前が存在します。ポリグロットな環境では注意が必要です。
依存関係更新ツール
GitHub の Dependabot は 2025年7月に cooldown ブロックを導入しました。デフォルトの待機日数に加えて、セマンティックバージョニングのレベル別(major / minor / patch)に異なる日数を指定でき、セキュリティアップデートは Cooldown をバイパスします。
# .github/dependabot.yml version: 2 updates: - package-ecosystem: "bundler" directory: "/" schedule: interval: "weekly" cooldown: default-days: 3 semver-major-days: 7
Renovate では minimumReleaseAge(旧名 stabilityDays)が利用できます。パッケージごとやアップデート種別ごとに粒度の高い制御が可能です。
{ "minimumReleaseAge": "3 days", "packageRules": [ { "matchUpdateTypes": ["major"], "minimumReleaseAge": "7 days" } ] }
パッケージマネージャ
pnpm は v10.16(2025年9月)で minimumReleaseAge を導入しました。パッケージマネージャ本体に Cooldown を組み込んだ先駆的な実装です。値は分単位で指定し、minimumReleaseAgeExclude で特定のパッケージを除外できます。
# pnpm-workspace.yaml minimumReleaseAge: 1440 # 24時間 minimumReleaseAgeExclude: - '@myorg/*'
npm は CLI 11.x(2026年2月)で min-release-age を導入しています。Bun は 2025年10月に minimumReleaseAge を、Deno は --minimum-dependency-age をそれぞれ導入しており、JavaScript エコシステムでは主要なランタイムすべてが Cooldown に対応しました。
Python エコシステムでは uv がもともと再現可能なビルドのために提供していた --exclude-newer オプションに相対期間指定("7 days" のような記法)が追加され、Cooldown 用途にも利用できるようになりました。pip も 26.0(2026年1月)で --uploaded-prior-to を導入しています。pip は絶対タイムスタンプのみの指定である点が uv と異なります。
RubyGems/Bundler の現状
このように多くのツールや言語パッケージマネージャで Cooldown の導入が急速に進んでいます。一方で RubyGems/Bundler 本体には現時点では Cooldown 機能が存在しません。
そこで、RubyGems/Bundler でも rubygems/rubygems の Discussion にて Cooldown 機能の要望があり、導入するべきか、Ruby のコミュニティメンバーや RubyGems 開発チームと議論を行いました。以下にその論点を整理します。
「人柱」問題
私自身が最初に感じた懸念がこれです。Cooldown は「誰かが先にインストールして問題を発見してくれる」ことを暗黙に前提としています。しかし多数のユーザが Cooldown を有効にすると、新しいバージョンを試す人がいなくなり、待機期間が意味をなさなくなります。何もしないよりは良いかもしれませんが、OSS の構造的な限界がある仕組みだと考えています。
セキュリティ修正の遅延
厳密な Cooldown は、緊急のセキュリティパッチの適用も遅延させてしまいます。悪意のあるリリースと緊急のセキュリティ修正を静的解析ツールが自動的に区別することは技術的に困難であり、Cooldown によってかえってセキュリティリスクが高まるケースもあり得ます。
「安心感」という錯覚
10年間更新されていないソフトウェアに未発見の脆弱性が存在する可能性があるように、時間の経過そのものがセキュリティを保証するわけではありません。Cooldown は一定の安心感を与えますが、それが実際のセキュリティ向上に直結するとは限りません。
セキュリティ研究者によるスキャンの時間確保
一方で、セキュリティ研究者が悪意のあるパッケージを発見するための時間を確保する意味は存在します。
実例として、RubyGems セキュリティチームのメンバーである Maciej Mensfeld 氏 の取り組みが挙げられます。Mensfeld 氏は Ruby 向けのサプライチェーンセキュリティプラットフォーム Diffend の開発者であり、これまでに様々なエコシステムで 20,000 件以上の悪意のあるパッケージを検出・報告しています。
RubyGems でも 2020 年に 700 以上のタイポスクワッティング型の悪意ある Gem(例: rails に対する rail)を発見し、2022 年には年間 400 件以上の悪意あるパッケージが削除されました。RubyKaigi 2023 での発表「RubyGems on the watch」でもこれらの取り組みが紹介されています。
現在も、rubygems.org では Gem のリリース後に Maciej 氏を含むセキュリティチームによるレビューが行われており、攻撃コードが含まれると判断した gem は削除されます。Cooldown は単なる時間稼ぎではなく、こうしたスキャン基盤と組み合わせることで初めて実効性を持つ仕組みだと考えています。
RubyGems/Bundler に Cooldown 機能を導入する際の検討事項
以上の議論を踏まえると、短期的な視点では Cooldown 機能を RubyGems/Bundler のオプションとして提供、中長期的には技術的により効果的な対策を講じるのが良いのではないかと考えています。
Bundler での Cooldown オプションの提供
企業環境を中心に要望が多いこと、また Dependabot や Renovate が既に同等の機能を提供していることから、RubyGems/Bundler 単体でも設定できるようにすることには意味があると思っています。
仕様としては以下のようなものを考えています。
bundle update --cooldown 3のように CLI オプションで指定するbundle config set cooldown 3のようにグローバル設定で指定する- Gemfile 内でブロック構文を用いて特定の Gem にのみ Cooldown を適用する粒度の高い制御
gem installコマンドでも同様の Cooldown をサポートし、GitHub Actions などの CI/CD 環境でも利用可能にする
あくまでオプションであり、デフォルトでは無効とするのが妥当だと考えています。ユーザが自分の運用方針に合わせて選択できる形が望ましいでしょう。
RubyGems.org でのスキャンとメタデータ提供
Cooldown の実効性を高めるためには、単に時間が経過したかどうかだけでなく、その Gem が検査済みかどうかという情報も重要になってきます。RubyGems.org 側で以下のような仕組みを整備できると、より実効性のある対策になると考えています。
- 新しい Gem のリリースに対する自動スキャンの実施とスキャン済みであることをインデックスのメタデータとして公開
- 最近のメンバーシップ変更や Trusted Publishing の無効化など、リスクの高い条件が揃ったリリースに対する遅延の導入
- RubyGems/Bundler がこれらのメタデータを参照して動作を制御できるようにする
さらに「スキャン済みであることを示すバッジがあると良いのでは」という提案もあり、RubyGems.org の UI として検討する価値があると思います。
Cooldown とは別のアプローチ
Cooldown とは別に、gem install 時のコード実行そのものをサンドボックス化するアプローチも議論としてあります。
RubyGems や Bundler は最近 Download と Install を分離する変更が入りました。
この変更はパフォーマンス向上が目的ですが、2つの処理を分離することにより、Download の後に SAST などを用いてコードの検証、問題がない場合は Install など、自動化を可能としつつ現在よりも効果的な対策が望めます。
まとめ
RubyGems/Bundler における Cooldown 機能について、他のエコシステムの動向と議論の背景を紹介しました。Cooldown は完璧な解決策ではありませんが、RubyGems.org 側でのスキャンやメタデータの提供と組み合わせることで、実効性のある対策にできる可能性があります。
アンドパッドでは、こうした OSS のセキュリティやエコシステムの改善に興味があるエンジニアを募集しています。RubyGems/Bundler のようなエコシステムの基盤技術について議論しながら、プロダクト開発やセキュリティ対策を実行していくことに興味がある方は、ぜひご応募ください。