How to Use Trivy in CI/CD Pipelines: GitHub Actions, GitLab CI, and Jenkins Integration Guide

Trivy integrates into CI/CD pipelines by executing its single binary or Docker image within workflow jobs, scanning targets on every commit, and failing builds based on configured severity thresholds.

The aquasecurity/trivy repository provides native integrations and documented patterns for embedding vulnerability scanning into automated build workflows. Whether you are securing container images, filesystems, or Infrastructure-as-Code (IaC) files, Trivy's lightweight architecture allows it to run as a standalone step that pulls vulnerability databases, performs the scan, and exits with a status code that CI systems can interpret as pass or fail.

Understanding Trivy's CI/CD Architecture

At its core, Trivy operates as a zero-dependency binary (or container image) that executes four deterministic steps in pipeline contexts:

  1. Install or pull Trivy – via GitHub Action, wget download in GitLab, or Docker image in Jenkins.
  2. Execute the scan – invoking commands like trivy image <image>, trivy fs <path>, or trivy config <dir>.
  3. Evaluate the exit code0 indicates no findings or filtered severities; non-zero triggers pipeline failure.
  4. Publish the report – SARIF for GitHub Code Scanning, GitLab Container-Scanning JSON, or archived artifacts for Jenkins review.

This consistent pattern is documented in docs/ecosystem/cicd.md, which outlines the official integration paths for multiple platforms.

GitHub Actions Integration

The official trivy-action wraps the Trivy binary in a reusable GitHub Action, automating the installation and execution steps.

Configuring the Security Scan Workflow

Create a workflow file (e.g., .github/workflows/trivy.yml) that checks out your repository and invokes the action from aquasecurity/trivy-action@master:

name: Security Scan
on:
  push:
    branches: [ main ]

jobs:
  trivy-scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Run Trivy vulnerability scan
        uses: aquasecurity/trivy-action@master
        with:
          image-ref: myapp:latest
          format: sarif
          output: trivy-results.sarif
      - name: Upload SARIF report
        uses: github/codeql-action/upload-sarif@v2
        with:
          sarif_file: trivy-results.sarif

The image-ref parameter specifies the target container image, while format: sarif generates output compatible with GitHub's security dashboard. The reference documentation in docs/tutorials/integrations/github-actions.md provides additional configuration options for scanning filesystems and repositories.

GitLab CI Integration

Trivy supports GitLab CI through both the built-in Container-Scanning template and custom job definitions that offer granular control over scan parameters and caching.

Using the Official Template

GitLab includes Trivy in its managed Container-Scanning template, which automatically produces a container_scanning report artifact visible in the GitLab Security Dashboard. Alternatively, implement a custom job as defined in docs/tutorials/integrations/gitlab-ci.md:

stages:
  - test

trivy:
  stage: test
  image: docker:stable
  services:
    - name: docker:dind
      entrypoint: ["env", "-u", "DOCKER_HOST"]
      command: ["dockerd-entrypoint.sh"]
  variables:
    DOCKER_HOST: tcp://docker:2375/
    TRIVY_NO_PROGRESS: "true"
    TRIVY_CACHE_DIR: ".trivycache/"
  before_script:
    - |
      export TRIVY_VERSION=$(wget -qO - "https://api.github.com/repos/aquasecurity/trivy/releases/latest" \
        | grep '"tag_name":' | sed -E 's/.*"v([^"]+)".*/\1/')
    - wget --no-verbose https://github.com/aquasecurity/trivy/releases/download/v${TRIVY_VERSION}/trivy_${TRIVY_VERSION}_Linux-64bit.tar.gz \
        -O - | tar -zxvf -
  script:
    - ./trivy image --exit-code 0 --format template \
        --template "@/contrib/gitlab.tpl" -o gl-container-scanning-report.json $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
    - ./trivy image --exit-code 1 --severity CRITICAL $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
  artifacts:
    reports:
      container_scanning: gl-container-scanning-report.json
  cache:
    paths:
      - .trivycache/

This configuration downloads the latest Trivy release dynamically, uses the GitLab-specific template (@/contrib/gitlab.tpl) for report formatting, and separates the reporting scan (--exit-code 0) from the enforcement scan (--exit-code 1 --severity CRITICAL) to ensure pipelines fail only on critical vulnerabilities while still capturing all findings for review.

