Container Scanning in CI/CD Pipelines

February 13, 2026 | Docker Security CI/CD

Trivy in GitHub Actions and Jenkins.

Container Scanning in CI/CD Pipelines

Integrating container image scanning into your CI/CD pipeline is the most effective way to prevent vulnerable images from reaching production. This guide shows how to implement scanning with Trivy in GitHub Actions and Jenkins, with policies that balance security with developer productivity.

Why CI/CD Scanning?

  • Shift left — Catch vulnerabilities during build, not in production
  • Automated enforcement — No manual review needed for known CVEs
  • Developer feedback — Developers see vulnerabilities immediately in PR checks
  • Compliance — Automated evidence of vulnerability management for auditors

GitHub Actions with Trivy

name: Build and Scan
on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  build-scan:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v4

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

    - name: Run Trivy vulnerability scanner
      uses: aquasecurity/trivy-action@master
      with:
        image-ref: myapp:${{ github.sha }}
        format: table
        exit-code: 1
        severity: CRITICAL,HIGH
        ignore-unfixed: true

    - name: Run Trivy (SARIF for GitHub Security)
      uses: aquasecurity/trivy-action@master
      if: always()
      with:
        image-ref: myapp:${{ github.sha }}
        format: sarif
        output: trivy-results.sarif

    - name: Upload SARIF
      uses: github/codeql-action/upload-sarif@v3
      if: always()
      with:
        sarif_file: trivy-results.sarif

    - name: Push to ECR (if scan passes)
      if: success()
      run: |
        aws ecr get-login-password | docker login --username AWS --password-stdin $ECR_REGISTRY
        docker tag myapp:${{ github.sha }} $ECR_REGISTRY/myapp:${{ github.sha }}
        docker push $ECR_REGISTRY/myapp:${{ github.sha }}

Jenkins Pipeline

pipeline {
    agent any
    stages {
        stage('Build') {
            steps {
                sh 'docker build -t myapp:${BUILD_NUMBER} .'
            }
        }
        stage('Security Scan') {
            steps {
                sh '''
                    trivy image \
                      --exit-code 1 \
                      --severity CRITICAL,HIGH \
                      --ignore-unfixed \
                      --format json \
                      --output trivy-report.json \
                      myapp:${BUILD_NUMBER}
                '''
            }
            post {
                always {
                    archiveArtifacts artifacts: 'trivy-report.json'
                    publishHTML(target: [
                        reportName: 'Trivy Report',
                        reportDir: '.',
                        reportFiles: 'trivy-report.json'
                    ])
                }
            }
        }
        stage('Push') {
            when { expression { currentBuild.result == null } }
            steps {
                sh 'docker push $ECR_REGISTRY/myapp:${BUILD_NUMBER}'
            }
        }
    }
}

Scanning Policy

SeverityActionTimeline
CRITICALBlock deploymentMust fix before merge
HIGHBlock deploymentMust fix before merge
MEDIUMWarn (don't block)Fix within 30 days
LOWInform onlyFix in next quarter

.trivyignore for False Positives

Suppress known false positives or accepted risks:

# .trivyignore
# Accepted risk: low-severity glibc issue, no exploit available
CVE-2023-12345

# False positive: not applicable to our runtime
CVE-2023-67890

ECR Native Scanning

Enable automatic scanning in ECR as a second layer:

aws ecr put-image-scanning-configuration \
  --repository-name myapp \
  --image-scanning-configuration scanOnPush=true

Best Practices

  1. Scan on every build — Not just on main branch, also on PRs
  2. Use --ignore-unfixed — Don't block on CVEs with no available fix
  3. Pin base images — Use digest references for reproducible builds
  4. Rebuild weekly — Pick up security patches in base images
  5. Track findings over time — Use SARIF integration for trend analysis

Eazy SaaS Tip: We implement a three-layer scanning approach: Trivy in CI/CD (pre-push), ECR scan-on-push (registry), and weekly re-scans of all production images (runtime). This catches vulnerabilities at every stage — from development to production.