はじめに:DevSecOpsとは何か、なぜ重要なのか?
ソフトウェア開発のスピードが加速する現代において、セキュリティはもはや開発ライフサイクルの最終段階で考慮されるべきものではなくなりました。DevSecOpsは、開発(Development)、セキュリティ(Security)、運用(Operations)を統合し、開発の初期段階からセキュリティを組み込む文化・プラクティスです。
このアプローチにより、以下のメリットがもたらされます。
- 早期の脆弱性発見と修正: 開発の早い段階で問題を発見することで、手戻りを減らし、修正コストを大幅に削減します。
- セキュアなソフトウェアの迅速なリリース: 自動化されたセキュリティチェックをCI/CDパイプラインに組み込むことで、スピードを犠牲にすることなく安全な製品を届けられます。
- 開発者とセキュリティチームの連携強化: 共通の目標に向かって協力することで、組織全体のセキュリティ意識が向上します。
本記事では、具体的なツールとしてGitHub Actionsを使い、DevSecOpsパイプラインを構築する実践的な方法を解説します。
最短で課題解決する一冊
この記事の内容と高い親和性が確認できたベストマッチです。早めにチェックしておきましょう。
DevSecOpsを実現するCI/CDパイプラインの全体像
DevSecOpsパイプラインは、従来のCI/CDパイプラインに複数のセキュリティチェックポイントを追加したものです。以下に代表的なセキュリティテストの種類と、それらを組み込むタイミングを示します。
- コードコミット時:
- SAST (Static Application Security Testing): ソースコードを静的に解析し、コーディング上の脆弱性を検出します。(例: CodeQL, SonarCloud)
- ビルド時:
- SCA (Software Composition Analysis): 使用しているオープンソースライブラリや依存関係の脆弱性を検出します。(例: Trivy, Dependabot, Snyk)
- コンテナイメージスキャン: Dockerイメージに含まれるOSパッケージやライブラリの脆弱性をスキャンします。(例: Trivy, Clair)
- デプロイ後:
- DAST (Dynamic Application Security Testing): 実行中のアプリケーションに対して外部から攻撃をシミュレートし、脆弱性を検出します。(例: OWASP ZAP)
この記事では、特に導入が容易で効果の高い「SAST」「SCA」「コンテナイメージスキャン」に焦点を当てて解説します。
さらに理解を深める参考書
関連記事と相性の良い実践ガイドです。手元に置いて反復しながら進めてみてください。
ステップ1:静的アプリケーションセキュリティテスト (SAST) の導入
SASTは、開発者がコードを書く段階でセキュリティ問題を特定するための最初の防衛線です。ここではGitHubが提供する強力なSASTツールであるCodeQLを導入する方法を解説します。
GitHub ActionsでCodeQLを有効化する
CodeQLは、GitHubリポジトリの「Security」タブから数クリックで有効化できますが、ここではよりカスタマイズ性の高いワークフローファイルを作成する方法を紹介します。
- リポジトリのルートに
.github/workflows/codeql-analysis.ymlというファイルを作成します。 - 以下の内容を記述します。
name: "CodeQL Analysis"
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
schedule:
- cron: '0 2 * * 1' # 毎週月曜日の2時にスキャン
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
language: [ 'javascript', 'python' ] # プロジェクトで使用している言語に合わせて変更
steps:
- name: Checkout repository
uses: actions/checkout@v4
# CodeQL Actionを初期化
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
# オプション: 解析設定ファイルを指定する場合
# config-file: ./.github/codeql/codeql-config.yml
# ビルドが必要な言語の場合、ここにビルドステップを追加
# - name: Autobuild
# uses: github/codeql-action/autobuild@v3
# CodeQL解析を実行
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
with:
category: "/language:${{matrix.language}}"なぜこの設定なのか?
onトリガー:pushやpull_request時に解析を実行することで、新しいコードがマージされる前に脆弱性を検出します。scheduleで定期実行することで、潜在的な問題を継続的に監視します。permissions:security-events: write権限により、CodeQLが検出した脆弱性をリポジトリの「Security」タブに報告できるようになります。matrix.language: プロジェクトで使用している言語(javascript,python,go,javaなど)を指定します。これにより、言語ごとに最適化された解析が実行されます。
このワークフローを導入するだけで、GitHubは自動的にコードをスキャンし、発見された脆弱性を「Security」タブの「Code scanning alerts」に報告してくれます。
さらに理解を深める参考書
関連記事と相性の良い実践ガイドです。手元に置いて反復しながら進めてみてください。
ステップ2:ソフトウェア構成分析 (SCA) の導入
現代のアプリケーションは、その大部分がオープンソースのライブラリやフレームワークで構成されています。SCAは、これらの依存関係に潜む既知の脆弱性を特定するプロセスです。
GitHub Dependabotによる依存関係の脆弱性管理
GitHubにはDependabotが標準で組み込まれており、リポジトリの依存関係を監視し、脆弱性が発見された場合にアラートを生成します。さらに、脆弱性を修正するプルリクエストを自動で作成することも可能です。
Dependabotはリポジトリの「Settings」>「Code security and analysis」から有効化できます。
CI/CDでのコンテナを使った依存関係スキャン (Trivy)
Dependabotは便利ですが、CI/CDパイプライン内で明示的にスキャンを実行したい場合もあります。ここでは、Aqua Securityが開発するオープンソースのスキャナTrivyを使って、プロジェクトの依存関係をスキャンする方法を紹介します。
以下のワークフロー(.github/workflows/sca-scan.yml)は、package-lock.json(Node.jsプロジェクトの場合)をスキャンします。
name: "SCA Scan with Trivy"
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
sca-scan:
name: SCA Scan
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Run Trivy vulnerability scanner in fs mode
uses: aquasecurity/trivy-action@master
with:
scan-type: 'fs' # ファイルシステムをスキャン
scan-ref: '.'
ignore-unfixed: true # まだ修正が提供されていない脆弱性は無視
format: 'table'
output: 'trivy-results.md'
severity: 'HIGH,CRITICAL' # HIGH以上の深刻度のみ報告
- name: Upload Trivy scan results
uses: actions/upload-artifact@v4
with:
name: trivy-scan-results
path: trivy-results.mdなぜTrivyなのか?
- 多機能: Trivyはファイルシステム、コンテナイメージ、Gitリポジトリなど、さまざまなターゲットをスキャンできます。
- 高速・簡単: インストールや設定が非常にシンプルで、高速に動作します。
- 豊富な対応言語: Node.js, Python, Ruby, Java, Goなど、多くの言語のパッケージマネージャーに対応しています。
このワークフローにより、プルリクエストが作成されるたびに依存関係がスキャンされ、問題があれば開発者はすぐに気づくことができます。
さらに理解を深める参考書
関連記事と相性の良い実践ガイドです。手元に置いて反復しながら進めてみてください。
ステップ3:コンテナイメージの脆弱性スキャン
アプリケーションをコンテナ化している場合、そのベースイメージや追加したライブラリに脆弱性が含まれている可能性があります。コンテナイメージのスキャンは、本番環境に脆弱なコンテナがデプロイされるのを防ぐための重要なステップです。
ここでもTrivyが活躍します。以下のワークフローは、Dockerイメージをビルドし、そのイメージをTrivyでスキャンします。
name: "Container Image Scan with Trivy"
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
build-and-scan:
name: Build and Scan Image
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Build an image from Dockerfile
run: |
docker build -t my-app:${{ github.sha }} .
- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@master
with:
image-ref: 'my-app:${{ github.sha }}'
format: 'table'
exit-code: '1' # 脆弱性が検出されたらワークフローを失敗させる
ignore-unfixed: true
severity: 'CRITICAL' # CRITICALな脆弱性が見つかった場合のみ失敗させる
# オプション: スキャン結果をアップロード
- name: Upload Trivy scan results
if: failure() # ワークフローが失敗した場合のみ実行
uses: actions/upload-artifact@v4
with:
name: trivy-critical-scan-results
path: trivy-results.sarif # TrivyはSARIF形式でも出力可能なぜこの設定が重要なのか?
exit-code: '1': この設定により、Trivyが指定された深刻度(この場合はCRITICAL)以上の脆弱性を検出した場合、ワークフロー全体が失敗します。これにより、脆弱なイメージが後続のデプロイプロセスに進むのを強制的に防ぎます。image-ref: ビルドしたローカルのDockerイメージを直接スキャン対象として指定しています。if: failure(): ワークフローが失敗した(=脆弱性が検出された)場合にのみスキャン結果をアーティファクトとしてアップロードすることで、問題の調査を容易にします。
さらに理解を深める参考書
関連記事と相性の良い実践ガイドです。手元に置いて反復しながら進めてみてください。
まとめ:セキュアな開発ライフサイクルへの第一歩
本記事では、DevSecOpsの考え方に基づき、GitHub Actionsを使用してCI/CDパイプラインに自動的なセキュリティチェックを組み込む具体的な方法を解説しました。
- SAST (CodeQL) でソースコードそのものの問題を早期に発見する。
- SCA (Trivy/Dependabot) でオープンソースの依存関係の脆弱性を管理する。
- コンテナスキャン (Trivy) でデプロイされるコンテナイメージの安全性を確保する。
これらのステップを導入することは、セキュアなソフトウェア開発体制を構築するための大きな一歩です。まずは導入しやすいものから始め、徐々にセキュリティカバレッジを広げていくことをお勧めします。DevSecOpsは一度きりの設定ではなく、継続的な改善とチーム全体の文化醸成が不可欠です。
さらに理解を深める参考書
関連記事と相性の良い実践ガイドです。手元に置いて反復しながら進めてみてください。



![Ansible実践ガイド 第4版[基礎編] impress top gearシリーズ](https://m.media-amazon.com/images/I/516W+QJKg1L._SL500_.jpg)

