mcpField
S
scanning-containers-with-trivy-in-cicd

scanning-containers-with-trivy-in-cicd

github.com/mukul975セキュリティ35.2k127 回インストール8 週間前に更新
リポジトリ

scanning-containers-with-trivy-in-cicd について

CI/CD で Trivy を使ってコンテナや設定を検査するチーム向けのワークフロースキルです。イメージのプッシュ前に脆弱性や設定不備を確認する手順に加え、SBOM 生成、例外管理、脆弱性データベースのキャッシュを扱います。

主な機能

  1. 01コンテナイメージの脆弱性スキャン
  2. 02Dockerfile と IaC 設定の検査
  3. 03重大度に応じたパイプラインの判定基準
  4. 04無視項目と VEX 例外の管理
  5. 05SBOM 生成と脆弱性データベースのキャッシュ

活用シーン

  1. 01プッシュ前に重大な検出結果のあるイメージを止める
  2. 02CI/CD で Dockerfile 設定を検査
  3. 03イメージの CycloneDX または SPDX SBOM 生成
  4. 04オフライン環境で脆弱性データベースを再利用

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/mukul975/anthropic-cybersecurity-skills --skill scanning-containers-with-trivy-in-cicd

インストール後、Claude Code で/scanning-containers-with-trivy-in-cicdを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

LICENSE
assets/
template.md
references/
api-reference.md
standards.md
workflows.md
scripts/
agent.py
process.py

詳細

CI/CDでTrivyを使用してコンテナをスキャンする

使用する場面

  • CI/CDでDockerコンテナイメージをビルドし、レジストリにプッシュする前に脆弱性を自動スキャンする必要がある場合
  • 重大または高リスクのCVEを含むイメージが本番環境に到達するのを防ぐ品質ゲートを設ける場合
  • コンプライアンス要件により、デプロイ前にすべてのコンテナイメージの脆弱性スキャンが義務付けられている場合
  • コンテナイメージのスキャンとあわせて、IaCファイル(Dockerfile、Kubernetesマニフェスト)もスキャンする場合
  • OSパッケージ、言語固有の依存関係、設定ミスを1つのツールでスキャンする必要がある場合

実行時のコンテナセキュリティ監視には使用しないでください(Falcoを使用してください)。本番環境で実行中のコンテナをスキャンする場合(実行時エージェントを使用してください)、またはコンテナ化せずにアプリケーションのソースコードのみをスキャンする場合(SASTツールを使用してください)も同様です。

前提条件

  • Trivy CLI(v0.50以降)がインストールされているか、aquasecurity/trivy-action GitHub Actionを利用できること
  • イメージのビルドとスキャンのために、CI/CDでDockerデーモンを利用できること
  • ベースイメージのプルとスキャン済みイメージのプッシュに必要なコンテナレジストリの認証情報
  • Trivyの脆弱性データベースにアクセスできること(自動ダウンロードまたはキャッシュ)

ワークフロー

ステップ 1:GitHub ActionsでTrivyスキャンを設定する

Dockerイメージをビルドし、コンテナレジストリにプッシュする前にTrivyでスキャンするGitHub Actionsワークフローを設定します。

# .github/workflows/container-security.yml
name: Container Security Scan

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]
    paths:
      - 'Dockerfile'
      - 'docker-compose*.yml'
      - 'src/**'
      - 'requirements*.txt'
      - 'package*.json'

jobs:
  build-and-scan:
    runs-on: ubuntu-latest
    permissions:
      security-events: write
      contents: read

    steps:
      - uses: actions/checkout@v4

      - name: Build Docker image
        run: docker build -t app:${{ github.sha }} .

      - name: Run Trivy vulnerability scanner
        uses: aquasecurity/[email protected]
        with:
          image-ref: 'app:${{ github.sha }}'
          format: 'sarif'
          output: 'trivy-results.sarif'
          severity: 'CRITICAL,HIGH'
          exit-code: '1'
          ignore-unfixed: true

      - name: Upload Trivy scan results
        uses: github/codeql-action/upload-sarif@v3
        if: always()
        with:
          sarif_file: 'trivy-results.sarif'
          category: 'trivy-container'

      - name: Run Trivy misconfiguration scanner
        uses: aquasecurity/[email protected]
        with:
          scan-type: 'config'
          scan-ref: '.'
          format: 'table'
          exit-code: '1'
          severity: 'CRITICAL,HIGH'
