固定したバージョン、どう更新する? Renovateで始める自動依存関係管理 #renovate #gitlab

はじめに
以前のブログ「2026年3月Trivyサプライチェーン攻撃とDockerイメージのバージョンピニング」では、DockerイメージのバージョンをタグやSHA256ハッシュ値で固定(ピニング)する重要性について取り上げました。
これでDockerイメージの内容が想定外に差し交わることはなくなるので一安心、と言いたいところですが、
「固定したバージョンが古くなったら、誰が更新するのか?」
「数百あるリポジトリのライブラリやベースイメージを、手動でチェックし続けるのか?」
といった新たな課題が浮上します。
本稿ではこの「バージョンの塩漬け」問題を解決するツール Renovate をご紹介します。
Renovate とは
Renovateとは、古くなったパッケージを自動的に検出し、プルリクエストやマージリクエストの形式でパッケージ更新を提供するソフトウェアです。似たような仕組みに Dependabot があります。
先に述べた通り、バージョンピニングはサプライチェーン攻撃を防ぐための第一歩です。しかし、固定した瞬間からそのイメージは古くなり始めます。最新の状態であるためには、新しいバージョンがリリースされていないかを常に確認し、テストし、更新し続けなければなりません。これを手動で行うのは現実的ではありませんが、怠るわけにもいきせん。これを自動化するのがRenovateやDependabotのような依存関係更新ツールです。
セルフホストGitLabで適用
セルフホストGitLabにて試してみました。正式な方法は公式ドキュメントをご覧ください。
まず、Renovateを実行するためのレポジトリ(ここでは creationline/renovate-bot )を用意します。そこには次の .gitlab-ci.yml を置きました。
stages:
- renovate
renovate:
stage: renovate
image:
name: renovate/renovate:43.205.2@sha256:436f8141e24268342921d14aa7f5a22ef7f85e4e65ece12c3447769189ff3b10
entrypoint: [""]
rules:
- if: '$CI_PIPELINE_SOURCE == "schedule"'
variables:
RENOVATE_LOG_LEVEL: info
- if: '$CI_PIPELINE_SOURCE == "web"'
variables:
RENOVATE_LOG_LEVEL: debug
variables:
RENOVATE_CONFIG_FILE: $CI_PROJECT_DIR/config.js
script:
- renovate
これをGitLabのパイプラインスケジュールで実行するようにします。
Renovate自体の設定ファイル config.js を同じレポジトリに配置します。
module.exports = {
platform: 'gitlab',
endpoint: 'https://gl.creationline.com/api/v4/',
gitAuthor: 'Renovate Bot <renovate-bot@example.com>',
autodiscover: false,
prHourlyLimit: 0,
repositories: [
'creationline/renovate-bot',
'creationline/REPOSITORY_A',
'creationline/REPOSITORY_B',
'creationline/REPOSITORY_C',
],
};
ここでは autodiscover を false として、このファイルで指定したレポジトリだけを監視しています。
また prHourlyLimit を 0 として、1時間に作成できるマージリクエスト(プルリクエスト)の数を無制限としています。デフォルトでは1時間に2つしか発行しないので、Renovateの実行間隔によっては制限にかかって更新が不十分となってしまいます。
次にこの creaionline/renovate-bot レポジトリに対する設定ファイル renovate.json を同じレポジトリに配置します。
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": ["config:best-practices"],
"timezone": "Asia/Tokyo",
"labels": ["renovate"],
"minimumReleaseAge": "7 days"
}
プリセットとして config:best-practices を設定しています。timezoneは日本です。GitLab Issueボードには自動的に renovate ラベルを付与するようにします。
minimumReleaseAgeにより、7日間経ったものでなければ適用しない、というクールダウン期間を設けています。2026年3月のTrivyサプライチェーン攻撃では数時間、2026年5月のNx Consoleの侵害では数十分、悪意ある最新版が公開されていたので、最新版をインストールしない期間をある程度設けておけば引っかかる可能性を下げることができます。もちろんこれは絶対ではありません。何年も誰にも見つからなかったバグがついに見つかった、という話も珍しいことではありません。
実際にRenovateを実行すると、次のようなマージリクエストが発行されます。

これを人間の目で確認し、人間の手でマージすることになりますが、設定によっては自動的にマージさせることも可能です。その際もどのような基準でマージするのかの設定が可能です。
Renovate導入直後は自動マージは有効にせず、しばらく手動で運用してみて問題なければ自動にするとよいでしょう。
またRenovateはCIがパスしていなければ自動マージしない、とすることもできるので、CIで十分にテストできるようになっていることも重要です。
まとめ
本稿ではRenovateの簡単な設定例を見てみました。
「サプライチェーン攻撃を避けるためにバージョンピニングを行う」ことと「ソフトウェアを最新の状態に保つ」ことは一見矛盾するように見えますが、両立させるべき概念です。近年ではエンドユーザが狙われるだけでなく、強い権限や鍵を持つ開発者や自動化されたワークフローが狙われることも増えてきたと感じています。であればソフトウェア開発をすべて手動でやるのか、というとそれはまったく現実的ではありません。可能な限り、安全を考慮した形で自動化しなければ立ち行かない状況となっています。
手動でのバージョン確認で疲弊する前に、ぜひRenovateの導入を検討してみてください。
