Github: security scanning built into GitHub Actions image build

Github Actions provide the ability to define a build workflow, and for projects that are building an OCI (Docker) image, there are custom actions available for running the Trivy container security scanner.

In this article, I will show you how to modify your GitHub Action to run the Trivy security scanner against your image, and then add that vulnerability report as an artifact that can assist in remediation.

Custom action for Trivy image scanner

Trivy, the open-source scanner, has a custom GitHub Action that can be called from within the Action definition.  This is a snippet from my example ‘.github/workflows/github-actions-buildOCI.yml‘.

# define registry and image name
env:
  GH_REGISTRY: ghcr.io # Github Container Registry
  FULL_IMAGE_NAME: ${{ github.repository }} # full image name: owner/image

...
      # actions building latest image
...

      - name: Run Trivy vulnerability scanner
        uses: aquasecurity/trivy-action@0.24.0
        with:
          image-ref: ${{ env.GH_REGISTRY }}/${{ env.FULL_IMAGE_NAME }}:latest
          format: table
          output: trivy-scan-results.txt
          exit-code: '0' # '1' would cause pipeline to fail if vulnerabilities found
          ignore-unfixed: true
          scanners: vuln
          vuln-type: 'os,library'
          severity: 'CRITICAL,HIGH,MEDIUM,LOW'

This will scan at the application library and OS level for any vulnerability from LOW to CRITICAL level.  It will not fail if it finds a vulnerability at these levels, it will just create a report named “trivy-scan-results.txt”.

Custom action to upload report as artifact

So these vulnerabilities can be addressed and remediated, we are going upload the report created in the last step as an artifact to the Action.  This will create a persistent (90 day retention), record of the risk profile of this published image.

      - name: Upload trivy report as a Github Action artifact
        uses: actions/upload-artifact@v4
        with:
          name: trivy-report
          path: '${{ github.workspace }}/trivy-scan-results.txt'

This artifact can be seen on the details page of each build as shown below.

Example Reports

As an example of the vulnerability reports that are generated, here is an example when my Dockerfile intentionally uses an older Go version in the multi-stage build and older Debian 11 (bullseye) build as a final runtime.

# Go 1.23 is latest at time of this writing, use older version
FROM golang:1.21.13-alpine3.19 AS builder
...
# bookworm(12) is latest as of this writing, use older version
FROM debian:bullseye-20240812-slim

Based on these results, I can remediate the vulnerabilities by using the latest Go 1.23 and a distroless Debian 12 (bookworm) to minimize the attack surface.

# latest version of Go
FROM golang:1.23.1-alpine3.20 AS builder
...
# distroless version of latest Debian
FROM gcr.io/distroless/base-debian12

And now the vulnerability results are clean.

 

REFERENCES

Trivy GitHub action

mafiaguy, how to embed Trivy into GitHub Actions

distroless Debian 12