Scan Docker Hardened Images
Docker Hardened Images (DHIs) are designed to be secure by default, but like any container image, it's important to scan them regularly as part of your vulnerability management process.
You can scan DHIs using the same tools you already use for standard images, such as Docker Scout, Grype, and Trivy. DHIs follow the same formats and standards for compatibility across your security tooling. Before you scan an image, the image must be mirrored into your organization on Docker Hub.
メモDocker Scout is automatically enabled at no additional cost for all mirrored Docker Hardened Image repositories on Docker Hub. You can view scan results directly in the Docker Hub UI under your organization's repository.
Docker Scout
Docker Scout is integrated into Docker Desktop and the Docker CLI. It provides vulnerability insights, CVE summaries, and direct links to remediation guidance.
Scan a DHI using Docker Scout
To scan a Docker Hardened Image using Docker Scout, run the following command:
$ docker scout cves <your-namespace>/dhi-<image>:<tag> --platform <platform>
Example output:
v SBOM obtained from attestation, 101 packages found
v Provenance obtained from attestation
v VEX statements obtained from attestation
v No vulnerable package detected
...
For more detailed filtering and JSON output, see Docker Scout CLI reference.
Automate DHI scanning in CI/CD with Docker Scout
Integrating Docker Scout into your CI/CD pipeline enables you to automatically verify that images built from Docker Hardened Images remain free from known vulnerabilities during the build process. This proactive approach ensures the continued security integrity of your images throughout the development lifecycle.
Example GitHub Actions workflow
The following is a sample GitHub Actions workflow that builds an image and scans it using Docker Scout:
name: DHI Vulnerability Scan
on:
push:
branches: [ main ]
pull_request:
branches: [ "**" ]
env:
REGISTRY: docker.io
IMAGE_NAME: ${{ github.repository }}
SHA: ${{ github.event.pull_request.head.sha || github.event.after }}
jobs:
scan:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
pull-requests: write
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build Docker image
run: |
docker build -t ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ env.SHA }} .
- name: Run Docker Scout CVE scan
uses: docker/scout-action@v1
with:
command: cves
image: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ env.SHA }}
only-severities: critical,high
exit-code: true
The exit-code: true
parameter ensures that the workflow fails if any critical or
high-severity vulnerabilities are detected, preventing the deployment of
insecure images.
For more details on using Docker Scout in CI, see Integrating Docker Scout with other systems.
Comparing Docker Scout results with other scanners
Some vulnerabilities reported by other scanners may not appear in Docker Scout results. This can happen for several reasons:
- Hardware-specific vulnerabilities: Certain vulnerabilities may only affect specific hardware architectures (for example, Power10 processors) that are not relevant to Docker images, so they are not reported by Docker Scout.
- VEX statement filtering: Docker Scout automatically applies VEX statements to document and suppress vulnerabilities that do not apply to the image. If your scanner does not consume VEX statements, you may see more vulnerabilities reported than what appears in Docker Scout results.
- Temporary vulnerability identifiers: Temporary vulnerability identifiers (like
TEMP-xxxxxxx
from Debian) are not surfaced by Docker Scout, as they are not intended for external reference.
While Docker Scout handles this filtering automatically, you can manually configure similar filtering with other
scanners using Grype ignore rules in its configuration
file (~/.grype.yaml
) or Trivy policy exceptions using
REGO rules to filter out specific vulnerabilities by CVE ID, package name, fix state, or other criteria. You can also
use VEX statements with other scanners as described in Use VEX to filter known non-exploitable
CVEs.
Grype
Grype is an open-source scanner that checks container images against vulnerability databases like the NVD and distro advisories.
Scan a DHI using Grype
After installing Grype, you can scan a Docker Hardened Image by pulling the image and running the scan command:
$ docker pull <your-namespace>/dhi-<image>:<tag>
$ grype <your-namespace>/dhi-<image>:<tag>
Example output:
NAME INSTALLED FIXED-IN TYPE VULNERABILITY SEVERITY EPSS% RISK
libperl5.36 5.36.0-7+deb12u2 (won't fix) deb CVE-2023-31484 High 79.45 1.1
perl 5.36.0-7+deb12u2 (won't fix) deb CVE-2023-31484 High 79.45 1.1
perl-base 5.36.0-7+deb12u2 (won't fix) deb CVE-2023-31484 High 79.45 1.1
...
You should include the --vex
flag to apply VEX statements during the scan,
which filter out known non-exploitable CVEs. For more information, see the VEX
section.
Trivy
Trivy is an open-source vulnerability scanner for containers and other artifacts. It detects vulnerabilities in OS packages and application dependencies.
Scan a DHI using Trivy
After installing Trivy, you can scan a Docker Hardened Image by pulling the image and running the scan command:
$ docker pull <your-namespace>/dhi-<image>:<tag>
$ trivy image <your-namespace>/dhi-<image>:<tag>
Example output:
Report Summary
┌──────────────────────────────────────────────────────────────────────────────┬────────────┬─────────────────┬─────────┐
│ Target │ Type │ Vulnerabilities │ Secrets │
├──────────────────────────────────────────────────────────────────────────────┼────────────┼─────────────────┼─────────┤
│ <namespace>/dhi-<image>:<tag> (debian 12.11) │ debian │ 66 │ - │
├──────────────────────────────────────────────────────────────────────────────┼────────────┼─────────────────┼─────────┤
│ opt/python-3.13.4/lib/python3.13/site-packages/pip-25.1.1.dist-info/METADATA │ python-pkg │ 0 │ - │
└──────────────────────────────────────────────────────────────────────────────┴────────────┴─────────────────┴─────────┘
You should include the --vex
flag to apply VEX statements during the scan,
which filter out known non-exploitable CVEs. For more information, see the VEX
section.
Use VEX to filter known non-exploitable CVEs
Docker Hardened Images include signed VEX (Vulnerability Exploitability eXchange) attestations that identify vulnerabilities not relevant to the image’s runtime behavior.
When using Docker Scout, these VEX statements are automatically applied and no manual configuration needed.
メモBy default, VEX attestations are fetched from
registry.scout.docker.com
. Ensure that you can access this registry if your network has outbound restrictions. You can also mirror the attestations to an alternate registry. For more details, see Mirror a Docker Hardened Image repository.
To manually create a JSON file of VEX attestations for tools that support it:
$ docker scout vex get <your-namespace>/dhi-<image>:<tag> --output vex.json
メモThe
docker scout vex get
command requires Docker Scout CLI version 1.18.3 or later.If the image exists locally on your device, you must prefix the image name with
registry://
. For example, useregistry://docs/dhi-python:3.13
instead ofdocs/dhi-python:3.13
.
For example:
$ docker scout vex get docs/dhi-python:3.13 --output vex.json
This creates a vex.json
file containing the VEX statements for the specified
image. You can then use this file with tools that support VEX to filter out
known non-exploitable CVEs.
For example, with Grype and Trivy, you can use the --vex
flag to apply the VEX
statements during the scan:
$ grype <your-namespace>/dhi-<image>:<tag> --vex vex.json