Jenkins Integration

While no official Jenkins plugin exists in the aquasecurity/trivy repository, you can integrate Trivy into Declarative Pipelines by executing the Docker image directly on your Jenkins agents.

Docker-Based Pipeline Scanning

Mount the Docker socket to allow Trivy to access the local image daemon, then archive the results and parse them to enforce security gates:

pipeline {
    agent any
    stages {
        stage('Trivy Scan') {
            steps {
                sh 'docker pull aquasec/trivy:latest'
                sh '''
                    docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
                        aquasec/trivy image --exit-code 0 --severity HIGH \
                        myapp:latest > trivy-report.txt
                '''
                archiveArtifacts artifacts: 'trivy-report.txt', onlyIfSuccessful: false
                script {
                    def exitCode = sh script: "grep -q 'HIGH' trivy-report.txt && echo 1 || echo 0", returnStatus: true
                    if (exitCode != 0) {
                        error "Trivy detected HIGH severity vulnerabilities."
                    }
                }
            }
        }
    }
}

This approach pulls the latest aquasec/trivy image, scans the target image with --severity HIGH threshold, archives the text report for manual inspection, and programmatically fails the build if high-severity vulnerabilities are detected.

Controlling Pipeline Behavior with Exit Codes

All three platforms utilize Trivy's exit code logic to control pipeline flow:

  • --exit-code 0 – Always returns success; use this when you want to generate reports without failing the build.
  • --exit-code 1 – Returns failure if vulnerabilities are found; combine with --severity flags (e.g., CRITICAL, HIGH) to fail only on specific risk levels.

This mechanism allows you to implement break-glass patterns where the pipeline generates security artifacts for every build but only blocks deployment for severe findings.

Summary

  • GitHub Actions: Use aquasecurity/trivy-action@master to scan images or filesystems and upload SARIF results directly to GitHub Code Scanning.
  • GitLab CI: Leverage the Container-Scanning template or custom jobs with @/contrib/gitlab.tpl templates to generate native GitLab security reports with proper artifact caching.
  • Jenkins: Execute the aquasec/trivy Docker image with socket mounts, archive text/JSON reports, and use shell scripts to parse results and enforce build failures.
  • Common pattern: Install Trivy, run the scan with appropriate severity filters, check exit codes, and publish reports in platform-native formats.

Frequently Asked Questions

How do I prevent Trivy from failing my CI pipeline on low-severity vulnerabilities?

Configure the --severity flag to specify which vulnerability levels should trigger a non-zero exit code. For example, use --severity HIGH,CRITICAL to fail only on high and critical findings, while allowing the scan to pass (exit code 0) for low and medium vulnerabilities. You can also run two separate scans: one with --exit-code 0 for reporting all findings, and one with --exit-code 1 --severity CRITICAL for enforcement.

Can Trivy scan source code before I build a container image?

Yes. Use trivy fs <path> to scan the filesystem and repository for vulnerabilities in application dependencies and IaC misconfigurations. In GitHub Actions, set scan-type: 'fs' in the trivy-action inputs. For GitLab CI and Jenkins, replace the trivy image command with trivy fs . to analyze the checked-out source code prior to image build steps.

Where does Trivy store its vulnerability database in CI environments?

Trivy downloads vulnerability databases to a local cache directory, which defaults to a system temp folder. In ephemeral CI runners, define the TRIVY_CACHE_DIR environment variable (e.g., TRIVY_CACHE_DIR: ".trivycache/") and configure your pipeline's cache mechanism to preserve this directory between jobs. This prevents redundant database downloads and speeds up subsequent scans, as demonstrated in the GitLab CI example.

What report formats should I use for different CI platforms?

SARIF (Static Analysis Results Interchange Format) is optimal for GitHub Actions because GitHub Code Scanning natively consumes it. GitLab Container-Scanning JSON (produced via the @/contrib/gitlab.tpl template) is required for GitLab's security dashboard integration. For Jenkins, JSON or plain text formats work best, allowing you to archive artifacts and parse results using shell commands or the Jenkins Warnings Next Generation plugin.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →