Tasuke HubLearn · Solve · Grow
#DevSecOps

DevSecOps実践ガイド:CI/CDにセキュリティを組み込む手法【2025年版】

開発の初期段階からセキュリティを確保するDevSecOpsの考え方と、GitHub Actionsを使ったCI/CDパイプラインへの具体的なセキュリティテスト(SAST, SCA, コンテナスキャン)の組み込み方法を解説します。

時計のアイコン19 September, 2025
TH

Tasuke Hub管理人

東証プライム市場上場企業エンジニア

情報系修士卒業後、大手IT企業にてフルスタックエンジニアとして活躍。 Webアプリケーション開発からクラウドインフラ構築まで幅広い技術に精通し、 複数のプロジェクトでリードエンジニアを担当。 技術ブログやオープンソースへの貢献を通じて、日本のIT技術コミュニティに積極的に関わっている。

🎓情報系修士🏢東証プライム上場企業💻フルスタックエンジニア📝技術ブログ執筆者

はじめに:DevSecOpsとは何か、なぜ重要なのか?

ソフトウェア開発のスピードが加速する現代において、セキュリティはもはや開発ライフサイクルの最終段階で考慮されるべきものではなくなりました。DevSecOpsは、開発(Development)、セキュリティ(Security)、運用(Operations)を統合し、開発の初期段階からセキュリティを組み込む文化・プラクティスです。

このアプローチにより、以下のメリットがもたらされます。

  • 早期の脆弱性発見と修正: 開発の早い段階で問題を発見することで、手戻りを減らし、修正コストを大幅に削減します。
  • セキュアなソフトウェアの迅速なリリース: 自動化されたセキュリティチェックをCI/CDパイプラインに組み込むことで、スピードを犠牲にすることなく安全な製品を届けられます。
  • 開発者とセキュリティチームの連携強化: 共通の目標に向かって協力することで、組織全体のセキュリティ意識が向上します。

本記事では、具体的なツールとしてGitHub Actionsを使い、DevSecOpsパイプラインを構築する実践的な方法を解説します。

ベストマッチ

最短で課題解決する一冊

この記事の内容と高い親和性が確認できたベストマッチです。早めにチェックしておきましょう。

DevSecOpsを実現するCI/CDパイプラインの全体像

DevSecOpsパイプラインは、従来のCI/CDパイプラインに複数のセキュリティチェックポイントを追加したものです。以下に代表的なセキュリティテストの種類と、それらを組み込むタイミングを示します。

DevSecOps Pipeline

  1. コードコミット時:
    • SAST (Static Application Security Testing): ソースコードを静的に解析し、コーディング上の脆弱性を検出します。(例: CodeQL, SonarCloud)
  2. ビルド時:
    • SCA (Software Composition Analysis): 使用しているオープンソースライブラリや依存関係の脆弱性を検出します。(例: Trivy, Dependabot, Snyk)
    • コンテナイメージスキャン: Dockerイメージに含まれるOSパッケージやライブラリの脆弱性をスキャンします。(例: Trivy, Clair)
  3. デプロイ後:
    • DAST (Dynamic Application Security Testing): 実行中のアプリケーションに対して外部から攻撃をシミュレートし、脆弱性を検出します。(例: OWASP ZAP)

この記事では、特に導入が容易で効果の高い「SAST」「SCA」「コンテナイメージスキャン」に焦点を当てて解説します。

さらに理解を深める参考書

関連記事と相性の良い実践ガイドです。手元に置いて反復しながら進めてみてください。

ステップ1:静的アプリケーションセキュリティテスト (SAST) の導入

SASTは、開発者がコードを書く段階でセキュリティ問題を特定するための最初の防衛線です。ここではGitHubが提供する強力なSASTツールであるCodeQLを導入する方法を解説します。

GitHub ActionsでCodeQLを有効化する

CodeQLは、GitHubリポジトリの「Security」タブから数クリックで有効化できますが、ここではよりカスタマイズ性の高いワークフローファイルを作成する方法を紹介します。

  1. リポジトリのルートに .github/workflows/codeql-analysis.yml というファイルを作成します。
  2. 以下の内容を記述します。
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 トリガー: pushpull_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は一度きりの設定ではなく、継続的な改善とチーム全体の文化醸成が不可欠です。

さらに理解を深める参考書

関連記事と相性の良い実践ガイドです。手元に置いて反復しながら進めてみてください。

この記事をシェア

続けて読みたい記事

編集部がピックアップした関連記事で学びを広げましょう。

#Security

APIセキュリティ実践ガイド【2025年版】:OWASP Top 10と具体的な対策

2025/9/3
#Security

Secrets/環境変数の実践ガイド【2025年版】:Next.js/Node/CI/CDの安全な管理

2025/9/13
#セキュリティ

【2025年版】AIエージェントのセキュリティテスト完全ガイド

2025/11/23
#OAuth

OAuth 2.1とOpenID Connect実践ガイド:セキュアな認証・認可の最新動向【2025年版】

2025/9/19
#MLOps

MLOpsパイプライン構築実践ガイド:MLflowとGitHub Actionsで作る機械学習CI/CD【2025年版】

2025/9/19
#データ

【2025年版】シンセティックデータガバナンス実践ガイド

2025/11/23