Safeguard
Security

Trivy Action: How to Use It in CI Without Getting Burned

The Trivy Action runs Aqua Security's scanner inside GitHub Actions. Here is how to wire it up, and why aquasecurity/trivy-action@master is the wrong way to pin it.

Marcus Chen
DevSecOps Engineer
5 min read

The Trivy Action is the official GitHub Action that runs Aqua Security's Trivy scanner inside your CI pipeline, and the most important thing to get right is how you pin it: never reference aquasecurity/trivy-action@master, always pin to a specific commit SHA. Trivy itself is an excellent, fast scanner for container images, filesystems, and infrastructure-as-code. The action wraps it for GitHub Actions, and the wrapper is where the interesting security decisions live.

This guide covers a working setup and, more importantly, the supply-chain hygiene that keeps the scanner from becoming the thing that gets you compromised.

What the Trivy Action Does

Trivy scans for known vulnerabilities in OS packages and language dependencies, misconfigurations in Terraform and Kubernetes manifests, exposed secrets, and license issues. The GitHub Action lets you run any of those scans as a workflow step and fail the build on findings.

A minimal image scan looks like this:

- name: Run Trivy vulnerability scanner
  uses: aquasecurity/trivy-action@<pinned-sha>
  with:
    image-ref: 'myorg/api:${{ github.sha }}'
    format: 'table'
    exit-code: '1'
    severity: 'CRITICAL,HIGH'

The exit-code: '1' combined with the severity filter is what turns the scan from informational into a gate: the job fails when a critical or high vulnerability is present.

Why You Should Not Use @master

It is tempting to write uses: aquasecurity/trivy-action@master and forget about it. Do not. A branch reference like @master means your pipeline runs whatever the tip of that branch is at execution time, which you do not control and cannot review.

This is not hypothetical. The trivy-action repository was the subject of a supply-chain incident involving a manipulated commit, and when users asked whether workflows pinned to @master had been safe, a Trivy maintainer publicly acknowledged they could not guarantee it, because the origin of the malicious commit was unclear. That is the whole problem with mutable references: you are trusting a moving target inside a job that often has access to your registry credentials and code.

Pin to a Commit SHA

The secure pattern is to pin the action to an immutable commit SHA and document which version it corresponds to:

- name: Run Trivy vulnerability scanner
  # v0.x tag corresponds to this commit; SHA is immutable
  uses: aquasecurity/trivy-action@<full-40-char-sha>
  with:
    image-ref: 'myorg/api:${{ github.sha }}'
    exit-code: '1'
    severity: 'CRITICAL,HIGH'

Version tags like @v0.36.0 are better than @master but still not ideal, because tags can be moved to point at a different commit. A full commit SHA cannot be rewritten to mean something else. Tools like Dependabot can keep pinned SHAs updated with pull requests, so you get both immutability and a review-gated upgrade path. This same principle applies to every third-party action in your workflows, not just Trivy.

Scanning More Than Images

The action handles several scan types through the scan-type input. Beyond image, you can scan your repository filesystem and infrastructure-as-code:

- name: Scan IaC and filesystem
  uses: aquasecurity/trivy-action@<pinned-sha>
  with:
    scan-type: 'fs'
    scan-ref: '.'
    scanners: 'vuln,secret,misconfig'

Running the misconfig scanner against Terraform and Kubernetes files catches issues like privileged containers or public storage buckets before they deploy. The secret scanner catches credentials committed to the repo. Combining these in one step gives broad coverage per pipeline run.

Uploading Results to GitHub Security

Rather than only failing the build, feed findings into GitHub's Security tab using SARIF output so they show up as code-scanning alerts:

- name: Run Trivy in SARIF mode
  uses: aquasecurity/trivy-action@<pinned-sha>
  with:
    image-ref: 'myorg/api:${{ github.sha }}'
    format: 'sarif'
    output: 'trivy-results.sarif'
- name: Upload to GitHub Security
  uses: github/codeql-action/upload-sarif@<pinned-sha>
  with:
    sarif_file: 'trivy-results.sarif'

This gives you a tracked, deduplicated view of findings over time instead of scrollback in a build log.

Handling Noise and Rate Limits

Two practical annoyances come up. First, Trivy downloads its vulnerability database on each run, and unauthenticated pulls can hit rate limits; cache the DB or authenticate the pull to avoid flaky builds. Second, a fresh scan can surface a wall of findings. Start by gating only on CRITICAL,HIGH with an available fix, and use a .trivyignore file to suppress accepted findings with a documented reason and expiry. Suppressing without a note is how ignore files rot into blanket exceptions.

Where the Trivy Action Fits

Trivy in CI is strong at catching known vulnerabilities in images and IaC, which makes it a solid build-time gate. It complements, rather than replaces, deeper software composition analysis of your application dependency graph and dynamic testing of the running app. A layered pipeline runs container scanning at build, SCA across the full dependency tree, and DAST against a deployed staging environment. If you want worked examples of chaining these gates, the Safeguard Academy has pipeline recipes.

FAQ

Is aquasecurity/trivy-action@master safe to use?

No. Referencing @master runs whatever is at the branch tip when your job executes, which you cannot review or control. The repository has been the target of a supply-chain incident, and maintainers could not guarantee @master users were unaffected. Pin to a commit SHA instead.

How should I pin the Trivy Action?

Pin to a full 40-character commit SHA, which is immutable, and note the corresponding version in a comment. Version tags are better than a branch but can still be moved. Let Dependabot open pull requests to bump the pinned SHA through review.

What can the Trivy Action scan?

Container images, repository filesystems, and infrastructure-as-code, with scanners for vulnerabilities, secrets, and misconfigurations. You select behavior with the scan-type and scanners inputs.

How do I make the Trivy Action fail the build?

Set exit-code: '1' and filter with severity (for example CRITICAL,HIGH) so the job fails only on the severities you care about. Combine that with a documented .trivyignore file for accepted findings to control noise.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.