Trivy’s API lets you integrate vulnerability scanning directly into your CI/CD pipelines, applications, or custom workflows, treating it as a library rather than just a CLI tool.

Let’s see Trivy in action, scanning a container image and getting structured output.

curl -s -X POST -H "Content-Type: application/json" \
  --data '{"Target": "ghcr.io/aquasecurity/trivy:latest", "Scan": {"Type": "image", "Target": "ghcr.io/aquasecurity/trivy:latest"}}' \
  http://localhost:8080/scan | jq .

This command sends a POST request to a locally running Trivy API server (defaulting to http://localhost:8080). It tells Trivy to scan the ghcr.io/aquasecurity/trivy:latest container image. The jq . at the end pretty-prints the JSON output.

The output will look something like this, detailing vulnerabilities found, their severity, and where they were detected:

{
  "Results": [
    {
      "Target": "ghcr.io/aquasecurity/trivy:latest (debian 11)",
      "Class": "vulnerability",
      "Type": "debian",
      "Vulnerabilities": [
        {
          "VulnerabilityID": "CVE-2023-XXXX",
          "PkgName": "libc6",
          "InstalledVersion": "2.31-13+deb11u5",
          "FixedVersion": "2.31-13+deb11u6",
          "Severity": "HIGH",
          "Title": "...",
          "Description": "...",
          "PrimaryURL": "...",
          "DataSource": {
            "Name": "debian-11",
            "URL": "..."
          },
          "References": [
            "..."
          ],
          "PublishedDate": "2023-XX-XXTXX:XX:XXZ",
          "LastModifiedDate": "2023-XX-XXTXX:XX:XXZ"
        }
        // ... more vulnerabilities
      ]
    }
    // ... other results for different package types (e.g., language-specific)
  ]
}

This structured JSON output is the key. It allows your automation tools to parse the results, make decisions (like failing a build if critical vulnerabilities are found), and integrate seamlessly. You can also specify different output formats like table or json-string directly in the API payload.

The primary problem Trivy’s API solves is the friction of integrating vulnerability scanning into automated workflows. Previously, you’d often shell out to the Trivy CLI, capture its output, and then parse it. This can be brittle, especially with complex output formats or when dealing with error conditions. The API provides a clean, programmatic interface: send a request, get structured data back.

Internally, when you send a scan request, the Trivy API server orchestrates the same scanning logic that the CLI uses. It identifies the target type (image, filesystem, Git repository, etc.), fetches necessary vulnerability databases (if not already cached), runs the appropriate scanners (OS package scanners, language-specific dependency scanners), aggregates the findings, and returns them in the requested format. The API server manages the state, including downloaded vulnerability data, allowing for faster subsequent scans.

The Scan object in the request payload is where you define the specifics of what you want scanned and how.

{
  "Target": "my-app",
  "Scan": {
    "Type": "filesystem",
    "Target": "/path/to/my/app",
    "FilePatterns": ["*.js", "package.json"],
    "SkipFiles": ["node_modules/**"]
  },
  "Policy": "data/policy.rego",
  "Options": {
    "VulnType": ["os", "library"],
    "ExitCode": 1,
    "Severity": ["CRITICAL", "HIGH"]
  }
}

Here, Type specifies filesystem, Target is the directory, FilePatterns and SkipFiles allow fine-grained control over what parts of the filesystem are analyzed. Policy lets you apply custom Open Policy Agent (OPA) policies for compliance checks. Options further refines the scan, specifying VulnType (which vulnerability types to check for), ExitCode (the exit code Trivy should return based on findings), and Severity (minimum severity to report).

The most surprising thing about Trivy’s API is how easily it abstracts away the underlying complexity of vulnerability database management and scanner execution. You don’t need to worry about fetching the latest vulnerability data for multiple OSes and languages; the API server handles it. It acts as a self-contained vulnerability intelligence service that you can query. This means your CI/CD pipeline just needs to know how to make an HTTP request and parse JSON, rather than managing Trivy’s data directories or update cycles.

The Context field in the response, often overlooked, provides crucial metadata about the scan itself, including the Trivy version used, the vulnerability database version, and the timestamp of the scan. This is invaluable for auditing and debugging.

The next step after programmatic scanning is often integrating policy-as-code for compliance checks, which Trivy’s API also supports.

Want structured learning?

Take the full Trivy course →