Vulnerability Scanning
Every pushed image is scanned for CVEs automatically — there is no “start scan” command. vuln reads the report for one artifact.
vuln
dodil registry vuln <repo> <reference><reference> is a tag or a digest. Aliases: vulnerabilities, scan.
dodil registry vuln web 1.2.0scan: Success severity: High total: 12 fixable: 7
CVE SEVERITY PACKAGE VERSION FIX
CVE-2026-1234 High openssl 3.0.11 3.0.14
CVE-2025-8842 Medium zlib 1.2.13 1.3
...Reading the report
The overview line first:
| Field | Meaning |
|---|---|
scan | Scanner status for this artifact — whether the push-time scan has completed |
severity | The worst finding: Critical > High > Medium > Low > Negligible > None (or Unknown) |
total | Number of vulnerabilities found |
fixable | How many have a fix_version available |
Then one row per CVE: id, severity, the affected package and installed version, and the version that fixes it (empty if no fix is released yet). The JSON form adds description and links (advisory URLs) per CVE:
dodil registry vuln web 1.2.0 -o json{
"scan_status": "Success",
"severity": "High",
"total": 12,
"fixable": 7,
"vulnerabilities": [
{
"id": "CVE-2026-1234",
"severity": "High",
"package": "openssl",
"version": "3.0.11",
"fix_version": "3.0.14",
"description": "…",
"links": ["https://nvd.nist.gov/vuln/detail/CVE-2026-1234"]
}
]
}If the scan hasn’t finished yet (a push seconds ago), re-run after a moment — the artifact list’s SCAN column shows the same overview once it lands.
Gate CI on severity
-o json + jq makes a fail-the-build check one line:
# Fail when the image has any Critical finding
dodil registry vuln web "$TAG" -o json \
| jq -e '(.severity | ascii_downcase) != "critical"'Or gate on fixable count:
dodil registry vuln web "$TAG" -o json | jq -e '.fixable == 0'See Push from CI for the full pipeline, including auth with a dk_ API key.