
こんにちは。エーピーコミュニケーションズ ACS事業部の福井です。
前回の記事でDependabotの週次運用について書いた流れで、ふと気になっていたことがありました。
「そもそも、グループ化機能を使えば102件のアラームを本当に1本のPRに集約できるのか?」という純粋な疑問です。
試してみました。結果から先に言うと、できました。
102件のアラームが1本のPRに集約され、マージしたらすべて消えるのを確認できました。
ただ、そこに至るまでにGitHubの仕様の罠にいくつかハマりました。
そして「1本にまとめ切ること」がゴールなのか、改めて考えさせられることにもなりました。
その試行錯誤の記録をお伝えします。
(余談ですが、この「銀の弾丸」という言葉、壁打ち相手のAI(Gemini等)が好んでよく出してくる表現ですよね。なんだか名探偵コナンの映画のタイトルみたいで少し大げさですが(※映画の正解は『緋色の弾丸』ですが、『銀の弾丸』も作中の超重要キーワードです)、IT業界の古典的な比喩でもありますし、せっかくなので今回はそのまま使ってみます 笑)
- 検証環境の構築:意図的に102件の脆弱性を仕込む
- グループ化のパターンを3つ試した
- 検証中に引っかかった「GitHub仕様の罠」4つ
- 最終確認:102件のアラームが1本のPRに集約され、マージで消滅した
- 「1本にまとめ切る」はゴールではない
- おわりに:機能を「オンにする」だけではDevSecOpsは完成しない
- ACS 事業部のご紹介
検証環境の構築:意図的に102件の脆弱性を仕込む
package.json に lodash、axios、express、tar、handlebars など、過去に多数のCVEが報告されている古いバージョンのnpmパッケージを意図的に大量に列挙しました。
その結果、GitHubのDependabotアラート画面に 102件のセキュリティアラーム が積み上がった状態が出来上がります。
この状態を起点に、dependabot.yml の groups 設定を変えながら、Dependabotがどんなふるまいをするかを1つずつ確認していきました。
※本記事の検証は2026年6月時点の仕様に基づいています。GitHubの仕様は変更される場合がありますのでご注意ください。
グループ化のパターンを3つ試した
パターン1:とにかく全部1つのPRにまとめる
一番シンプルな設定から始めました。*(ワイルドカード)で全パッケージを1つのグループに指定します。
groups: all-dependencies: patterns: - "*"
結果: 「1つのPR」にはならなかった。
「これでPRが1本になる」と期待したのですが、実際には3〜4本のPRに自動分割されて生成されました。
Dependabotには、メジャーバージョンの破壊的変更(Breaking Changes)が含まれる場合や依存解決に競合が生じる場合に、安全のためPRを自動的に分割する仕様があります。
「*で全部まとめれば完全に1本になる」は、仕様上の幻想でした。
生成されたPRを gh pr view でダンプすると、こんな状態です。
Title: chore(deps): bump the all-dependencies group with 98 updates | Package | From | To | | --- | --- | --- | | lodash | `4.17.8` | `4.18.1` | | axios | `0.17.0` | `0.32.0` | ... (延々と続く98個のパッケージリスト)
「このPRの中に、あのCriticalなアラームの修正は入っているの?」という疑問が残ります。
PRを見ただけでは、どれが脆弱性の修正でどれがただのバージョンアップなのか、まったく判断できません。
パターン2:本番依存と開発依存(devDependencies)で分離する
次に、影響範囲を意識して dependency-type でグループを分けてみました。
groups: production-dependencies: dependency-type: "production" dev-dependencies: dependency-type: "development"
結果:PRが2本になり、レビューの優先度をつけやすくなった。ただしブラックボックスは残る。
「テストツールやビルドツールのCritical脆弱性は本番環境には影響しないため優先度を下げる」という観点で、実用的な分離だと感じました。
ただ「本番用PRにどの脆弱性の修正が含まれているか」という可視性の問題は、依然として解消されないままです。
パターン3:セキュリティアップデート専用グループを定義する
applies-to: security-updates でセキュリティアップデートだけをまとめる専用グループを定義しました。
groups: security-alerts-group: applies-to: security-updates patterns: - "*"
結果:セキュリティ専用のグループPRは生成されたが、致命的な問題が判明した。
以前の個別PRでは、GitHubがPR本文に Fixes #アラートID を自動付与してくれていました。
ところがグループ化が適用されると、この紐付け情報がPRのテキスト本文から 完全に消えてしまう のです。
ブラウザUIの右サイドバーにリンクが出るケースもありますが、対象が多すぎると、それすら表示されないことも確認しました。
監査ログやトレーサビリティが求められる現場では、これは見過ごせないトレードオフです。
検証中に引っかかった「GitHub仕様の罠」4つ
グループ化パターンの試行と並行して、いくつかの仕様の罠にもハマりました。元資料として残している検証ログから、確認できた4つをまとめます。
罠1:手動Closeするとスパム防止フィルターが働き、以降そのパッケージのPRが生成されない
整理のため個別のセキュリティPRを手動でCloseしたところ、設定を何度変えても、そのパッケージのPRが二度と生成されなくなりました。
Dependabotには「一度拒否(Close)した脆弱性に対しては二度とPRを作らない」というスパム防止フィルターが存在します。
package.json のバージョンを微妙に変えるか、別の脆弱なパッケージ(ansi-regex 等)を追加して「未知の新しい脆弱性」として再認識させることで回避できましたが、原因がわかるまでに時間がかかりました。
罠2:グループPRの本文から Fixes #ID が消える
生成されたグループPRを gh pr view でCLIからダンプしても、PR本文(Description)に Fixes #アラートID の記載がどこにもありませんでした。
公式ドキュメントでは、通常のセキュリティ更新PRについて「パッチを含む最小バージョンへの更新PRを作成し、Dependabotアラートとリンクする(links the pull request to the Dependabot alert)」と明記されています。
しかし現在のグループ化PRでは、このアラートとの紐付けはブラウザUIの右サイドバーのみで表現される仕様に変わっており、PR本文テキストには出力されません。
CLIやAPIからの読み取りでは情報が欠落するため、自動化や監査ログとの連携が難しくなります。
罠3:バージョン更新設定が残っているとセキュリティPRが横取りされる
dependabot.yml にバージョン更新のグループ設定を残したまま検証していたところ、セキュリティ専用のグループPRではなく「ただのバージョンアップPR」が大量に生成されてしまいました。
バージョン更新が先に動くと「すでに更新用のPRがある」としてDependabotがセキュリティ専用PRの生成をスキップしてしまう仕様があります。
純粋なセキュリティグループPRを生成させるには、バージョン更新の設定を明確に分離または削除する必要がありました。
罠4:UIのデフォルト設定でグループ化すると完全にブラックボックス化する
GitHubのSettings画面のトグルや、デフォルト状態で生成されたグループPR(例: npm_and_yarn グループ)を確認したところ、UIのサイドバーにすらアラートの紐付けが表示されず、単なる「巨大なバージョンアップPR」として処理されていました。
「どの脆弱性が直るのか、画面のどこにも書いていない」という状態は、エンタープライズ環境の監査要件において致命的な問題です。
最終確認:102件のアラームが1本のPRに集約され、マージで消滅した
試行錯誤の末、バージョン更新設定を取り除き、セキュリティアップデート専用グループのみを定義したシンプルな dependabot.yml にたどり着きました。
version: 2 updates: - package-ecosystem: "npm" directory: "/" groups: security-alerts-group: applies-to: security-updates patterns: - "*"
この設定でDependabotを動かすと、102件の脆弱性アラームを対象とした1本のグループPRが生成されました。
そのPRをマージしたところ――GitHubのSecurityタブに積み上がっていた 102件のアラームがすべて消えた のを確認できました。
「消えた……本当に全部消えた」
「1本にまとめて集約してマージすれば全部消える」ことは、実際に手を動かして確認できた事実です。
ただ、ここで改めて問いが生まれました。「1本にまとめ切ることは、本当に正しい運用なのか?」と。
「1本にまとめ切る」はゴールではない
実際にやってみてわかったことがあります。
1本のPRにまとまると確かにノイズは減りますが、「何が直るのかをレビュアーが説明できない」というトレードオフが生まれます。
特に、セキュリティ対応の記録が求められる現場では、これは運用として成立しません。
検証を通じて整理できた4つのパターンを紹介します。
| 運用パターン | PRのノイズ | 可視性・トレーサビリティ | 監査対応 | 導入コスト |
|---|---|---|---|---|
| 個別PR(グループ化なし) | 多い | 高い(Fixes #ID 明記) |
○ | 不要 |
| 標準グループ化(1本にまとめる) | 少ない | 低い(ブラックボックス) | △ | 低 |
グループ化 + @copilot コメント |
少ない | 中(都度Copilotに確認) | △〜○ | 低(AI Credit消費) |
| グループ化 + GHAS API 自動サマリー | 少ない | 高い(自動でサマリーを補完) | ◎ | 高(スクリプト整備が必要) |
ブラックボックス問題を解消する方法として、2つのアプローチが考えられます。
軽量な代替案:GitHub Copilot にPRの安全性を確認してもらう
実は手軽な方法があります。
DependabotのグループPRが作成されたら、PRのコメント欄に以下のように書くだけです。
@copilot 影響範囲を特定して問題ないかチェック いくつのCVEに対応か洗い出してこのPRを要約
GitHub Copilot がPRの差分とリポジトリのコードを解析し、「このパッケージの更新は影響範囲がここに限定されるため安全にマージできると思われます」といったコメントを返してくれます。
スクリプトやActionsのセットアップが不要で、すぐに試せるのが利点です。

ただし注意点もあります。
GitHub Copilot のコードを走査する動作はAI Creditを消費します。また、GHAS(GitHub Advanced Security)のAPIで取得するアラートIDとの突き合わせのような、構造化されたサマリーは得られません。
「都度手動で確認する運用」として使うには十分ですが、CI/CDパイプラインに組み込んだ自動化や監査ログへの出力が必要な場合は、後述のAPIスクリプト方式の方が適しています。
より確実な方法:GHAS(GitHub Advanced Security)API + GitHub Actions でサマリーを自動生成する
グループ化でPRのノイズを減らしつつ、GHAS APIを使ったGitHub Actionsで「どのアラームが解消されるか」をPRコメントに自動投稿することで、ブラックボックス問題を解消します。
Actions経由の実行もAI Creditと同様にAPIクォータを消費しますが、PRを作成するたびに自動でサマリーが投稿されるため、運用の手間が省けます。
実際に今回作成したPythonスクリプトの出力はこのようになります(以下はPoC環境での実行サンプルです。CVE番号は検証用リポジトリで使用したものです)。
=== 🔔 Alerts to be Resolved by this PR === [Package] axios (Resolves 23 alerts) - [HIGH] CVE-2026-44496 : Axios: Regular Expression Denial of Service... - [HIGH] CVE-2026-42033 : Axios: Prototype Pollution Gadgets... [Package] tar (Resolves 13 alerts) - [HIGH] CVE-2026-31802 : node-tar Symlink Path Traversal... ✅ Total Alerts that will be resolved upon merge: 102
「このPRをマージすれば102件の脆弱性が一掃される」と文字で書かれていれば、レビュアーが状況を把握した上でレビューに臨めます。
「なんとなくマージした」ではなく「何を直したかを説明できる」状態が、本当の意味でのセキュリティ対応だと思います。
手軽さを取るか、自動化と監査証跡を取るか――チームの規模や要件に合わせて選べるのが、この領域の現在地だと感じています。
おわりに:機能を「オンにする」だけではDevSecOpsは完成しない
今回の検証を振り返ると、「1つにまとめ切ることはできるか?」という素朴な疑問から始まり、仕様の罠に何度もハマり、アラームがうるさいし一気に直したいからと言って、最終的に「まとめ切ることがゴールではない」という結論にたどり着きました。
机上のドキュメント読解だけでは、PRのダンプを取得し解析をしなければ見えてこない仕様の細かな挙動には気づけなかったと思っています。
「個別PRはノイズが多い」
「標準のグループ化は中身がブラックボックスになる」
「@copilot コメントで都度確認する手もある」
「GHAS APIで自動サマリーを出せば、ノイズ削減と透明性を両立できる」
この4つを自分の手で確認できたことは、今後の技術選定において強力な根拠になります。
本記事が、Dependabotの運用設計に悩む方の一助になれば幸いです。
「1本にまとめ切ることはできる。でも、何が直るかを説明できてこそ、セキュリティ対応は完成する。」
ACS 事業部のご紹介
私の所属する ACS 事業部では、開発者ポータル Backstage、Azure AI Service などを活用し、Platform Engineering + AI の推進・内製化を支援しています。
www.ap-com.co.jp www.ap-com.co.jp www.ap-com.co.jp
また、GitHub パートナーとしてお客様に GitHub ソリューションの導入支援を行っています。 GitHub Copilot などのトレーニングなども行っておりますので、ご興味を持っていただけましたらぜひお声がけいただけますと幸いです。
一緒に働いていただける仲間も募集中です! ご興味持っていただけましたらぜひお声がけください。 ※求人名の冒頭に【ACSD】と入っている求人が当事業部の求人です。