Files
sec-actions/scan-image
t.behrendt 1bd96bbcef
CI / Test Merge SARIF Files (pull_request) Successful in 3s
CI / Test Get Images From Files (pull_request) Successful in 4s
CI / Test Setup DB (pull_request) Successful in 6s
CI / Test scan-config (pull_request) Failing after 12s
CI / Test scan-image (pull_request) Failing after 1m0s
CI / Test scan-fs (pull_request) Failing after 1m37s
fix: ensure that cache-dir exists
2026-04-10 19:14:57 +02:00
..
2026-04-10 19:14:57 +02:00

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: ${{ runner.temp }}/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 ${{ runner.temp }}/trivy
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

  • output-dir is created with mkdir -p if missing; cache-dir must already exist.
  • 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).