Trivy scan (image)
Composite action that runs trivy image inside Docker with the same hardening style as setup-db: read-only root filesystem, dropped capabilities, no-new-privileges, AppArmor docker-default, a private tmpfs on /tmp, and resource limits.
You pass a pullable image reference (e.g. alpine:3.20 or a digest). Trivy pulls and scans it inside the container. The Trivy cache from setup-db is mounted read-only at /cache (--skip-db-update avoids re-downloading the DB). Your output-dir is mounted read-write at /out; the report is written as output-file inside that directory. The report format is always SARIF (--format sarif). Trivy is always run with --offline-scan (no API calls to identify dependencies) and --exit-code 0 (the step succeeds after writing the report even when findings are present). Image layers are still pulled over the network when needed.
Image scans need network access to pull the image (and possibly layers). This action does not set --network none (unlike scan-config and scan-fs).
Prerequisites
- Docker on the runner.
- A populated Trivy cache at
cache-dir(typically from the setup-db action).
Usage
- name: Setup Trivy DB cache
id: db
uses: ./setup-db
- name: Image scan
id: scan
uses: ./scan-image
with:
image: alpine:3.20
cache-dir: ${{ steps.db.outputs.cache-dir }}
output-dir: ${{ github.workspace }}/trivy-reports
output-file: image.sarif
- name: Upload report
uses: actions/upload-artifact@v4
with:
name: trivy-image
path: ${{ steps.scan.outputs.output-path }}
Inputs
| Input | Description | Required | Default |
|---|---|---|---|
image |
Image reference to scan (pulled inside the container) | Yes | — |
cache-dir |
Trivy cache directory (mounted read-only at /cache) |
No | ${{ github.workspace }}/.trivy-cache |
output-dir |
Host directory for the report (mounted read-write at /out) |
Yes | — |
output-file |
SARIF file name only (no /); created under output-dir |
Yes | — |
trivy-version |
Trivy Docker image (digest pin recommended) | No | Same pin as setup-db / see action.yaml |
trivy-version is optional. Omit it to use the default image from action.yaml.
Outputs
| Output | Description |
|---|---|
output-path |
Absolute path to the SARIF report on the host |
Notes
- Use
cache-dirandoutput-dirunder${{ github.workspace }}(or another path the Docker daemon can bind-mount) when the job runs in a container. output-dirandcache-dirare created withmkdir -pif missing.- Local-only images (e.g. built on the host) are not supported unless they are available to the inner Docker pull (this action does not mount
docker.sock). - The step still fails if Docker or the container exits non-zero before Trivy completes (e.g. mount or runtime errors).