Skip to content

Trivy Security Scanning

Trivy runs in two modes in CWIQ pipelines: a filesystem scan on every branch (blocking secrets, advisory misconfig) and a Docker image CVE scan on main-branch builds only.

Version: v0.69.3 (pinned)

Image: nexus.shared.cwiq.io:8444/aquasec/trivy:0.69.3

Trivy is pulled through the Nexus Docker Hub proxy cache. No direct internet access is required from CI runners.


Scan Components

1. Blocking Secrets Scan

Runs in the validate stage on every branch.

trivy fs --scanners secret --exit-code 1 .

This is the only security scan in CWIQ pipelines that blocks the pipeline. It scans the entire repository for hardcoded secrets — API keys, passwords, connection strings, private keys, and tokens.

If any secrets are found, Trivy exits with code 1 and the pipeline stops. No build, deploy, or downstream scan jobs run.

Pipeline will fail if secrets are found

Remove the secret from your code immediately. Never commit secrets to source control, even in private repositories. Use Vault to retrieve credentials at runtime. See Vault JWT Auth for the CI/CD pattern.

2. Filesystem SARIF Scan

Runs in the validate stage on every branch, after the secrets scan.

trivy fs --format sarif --output trivy-fs-results.sarif --scanners misconfig,secret --exit-code 0 .
trivy fs --format json --output trivy-fs-results.json --scanners misconfig,secret --exit-code 0 .

This scan covers misconfigurations (Dockerfile best practices, IaC issues) and also captures secrets in SARIF format for import into SonarQube. It uses --exit-code 0 so the pipeline continues regardless of findings.

Two output files are produced as job artifacts:

Artifact Format Consumed By
trivy-fs-results.sarif SARIF sonarqube-scan job (imported into SonarQube)
trivy-fs-results.json JSON Available for manual download from pipeline

3. Docker Image CVE Scan

Runs in the scan stage on the main branch only, after the Docker image has been built and pushed.

trivy image --format json --output trivy-image-results.json --exit-code 0 "${TARGET_IMAGE}"

This scan pulls the built Docker image from Nexus and checks every OS package and language dependency against known CVE databases. It requires Vault JWT authentication to pull the image.

The JSON output is consumed by the defectdojo-import job in the same stage.


Including Trivy in Your Pipeline

Add the template include and define the three Trivy jobs in your .gitlab-ci.yml:

include:
  - project: 'orchestrator/ci-templates'
    ref: main
    file:
      - '/.gitlab-ci-common.yml'
      - '/.gitlab-ci-python.yml'   # or .gitlab-ci-node.yml
      - '/.gitlab-ci-trivy.yml'
      - '/.gitlab-ci-scan.yml'

trivy-fs-scan:
  extends: .trivy-fs-scan

trivy-image-scan:
  extends: .trivy-image-scan
  needs:
    - job: build-push
      artifacts: true
  variables:
    IMAGE_NAME: orchestrator-$CI_PROJECT_NAME

defectdojo-import:
  extends: .defectdojo-import
  needs:
    - job: trivy-image-scan
      artifacts: true

The trivy-fs-scan job has no needs: because it runs against the repository checkout directly. The image scan requires the build job to complete first so that the image exists in Nexus.


Artifact Availability

Job Artifacts Produced Downloaded By
trivy-fs-scan trivy-fs-results.sarif, trivy-fs-results.json sonarqube-scan (via needs: artifacts: true)
trivy-image-scan trivy-image-results.json defectdojo-import (via needs: artifacts: true)