Vulnerability Scanning of Container Images with GitHub Actions

Automated Vulnerability Scanning in CI/CD

Security has become a crucial part of every DevOps workflow. With applications running in containers, securing images before deploying them is more important than ever. Imagine deploying an application only to discover later that the container image had critical vulnerabilities. That single mistake can put the entire system at risk.

To address this, you can integrate Trivy, an open-source vulnerability scanner, with GitHub Actions. This setup scans every container image automatically during the CI/CD process. If it finds critical issues, the pipeline fails and blocks insecure images from being pushed further

Watch the full walkthrough here:

Why Vulnerability Scanning Matters

Container images often include operating system libraries, dependencies, and third-party packages. Any of these may contain known vulnerabilities. Without an automated scanning step, there is a chance of deploying applications with security risks. By adding Trivy to the pipeline, you catch risks early and save both time and effort in fixing them.

Workflow Overview

The GitHub Actions pipeline in this setup:

  1. Pull the latest code from the repository
  2. Build a Docker image from the project files
  3. Scan the image using Trivy
  4. Fails the workflow if it detects critical vulnerabilities
  5. Upload the scan report as an artifact for later review

The entire process runs automatically whenever code is pushed or a pull request is created.

Setting Up Image Scanning in GitHub Actions

For this guide, I have used a self-hosted runner. That choice allows tighter control over the runtime (Docker engine, CPU/RAM) and often results in quicker builds.
If you haven’t created a runner yet, do that first— using this guide.

Let’s break down the workflow step by step:

1. Triggering the Workflow

The pipeline is triggered on every push or pull_request to the main branch. This ensures that no new change goes unchecked.

2. Building the Docker Image

Pulls the latest code from the repository and builds a Docker image. For this example, the image is tagged as myapp:latest.

3. Running the Trivy Scan

Uses Trivy to scan the image. The scan looks for vulnerabilities marked as HIGH and CRITICAL. Fails the job immediately if it finds critical issues.

4. Uploading the Scan Report

Even if the job fails, the scan report is uploaded as an artifact. This allows developers to download it later, review details of the vulnerabilities, and apply fixes.

Workflow File

name: Container Image Vulnerability Scan

on:
  push:
    branches:
      - main
  pull_request:
    branches:
      - main

jobs:
  security_scan:
    runs-on: self-hosted 

    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Build Docker Image
        run: |
          sudo docker build -t myapp:latest .

      - name: Generate Trivy Reports (Before Failing)
        run: |
          sudo trivy image --format json -o trivy-results.json myapp:latest
          sudo trivy image --severity HIGH,CRITICAL myapp:latest | tee trivy-report.txt

      - name: Upload Trivy Reports
        uses: actions/upload-artifact@v4  
        with:
          name: trivy-reports
          path: |
            trivy-report.txt
            trivy-results.json
          retention-days: 7

      - name: Fail if Critical Vulnerabilities Found
        run: |
          sudo trivy image --exit-code 1 --severity CRITICAL myapp:latest

Running the Workflow

After you push changes, the workflow builds the image, runs the scan, and shows the results directly in the Actions tab. If critical vulnerabilities appear, the workflow fails, proving that the pipeline successfully blocked an insecure image.

You can then download the uploaded report, review the exact issues, and apply the necessary fixes.

Conclusion

Integrating Trivy with GitHub Actions turns container image scanning into an automatic step in the development workflow. Instead of pushing images with hidden risks, the pipeline stops them early and gives teams the chance to fix issues before release.

Making security checks part of CI/CD is no longer optional, it’s a habit every DevOps team should adopt.

You can explore the full workflow and other examples in my GitHub repository here: My Github Actions Code Repository

For a deeper dive, check out my playlist: GitHub Actions: Basics to Advanced

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top