Docker Image Security Scanning

February 13, 2026 | Docker Security CI/CD

Trivy, Cosign, admission controllers.

Container Image Security Scanning

Container images inherit vulnerabilities from their base images and dependencies. A single unpatched CVE can expose your entire infrastructure. Integrating security scanning into your CI/CD pipeline catches vulnerabilities before they reach production.

Why Scanning Matters

  • 80% of container images contain at least one known vulnerability
  • Base images like ubuntu:22.04 may have 50+ CVEs at any given time
  • Application dependencies (npm, pip, Maven) introduce additional risk
  • Compliance frameworks (SOC 2, ISO 27001) require vulnerability management

Trivy: The Go-To Scanner

Trivy is the most popular open-source scanner, supporting OS packages, language dependencies, and IaC misconfigurations:

# Scan a local image
trivy image myapp:latest

# Scan with severity filter
trivy image --severity HIGH,CRITICAL myapp:latest

# Output as JSON for CI/CD processing
trivy image --format json --output results.json myapp:latest

# Fail CI if critical vulnerabilities found
trivy image --exit-code 1 --severity CRITICAL myapp:latest

GitHub Actions Integration

name: Build and Scan
on: push

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

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

    - name: Run Trivy scan
      uses: aquasecurity/trivy-action@master
      with:
        image-ref: myapp:${{ github.sha }}
        format: sarif
        output: trivy-results.sarif
        severity: CRITICAL,HIGH

    - name: Upload scan results
      uses: github/codeql-action/upload-sarif@v3
      with:
        sarif_file: trivy-results.sarif

Image Signing with Cosign

Verify that images in production came from your CI/CD pipeline:

# Sign an image after building
cosign sign --key cosign.key myregistry/myapp:v1.0.0

# Verify before deployment
cosign verify --key cosign.pub myregistry/myapp:v1.0.0

Admission Controllers

Prevent unscanned or unsigned images from being deployed:

# Using Kyverno policy
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: require-image-signature
spec:
  validationFailureAction: enforce
  rules:
  - name: verify-signature
    match:
      resources:
        kinds:
        - Pod
    verifyImages:
    - imageReferences:
      - "myregistry/*"
      attestors:
      - entries:
        - keys:
            publicKeys: |-
              -----BEGIN PUBLIC KEY-----
              ...
              -----END PUBLIC KEY-----

Scanning Strategy

  1. Build time — Scan during CI/CD, fail pipeline on CRITICAL CVEs
  2. Registry — Enable automatic scanning in ECR/GCR (catches new CVEs in existing images)
  3. Runtime — Use Falco or Sysdig for runtime threat detection
  4. Scheduled — Re-scan all production images weekly for newly discovered CVEs

Reducing Vulnerabilities

  • Use minimal base images — Alpine, distroless, or scratch
  • Multi-stage builds — Remove build tools from production images
  • Pin versions — Use specific tags and digests, not :latest
  • Update regularly — Rebuild images weekly to pick up base image security patches
  • Remove unnecessary packages — Every package is a potential attack vector

Eazy SaaS Tip: We integrate Trivy scanning into every CI/CD pipeline we build, with Slack notifications for new CRITICAL CVEs. Combined with weekly base image updates, this keeps our clients' container fleet vulnerability-free.