【セキュリティ自動化】GitHub Actionsで毎朝ライブラリの脆弱性を自動検知しSlackへ通知する設計術
「またパッケージの脆弱性報告が見過ごされていた……」
Webエンジニアとして複数のプロジェクトを抱えていると、依存ライブラリのセキュリティアップデート作業は後回しになりがちです。ある日突然、深刻な脆弱性 CVE が発表され、慌てて緊急対応に追われた経験を持つ方も少なくないでしょう。
今回は、GitHub ActionsのScheduled Trigger (cron) と pip-audit(または npm audit)を活用し、 「毎朝定時に依存パッケージの脆弱性を全自動スキャンし、問題があればSlackへピンポイント通知する仕組み」 の構築手順を余すことなく解説します。
なぜ「脆弱性スキャンの自動化」が必要なのか?
手動での脆弱性チェックは、どれほど意識の高いチームであっても必ず形骸化します。「リリース時に確認する」というルールを作っても、繁忙期には「今回は軽微な修正だから」とスルーされがちです。
私がこの自動化を導入するきっかけとなったのは、過去に古い依存ライブラリのセキュリティホールを突かれ、開発環境のトークンが漏洩しかけたヒヤリハットでした。それ以来、「人間の記憶や習慣に頼るセキュリティ運用は廃止する」と心に決めました。
自動スキャンフローの全体像
毎朝の始業前に自動実行され、脆弱性が検出された場合のみSlackへ通知を送る構成です。問題がない場合は通知を飛ばさない「サイレント運用」にすることで、通知のオオカミ少年化を防ぎます。
graph TD
A["毎朝8:00 (GitHub Actions cron)"] --> B["リポジトリのチェックアウト"]
B --> C["依存ライブラリのスキャン (pip-audit / npm audit)"]
C --> D{"脆弱性は検出されたか?"}
D -- "検出された" --> E["Slack Incoming Webhook へエラー詳細を送信"]
D -- "問題なし" --> F["処理終了 (通知なし)"]
E --> G["エンジニアが朝会で確認・対応"]
GitHub Actions ワークフローの実装コード
以下は、Pythonプロジェクトにおける pip-audit を用いた実際のワークフロー定義ファイル(.github/workflows/vulnerability-scan.yml)です。
name: Daily Security Vulnerability Audit
on:
schedule:
# 毎朝 UTC 23:00 (日本時間 8:00) に実行
- cron: '0 23 * * *'
workflow_dispatch: # 手動実行用ボタンも設置
jobs:
audit:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install dependencies & audit tool
run: |
python -m pip install --upgrade pip
pip install pip-audit
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
- name: Run pip-audit
id: audit
continue-on-error: true
run: |
# 脆弱性レポートをファイルに出力
pip-audit --desc on > audit_report.txt 2>&1
echo "exit_code=$?" >> $GITHUB_OUTPUT
- name: Notify Slack on failure
if: steps.audit.outputs.exit_code != '0'
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
run: |
REPORT=$(cat audit_report.txt | head -n 30)
PAYLOAD=$(jq -n --arg txt "⚠️ *【セキュリティ警告】依存ライブラリに脆弱性が検出されました* \n\`\`\`\n$REPORT\n\`\`\`" '{text: $txt}')
curl -X POST -H 'Content-type: application/json' --data "$PAYLOAD" "$SLACK_WEBHOOK_URL"
実装のこだわりポイント
continue-on-error: trueとステータス制御 スキャンエラーでステップを即時異常終了させず、終了コードを取得して後続のSlack通知処理へ引き継いでいます。jqによる安全なJSONペイロード生成 ログメッセージ内に特殊文字や改行が含まれていても、jqを経由することでSlackのAPIリクエストが壊れないように配慮しています。- 通知の絞り込み
head -n 30でログの長さを制限し、Slackの通知画面が巨大なスタックトレースで埋め尽くされないように配慮しています。
実際に導入して得られた3つのメリット
- 脆弱性の即時手当がルーチン化された
毎朝Slackに通知が来ると、朝のコーヒーを飲みながら「このライブラリなら
pip install --upgradeでバージョンアップすれば済むな」と、その日のタスクにサクッと組み込めるようになりました。 - 開発メンバーのセキュリティ意識向上 チーム全体で「ライブラリは常に最新近くに保つもの」という認識が共有され、バージョン固定の理由をコードレビューで確認する文化が定着しました。
- 無駄な「手作業チェック会議」の撲滅 月1回のセキュリティ点検会議が不要になり、月あたり約4時間のエンジニア工数が削減されました。
まとめ:セキュリティは「仕組み」で守る
セキュリティ対策で最も重要なのは、「エンジニアの善意や注意深さに依存しない環境づくり」です。
今回紹介したGitHub Actionsの設定は、15分もあればリポジトリに導入できます。まずは手元のプロジェクトで手動起動(workflow_dispatch)から試してみてください。
自動化によって守られた安心感のもとで、本来集中すべき機能開発に力を注いでいきましょう!