ステップ 2:設定ミスがないかDockerfileをスキャンする

Trivyは、rootユーザーでの実行、latestタグの使用、不要なポートの公開など、よくあるDockerfileのセキュリティ上の問題を検出します。

# Scan Dockerfile for misconfigurations
trivy config --severity HIGH,CRITICAL ./Dockerfile

# Scan with custom policy directory
trivy config --policy ./security-policies --severity MEDIUM,HIGH,CRITICAL .

# Example secure Dockerfile practices Trivy checks for:
# - USER instruction present (not running as root)
# - HEALTHCHECK instruction defined
# - Base image uses specific tag, not :latest
# - No secrets in ENV or ARG instructions
# - COPY preferred over ADD
ステップ 3:GitLab CI/CDと統合する
# .gitlab-ci.yml
stages:
  - build
  - scan
  - push

variables:
  TRIVY_CACHE_DIR: .trivycache/

build:
  stage: build
  script:
    - docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA .
    - docker save $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA -o image.tar
  artifacts:
    paths:
      - image.tar

trivy-scan:
  stage: scan
  image:
    name: aquasec/trivy:latest
    entrypoint: [""]
  cache:
    paths:
      - .trivycache/
  script:
    - trivy image
        --input image.tar
        --exit-code 1
        --severity CRITICAL,HIGH
        --ignore-unfixed
        --format json
        --output trivy-report.json
    - trivy image
        --input image.tar
        --severity CRITICAL,HIGH,MEDIUM
        --format table
  artifacts:
    reports:
      container_scanning: trivy-report.json
    paths:
      - trivy-report.json
  allow_failure: false

push:
  stage: push
  needs: [trivy-scan]
  script:
    - docker load -i image.tar
    - docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
ステップ 4:Trivyの無視設定と例外処理を構成する

Trivyの無視ファイルとVEXステートメントを使って、誤検知や許容するリスクを管理します。

# .trivyignore.yaml
vulnerabilities:
  - id: CVE-2023-44487    # HTTP/2 rapid reset - mitigated at load balancer
    statement: "Mitigated by WAF rate limiting at ingress layer"
    expires: 2026-06-01

  - id: CVE-2024-21626    # runc container escape - patched in base image update
    statement: "Tracked in JIRA-SEC-1234, base image update scheduled"
    expires: 2026-03-15

misconfigurations:
  - id: DS002             # User not set - required for init containers
    paths:
      - "docker/init-container/Dockerfile"
    statement: "Init container requires root for volume permission setup"
ステップ 5:データベースのキャッシュとオフラインスキャンを実装する

CI/CDでTrivyの脆弱性データベースをキャッシュし、スキャン時間を短縮するとともに、エアギャップ環境での利用を可能にします。

# GitHub Actions with database caching
- name: Cache Trivy DB
  uses: actions/cache@v4
  with:
    path: /tmp/trivy-db
    key: trivy-db-${{ hashFiles('.github/workflows/container-security.yml') }}
    restore-keys: trivy-db-

- name: Run Trivy with cached DB
  uses: aquasecurity/[email protected]
  with:
    image-ref: 'app:${{ github.sha }}'
    cache-dir: /tmp/trivy-db
    format: 'json'
    output: 'trivy-results.json'
    severity: 'CRITICAL,HIGH'
    exit-code: '1'
# Air-gapped: Download DB manually and mount
trivy image --download-db-only --cache-dir /path/to/cache
# Transfer cache to air-gapped system
trivy image --skip-db-update --cache-dir /path/to/cache myimage:tag
ステップ 6:SBOMを生成し、ライセンス遵守をスキャンする

Trivyを使用して、脆弱性スキャンとあわせてソフトウェア部品表を生成します。

# Generate SBOM in CycloneDX format
trivy image --format cyclonedx --output sbom.cdx.json app:latest

# Generate SBOM in SPDX format
trivy image --format spdx-json --output sbom.spdx.json app:latest

# Scan SBOM for vulnerabilities (decouple generation from scanning)
trivy sbom sbom.cdx.json --severity CRITICAL,HIGH

