All integrations

Trivy Integration with DefectDojo

Trivy Integration with DefectDojo

Trivy is an open source security scanner maintained by Aqua Security. A single binary scans container images, filesystems, Git repositories, virtual machine images, and Kubernetes clusters, and reports known vulnerabilities in OS and language packages, infrastructure as code misconfigurations, exposed secrets, and software licenses. Trivy Operator, also from Aqua, runs Trivy inside a Kubernetes cluster and stores results as custom resources such as VulnerabilityReport, ConfigAuditReport, and ExposedSecretReport. Both write JSON, and DefectDojo has a parser for each.

Trivy Integration with DefectDojo

Trivy is the scanner we run everywhere: in every image build, against Terraform in pull requests, and continuously in our clusters through Trivy Operator. That breadth is also why its output needs a home. Imported into DefectDojo, each CVE, misconfiguration, and secret becomes a Finding on the Asset that owns the image or workload, deduplicated across builds, with an SLA and an owner. Trivy's vendor status for each CVE comes along, so a vulnerability the distribution says doesn't affect us arrives already mitigated.

Why Trivy Matters

Container and cloud-native environments create many places for vulnerabilities to hide, and Trivy covers most of them with one tool.

  • It finds CVEs in OS packages and in language dependencies inside images, including ones the application team never declared directly.
  • The same binary checks Dockerfiles, Kubernetes manifests, Terraform, and other IaC for misconfigurations.
  • Secret scanning catches credentials baked into image layers or committed to repositories.
  • Trivy Operator rescans workloads in the cluster, so newly published CVEs are caught in images that are already running.
  • Each scan is a snapshot. Knowing which CVEs are new this week, or which team owns them, needs a system that keeps history.

Advantages of This Integration

What we gained by running Trivy through DefectDojo:

  • Deduplication across builds. Trivy Scan findings are hashed on title, severity, vulnerability IDs, CWE, and description; Trivy Operator findings on title, severity, vulnerability IDs, and description. Rescanning an unchanged image doesn't create new findings.
  • Vendor status mapped to DefectDojo status. A Trivy status of not_affected arrives inactive, verified, and mitigated; unknown and under_investigation arrive unverified; affected and fix-pending statuses stay active and verified.
  • Fix availability. Findings record whether a fixed version exists, which lets teams separate "upgrade now" from "wait for the vendor."
  • Lifecycle through reimport. Reimporting each build's report into the same Test closes CVEs a base image update removed and reopens any that return.
  • Kubernetes context. Cluster scans and Trivy Operator reports record namespace, kind, and workload name as the finding's service, so the same CVE in two deployments is tracked separately.

How This Integration Works

There are two scan types: Trivy Scan for Trivy CLI JSON and Trivy Operator Scan for Trivy Operator custom resources.

Trivy Scan. Run Trivy with JSON output, for an image or for a cluster:

trivy image --format json --output trivy-image.json registry.example.com/orders:2.3.1
trivy k8s --report all --format json --output trivy-k8s.json

The parser accepts the current report schema (SchemaVersion 2), the older list-style format, and Kubernetes cluster reports. Filesystem, repository, and config scans use the same schema. Import in the UI with Import Scan Results, or with the API in Community Edition or DefectDojo Pro:

curl "https://YOUR_INSTANCE/api/v2/import-scan/" \
  -H "Authorization: Token $DD_API_TOKEN" \
  -F "scan_type=Trivy Scan" \
  -F "file=@trivy-image.json" \
  -F "product_name=orders" \
  -F "engagement_name=Image Builds" \
  -F "auto_create_context=true"

DefectDojo Pro users can run the same import with Universal Importer:

universal-importer import \
  --defectdojo-url "https://YOUR_INSTANCE.cloud.defectdojo.com/" \
  --scan-type "Trivy Scan" \
  --report-path "./trivy-image.json" \
  --product-name "orders" \
  --engagement-name "Image Builds" \
  --auto-create-context

Trivy Operator Scan. Export the operator's reports from the cluster as JSON. The parser accepts a single report object, a JSON array of reports, or a dictionary keyed by resource type (for example vulnerabilityreports.aquasecurity.github.io). For a whole namespace, extract the items array from the list:

kubectl get vulnerabilityreports -n payments -o json | jq '.items' > trivy-operator.json

Import it with scan_type=Trivy Operator Scan using the same API or Universal Importer commands. The DefectDojo docs also point to the community trivy-dojo-report-operator project, which pushes VulnerabilityReports to DefectDojo automatically.

Data Granularity: What Gets Imported

Trivy Scan

DefectDojo Field Source in Trivy JSON Notes
Title (vulnerabilities) VulnerabilityID, PkgName, InstalledVersion For example CVE-ID package version
Severity Severity UNKNOWN is Info; if missing, derived from CVSS (preferring the severity source, then nvd, ghsa, redhat, bitnami)
CVSS v3 / v4 CVSS vectors and scores  
Description Title, target, type, fixed version, description  
Mitigation / Fix Available FixedVersion Fix available is false when empty
Impact / Status Status Drives active, verified, and mitigated flags
CWE CweIDs First as primary; full list stored
Component / File Path Package name and version; PkgPath or Target  
Misconfigurations ID, Title, Resolution, PrimaryURL, CauseMetadata Title ID - Title; offending lines added to description
Secrets Title, Category, Match, StartLine Title Secret detected in target - title
Licenses Name, Category, PkgName, Confidence Title License detected in target - name
Tags / Service Target type and class; cluster namespace, kind, name  
Finding type Static  

Trivy Operator Scan

DefectDojo Field Source in Operator Report Notes
Vulnerabilities report.vulnerabilities Title vulnID package version; score stored as CVSS v3 score; publish date kept
Config and RBAC checks report.checks Title checkID - title; remediation and messages as mitigation
Secrets report.secrets Title Secret detected in target - title
Compliance status.detailReport, status.summaryReport Failed CIS-style checks and cluster compliance controls; marked dynamic
Service Resource namespace, kind, name, container From report labels
Tags Namespace, package type, class, check category  
Vulnerability IDs CVE or normalized AVD check ID  

SBOM reports in the operator output are ignored.

Use Cases

Image builds in CI: Every build runs trivy image and reimports into a Test for that image. Engineers see only the change from the previous build, and a release step can check DefectDojo for new Critical findings with a fix available.

Cluster-wide visibility: Trivy Operator keeps reports for running workloads in the cluster. A scheduled export reimports the reports so newly disclosed CVEs in already-deployed images become findings with owners, tagged by namespace.

IaC review: Trivy config scans of Terraform and Kubernetes manifests import as misconfiguration findings with the offending lines in the description, alongside the image CVEs for the same service.

Compliance evidence: Failed checks from Trivy Operator compliance reports are tracked as findings, so remediation of benchmark failures has the same history and SLAs as other work.

Operational Tips

  • Use one Test per image or per namespace and reimport into it. Mixing many images in one Test makes reimport close findings that still exist elsewhere.
  • Decide how to handle vendor statuses. will_not_fix, fix_deferred, and end_of_life stay active, so risk-accept them with an expiry rather than letting them age out of SLA.
  • Filter at the source if you want to. Trivy's own --ignore-unfixed and severity flags reduce what gets imported, and minimum_severity does the same on the DefectDojo side.
  • Treat secret findings as sensitive. The Match text is copied into the description, so restrict access to those Tests.
  • Tag imports with the image name and tag (for example tags=orders,2.3.1) so findings can be filtered by release.
  • Prefer CLI JSON for build-time results and Trivy Operator exports for what is running. Keeping them in separate Engagements shows the gap between what was built and what is deployed.