Dockle Integration with DefectDojo
Dockle Integration with DefectDojo
Dockle is an open source container image linter written in Go and maintained by goodwithtech on GitHub. Instead of looking for vulnerable packages, it inspects a built image's configuration and file system for risky build practices: running as root, missing HEALTHCHECK instructions, credentials left in environment variables or files, setuid and setgid binaries, use of the latest tag, and package manager caches left behind. Its checks combine image-related items from the CIS Docker Benchmark (codes beginning CIS-DI) with Dockle's own rules (codes beginning DKL), each reported at a level of FATAL, WARN, or INFO. Dockle can write its results as JSON, which DefectDojo imports.
Dockle Integration with DefectDojo
We run Dockle next to our image vulnerability scanner because a clean CVE report says nothing about whether the image runs as root or ships a setuid binary it doesn't need. On its own, Dockle prints a list and exits. Importing Dockle JSON into DefectDojo gives each failed check a Finding on the Asset that owns the image, tracked across rebuilds, so a WARN that has been ignored for six releases is visible as exactly that.
Why Dockle Matters
Image configuration problems are cheap to fix at build time and expensive to find in production, and vulnerability scanners don't report them.
- Dockle checks what was actually built, not just the Dockerfile, so it catches settings inherited from a base image.
- Its CIS-based checks give a recognizable reference for container image hardening.
- It flags likely secrets in image files and environment variables, which are easy to bake in by accident.
- It is fast and has no server component, so it fits into any image build pipeline.
- Dockle has no history of its own. Without a tracking system, each build's output replaces the last one.
Advantages of This Integration
What we gained by importing Dockle results into DefectDojo:
- Rebuilds don't multiply findings. DefectDojo hashes Dockle findings on title, description, and the Dockle check code, so the same check failing the same way on the next build is recognized as the same finding.
- Fixes are recorded. Reimporting the next build's report into the same Test mitigates checks that now pass and adds new failures.
- Image hygiene next to image CVEs. Dockle findings sit on the same Asset as findings from container vulnerability scanners, so one view covers both what is in the image and how it was built.
- Accepted exceptions stay documented. A check that doesn't apply, such as a HEALTHCHECK on an image orchestrated with its own probes, can be risk-accepted with a reason instead of silently ignored.
- Ownership. Each finding can be assigned to the team that owns the Dockerfile and pushed to Jira.
How This Integration Works
DefectDojo imports Dockle results with the Dockle Scan scan type, which reads Dockle's JSON output.
1. Run Dockle with JSON output. Point it at a local or registry image and write the report to a file:
dockle -f json -o dockle-report.json registry.example.com/payments-api:2.3.0
2. Import the report. In the UI, open the Engagement, choose Import Scan Results, select Dockle Scan, and upload the file. To automate, use the import API in Community Edition or DefectDojo Pro:
curl "https://YOUR_INSTANCE/api/v2/import-scan/" \
-H "Authorization: Token $DD_API_TOKEN" \
-F "scan_type=Dockle Scan" \
-F "file=@dockle-report.json" \
-F "product_name=payments-api" \
-F "engagement_name=Image Builds" \
-F "tags=payments-api,2.3.0" \
-F "auto_create_context=true"
DefectDojo Pro users can run the same import with Universal Importer:
universal-importer import \
--defectdojo-url "https://YOUR_INSTANCE.cloud.defectdojo.com/" \
--scan-type "Dockle Scan" \
--report-path "./dockle-report.json" \
--product-name "payments-api" \
--engagement-name "Image Builds" \
--auto-create-context
3. Reimport on each build. Send later reports for the same image to /api/v2/reimport-scan/ against the same Test so passing checks close and new failures appear.
The parser reads the details array of the report. Entries at level IGNORE, which Dockle uses for checks you have told it to ignore, are skipped. Passing checks are not listed in details, so they produce no findings.
Data Granularity: What Gets Imported
| DefectDojo Field | Source in Dockle Report | Notes |
|---|---|---|
| Title | code, title |
Formatted as code: title, for example a CIS-DI check and its name |
| Severity | level |
FATAL is High; WARN is Medium; INFO is Low; any other level defaults to Medium |
| Skipped entries | level |
IGNORE entries are not imported |
| Description | alerts |
The check's alert messages, sorted and one per line |
| Vulnerability ID from tool | code |
The Dockle check code |
| Occurrences | Repeated entries | Entries with the same code and title count as one finding |
| Finding type | Static | Image analysis, not runtime testing |
| Deduplication | Hashcode | Title, description, vulnerability ID from tool |
Dockle doesn't provide remediation text, CWE, or file path fields in its JSON, so those DefectDojo fields stay empty. The check code and title are usually enough to find Dockle's guidance for the rule.
Use Cases
In an image build pipeline: Every image build runs Dockle after the build step and reimports into a Test for that image. A pipeline gate can fail the build on new High findings (Dockle FATAL) while existing, risk-accepted ones don't block releases.
Standardizing base images: A platform team maintains a set of approved base images. Importing Dockle results for each one shows which checks the base images already fail, so application teams aren't blamed for problems they inherited.
Catching secrets in images: When Dockle reports a suspicious file or environment variable, the finding gets an owner and an SLA in DefectDojo, and the description lists exactly what Dockle matched so the team can rebuild without it.
Reporting on container hygiene: Security leads can compare open Dockle findings across Assets to see which teams still ship images that run as root.
Operational Tips
- The description is part of the hashcode, and for some checks it lists files found in the image (setuid binaries, for example). If the image contents change, that finding can appear as new on reimport, so close the old one when it does.
- Because the hashcode doesn't include the image name, keep each image in its own Engagement and import with
deduplication_on_engagement=true, or give each image its own Asset. Otherwise identical results from two images in one Asset are flagged as duplicates. - Dockle's highest level maps to High, not Critical. Set your SLA expectations for image hygiene with that in mind.
- Record intentional exceptions in DefectDojo with risk acceptance and an expiry, rather than only in Dockle's ignore settings, so the decision is visible to reviewers.
- Tag imports with the image name and tag to filter findings by release.
- If you also gate builds with Dockle's own
--exit-codeand--exit-leveloptions, write the JSON report before the gate fails the job, so the import step still runs and DefectDojo records the failure. - Pair Dockle with a container vulnerability scanner on the same Asset. Dockle doesn't look for CVEs.