# Scan with license detection
trivy image --scanners vuln,license --severity HIGH,CRITICAL app:latest

主な概念

用語定義
CVECommon Vulnerabilities and Exposures — 公知のセキュリティ脆弱性に付与される標準化された識別子
Vulnerability DBTrivyの定期更新データベース。NVD、ベンダーのアドバイザリ、言語固有の情報源からCVEデータを集約します
MisconfigurationDockerfile、Kubernetesマニフェスト、IaCテンプレートにおける、セキュリティに関わる設定上の問題
SBOMSoftware Bill of Materials — コンテナイメージ内のすべてのコンポーネントと依存関係の完全な一覧
Ignore Unfixed利用可能なパッチがないCVEをスキップするフラグ。対処可能な修正がない脆弱性によるノイズを減らします
VEXVulnerability Exploitability eXchange — 特定の状況で脆弱性が悪用可能かどうかを示す、機械可読なステートメント
Exit Code検出結果が重大度のしきい値を超えた場合にTrivyが返すゼロ以外の終了コード。CI/CDパイプラインの失敗に使用されます

ツールとシステム

  • Trivy:Aqua Securityが提供するオープンソースの脆弱性スキャナー。イメージ、ファイルシステム、リポジトリ、IaCに対応しています
  • trivy-action:GitHub ActionsのワークフローでTrivyスキャンを実行する公式GitHub Action
  • Trivy Operator:Trivyを使用してクラスターのワークロードを継続的にスキャンするKubernetesオペレーター
  • Grype:スキャン結果の比較と検証に利用できる、Anchoreが提供する代替イメージスキャナー
  • Harbor:プッシュ時のイメージ自動スキャンにTrivyを組み込んだコンテナレジストリ

よくあるシナリオ

シナリオ:スキャンとプッシュを分けたマルチステージビルド

背景:あるチームではマルチステージの Docker イメージをビルドしており、ECR にプッシュする前に最終的な本番イメージをスキャンすると同時に、サプライチェーンのリスクを確認するためにビルドステージもスキャンする必要があります。

アプローチ:

  1. 最終ステージに対して --target production を指定して Docker イメージをビルドします
  2. --severity CRITICAL,HIGH --exit-code 1 --ignore-unfixed を指定して Trivy を実行し、悪用可能な問題があれば処理を停止します
  3. CycloneDX 形式で SBOM を生成し、ビルド成果物として保存します
  4. SARIF の結果を GitHub Security タブにアップロードして可視化します
  5. Trivy スキャンがコード 0 で終了した場合にのみ、ECR にプッシュします
  6. 監査で追跡できるよう、プッシュしたイメージにスキャンのタイムスタンプと Trivy DB のバージョンをタグ付けします

注意点:最終ステージだけをスキャンすると、ビルドステージに存在してビルドに影響した可能性のある脆弱なパッケージを見落とします。ビルドコンテキストに対して、別途 trivy fs を実行してください。Trivy DB を過度に頻繁に(週単位で)キャッシュすると、新たに公開された CVE がスキャンに反映されるまで数日かかります。

出力形式

Trivy Container Scan Report
=============================
Image: app:a1b2c3d4
Base Image: python:3.12-slim-bookworm
Scan Date: 2026-02-23
DB Version: 2026-02-23T00:15:00Z

VULNERABILITY SUMMARY:
  Total: 47
  Critical: 2
  High: 5
  Medium: 18
  Low: 22
  Unfixed: 8 (excluded from gate)

CRITICAL FINDINGS:
  CVE-2025-12345  libssl3    3.0.11-1  3.0.13-1  OpenSSL buffer overflow
  CVE-2025-67890  curl       7.88.1-10 7.88.1-12 curl HSTS bypass

HIGH FINDINGS:
  CVE-2025-11111  zlib1g     1.2.13    1.2.13.1  zlib heap buffer overflow
  CVE-2025-22222  python3.12 3.12.1    3.12.3    CPython path traversal
  CVE-2025-33333  requests   2.31.0    2.32.0    requests SSRF in redirects

MISCONFIGURATION:
  DS002  [HIGH]   Dockerfile: USER instruction not set (running as root)
  DS026  [MEDIUM] Dockerfile: No HEALTHCHECK defined

QUALITY GATE: FAILED (2 Critical, 5 High findings)

コメント