Trivy can scan container images, filesystems, and Git repositories for vulnerabilities and misconfigurations, and it’s designed to be integrated into your DevSecOps workflow.

Let’s see Trivy in action scanning a container image. Imagine you’ve just built a new Docker image for your web application. You want to ensure it’s free of known vulnerabilities before pushing it to your registry.

trivy image --severity HIGH,CRITICAL --output results.json --format json your-docker-repo/your-app:latest

This command tells Trivy to scan the your-docker-repo/your-app:latest image. It’s specifically looking for vulnerabilities marked as HIGH or CRITICAL and will output the findings in a JSON format to a file named results.json.

Now, let’s break down how this fits into a typical DevSecOps workflow.

The Problem: Security Gaps in the Pipeline

Traditionally, security scanning happened late in the development cycle, often just before deployment. This meant that if significant vulnerabilities were found, it could cause major delays, requiring developers to scramble to fix issues that might have been easier to address earlier. The goal of integrating security earlier, or "shifting left," is to catch these problems when they are cheapest and easiest to fix.

Trivy’s Role: Continuous Scanning

Trivy can be deployed at multiple stages:

  1. Local Development: Developers can run Trivy on their local machine against code or container images they’re building. This provides immediate feedback.

    trivy fs --severity HIGH --exit-code 1 .
    

    This command scans the current directory (.) for high-severity vulnerabilities. The --exit-code 1 is crucial for CI/CD integration: if any vulnerabilities are found, the command will exit with a non-zero status, failing the build or pipeline step.

  2. CI/CD Pipeline (Build Stage): After code is committed and a new container image is built, Trivy scans the image. This is often the first automated gate.

    trivy image --severity HIGH --output image-scan.sarif --format sarif your-docker-repo/your-app:build-$(git rev-parse --short HEAD)
    

    Here, we’re scanning the newly built image, outputting in SARIF format (a standard for security tool output) for potential integration with other security platforms. The image tag is dynamically set using the Git commit hash for traceability.

  3. CI/CD Pipeline (Registry Scan): Before an image is deployed, a final scan on the image stored in the container registry can be performed as a secondary check.

    trivy image --severity CRITICAL --reset --cache-dir /tmp/trivy-cache your-docker-repo/your-app:latest
    

    The --reset flag ensures that Trivy uses the latest vulnerability database, and --cache-dir helps speed up subsequent scans by storing downloaded data.

  4. Kubernetes Deployments: Trivy can scan Kubernetes cluster configurations and running workloads for misconfigurations and vulnerabilities.

    trivy k8s --severity MEDIUM --namespaces default --report summary
    

    This command scans resources in the default namespace for medium-severity issues and provides a summary report.

Internal Mechanics: How Trivy Finds Issues

Trivy works by downloading vulnerability databases (like CVE databases from NVD, OS vendor advisories, and language-specific package managers) and configuration best practices. When you scan an artifact, Trivy analyzes its contents:

  • Container Images: It inspects the base image, installed packages (OS packages, application dependencies like npm, pip, Maven), and environment variables. It then correlates the versions of these components against its downloaded vulnerability databases. For misconfigurations, it checks image layers for common insecure practices.
  • Filesystems: It traverses the directory, identifying installed packages and configuration files, performing the same correlation against its databases.
  • Git Repositories: It scans files for secrets and checks IaC (Infrastructure as Code) files (like Terraform, CloudFormation, Kubernetes manifests) for misconfigurations based on predefined policies.

The power of Trivy lies in its speed and comprehensive database. It’s designed to be fast enough to run in a CI pipeline without significantly delaying builds.

When Trivy reports a vulnerability, it provides crucial details: the vulnerability ID (e.g., CVE-2023-12345), the affected package and version, the fixed version, and a severity score. This allows developers to quickly understand the risk and apply the necessary patch.

One aspect that often surprises people is how Trivy handles different package managers and language ecosystems within a single container image. It doesn’t just scan the OS packages; it can also detect and scan vulnerabilities in application dependencies installed via npm, pip, yarn, composer, gem, maven, gradle, and more, all from a single scan command. This deep inspection across multiple layers of software composition is what makes it so effective for identifying the full attack surface of an application.

The next step in enhancing your DevSecOps workflow would be to implement automated remediation or policy enforcement based on Trivy’s findings.

Want structured learning?

Take the full Trivy course →