こんにちは。
アプリケーションサービス部、DevOps担当の兼安です。
お盆が近づき、実家の草刈りに追われる毎日を過ごしています。
今年は空調服を着て作業していますが、それでも凄まじく体力を消耗します。
みなさまも外での作業をされる場合はお気をつけてください。
さて、今回はGitHubのDependabotについてお話しします。
- 本記事のターゲット
- GitHub Dependabotとは
- 検証用のサンプルコード
- Dependabotが作成するPR
- PRのグループ化
- dependabot.ymlによるグループ化の制御
- まとめ
- 余談
本記事のターゲット
- GitHubの基礎知識がある方
- プログラミング言語のパッケージ管理と脆弱性の関係の知識がある方
- パッケージの脆弱性対策に関心がある方
GitHub Dependabotとは
GitHub Dependabotは、GitHubが提供する機能で、リポジトリ内の依存関係の脆弱性を検出し、修正するための自動化ツールです。
リポジトリの設定のAdvanced Securityで、Dependabot security updatesを有効にすることで、脆弱性のある依存関係を検出し、プルリクエストを自動で作成するようになります。

脆弱性の検知とプルリクエストの作成は、リポジトリのデフォルトブランチに対してプッシュした時や、定期的なスケジュールに基づいて行われます。
次項から、GitHub DependabotはDependabot、プルリクエストはPRと記述します。
検証用のサンプルコード
/
├── python-1/
│   ├── app.py
│   ├── pyproject.toml
│   └── uv.lock
├── python-2/
│   ├── app.py
│   ├── pyproject.toml
│   └── uv.lock
└── ts/
    ├── app.ts
    ├── package.json
    └── package-lock.json
PythonとTypeScriptで脆弱性を持つサンプルコードを用意しました。
Pythonはフォルダを2つ用意しています。
Dependabotが作成するPR
上記コードをGitHubにプッシュすると、Dependabotが脆弱性のある依存関係を検出し、PRを作成します。

自動でPRを作成してくれる時点で大変便利ではありますが、PRが多くなると対応が大変になります。
PRのグループ化
Advanced Securityで、Dependabot security updatesの下にある、Grouped security updatesを有効にすると、PRのグループ化が有効になります。

すると、次にPRが作成される際に、同じパッケージ管理システムの脆弱性をまとめて1つのPRにグループ化してくれます。

PRを開くと、複数の脆弱性の修正が含まれていることがわかります。

dependabot.ymlによるグループ化の制御
PRのグループ化を細かく制御したい場合は、.github/dependabot.ymlを使用します。
今回の検証用のサンプルコードに、.github/dependabot.ymlを追加します。
/
├── .github/
│   └── dependabot.yml
├── python-1/
│   ├── app.py
│   ├── pyproject.toml
│   └── uv.lock
├── python-2/
│   ├── app.py
│   ├── pyproject.toml
│   └── uv.lock
└── ts/
    ├── app.ts
    ├── package.json
    └── package-lock.json
.github/dependabot.ymlの内容は以下の通りです。
Pythonのフォルダを2つに対し、django系以外に関するPRをpyグループに、django系のPRをdjangoグループに分けています。
TypeScriptのフォルダに関するPRはtsグループにまとめています。
version: 2 updates: - package-ecosystem: "uv" directory: "/python-1" schedule: interval: "daily" groups: py: patterns: - "*" exclude-patterns: - "django*" django: patterns: - "django*" - package-ecosystem: "uv" directory: "/python-2" schedule: interval: "daily" groups: py: patterns: - "*" exclude-patterns: - "django*" django: patterns: - "django*" - package-ecosystem: "npm" directory: "/ts" schedule: interval: "daily" groups: ts: patterns: - "*"
このYAMLを作成後、完成したPRは以下のようになります。

python-1とpython-2は同じpyグループを指定しましたが、同じ名前のグループを作っても、フォルダ別にPRが作成されるようです。
django系のPRは想定通り独立したグループとして作成されています。
tornadoやcertifiのPRは、単独のPRとして作成されました。
これらに関しては特に指定していないのですが、優先度の高い修正は.github/dependabot.ymlで定めたルールから外れて個別のPRとして作成されることがあるようです。
今回試したグループ化のパターン以外の例は、下記のページを参考にするとよいでしょう。
dependabot.ymlを設定した時に気になった点
PRのグループ化は、Grouped security updatesと.github/dependabot.ymlで設定できますが、この2つには依存関係はないようです。
Grouped security updatesを有効にしていなくても、.github/dependabot.ymlでグループ化の設定を行うことでPRはグループ化されます。
.github/dependabot.ymlは、ファイルのグループ化ルールを編集すると、プッシュした時点でPRが再グルーピングされる動きをします。
まとめ
- Dependabotは、GitHubが提供する依存関係の脆弱性を検出し、PRを自動で作成することができるツールです。
- DependabotのPRは、Advanced SecurityでGrouped security updatesを有効にすることで、同じパッケージ管理システムの脆弱性をまとめて1つのPRにグループ化できます。
- .github/dependabot.ymlを使用することで、PRのグループ化を細かく制御できます。
脆弱性対策は、セキュリティの観点から非常に重要ですが、気持ちだけでは継続的に行うことは難しいです。
Dependabotを利用することで効率的な脆弱性対策が可能になります。
本記事がDependabotの運用のヒントになれば幸いです。
余談
Dependabotの前に、そもそも脆弱性をちゃんと仕込めているのかを検証するために、GitHub ActionsでTrivyを動かしていました。
その時気付いたのですが、本記事執筆時点(2025年8月)でのTrivyは、uvに対応していないようです。
uv exportでrequirements.txtを生成してからTrivyを動かせば検知できるので、やり方を共有しておきます。
下記のYAMLのGenerate requirements.txt for Python1・Generate requirements.txt for Python2の部分をご覧ください。
このYAMLのワークフローは、検知できているかを調べるコードなので、Trivyが脆弱性を検知しても正常終了させています。
exit-code: '0'の部分がその設定です。
本来はここはexit-code: '1'にして、脆弱性を検知したらエラーコードを返すようにするのが正しいです。
name: Trivy Vulnerability Scan on: push: branches: - main pull_request: jobs: build: name: Build runs-on: ubuntu-24.04 steps: - name: Checkout code uses: actions/checkout@v4 - name: Setup Python uses: actions/setup-python@v4 with: python-version: '3.13' - name: Install uv run: pip install uv - name: Generate requirements.txt for Python1 run: | cd python-1 uv export --format requirements-txt --output-file requirements.txt - name: Generate requirements.txt for Python2 run: | cd python-2 uv export --format requirements-txt --output-file requirements.txt - name: Scan Python-1 uses: aquasecurity/trivy-action@0.28.0 with: scan-type: 'fs' scan-ref: './python-1' format: 'table' output: 'python-1-results.txt' exit-code: '0' severity: 'UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL' - name: Scan Python-2 uses: aquasecurity/trivy-action@0.28.0 with: scan-type: 'fs' scan-ref: './python-2' format: 'table' output: 'python-2-results.txt' exit-code: '0' severity: 'UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL' - name: Scan TypeScript uses: aquasecurity/trivy-action@0.28.0 with: scan-type: 'fs' scan-ref: './ts' format: 'table' output: 'ts-results.txt' exit-code: '0' severity: 'UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL' - name: Check all results run: | echo "=== Python1 results ===" cat python-1-results.txt || echo "No Python1 results" echo "=== Python2 results ===" cat python-2-results.txt || echo "No Python2 results" echo "=== TypeScript results ===" cat ts-results.txt || echo "No TypeScript results" - name: Upload Trivy scan results uses: actions/upload-artifact@v4 if: always() with: name: trivy-results path: | python-1-results.txt python-2-results.txt ts-results.txt
兼安 聡(執筆記事の一覧)
アプリケーションサービス部 DS3課所属
2025 Japan AWS Top Engineers (AI/ML Data Engineer)
2025 Japan AWS All Certifications Engineers
2025 AWS Community Builders
Certified ScrumMaster
PMP
広島在住です。今日も明日も修行中です。
 
           
            