dockerfile_lint Integration with DefectDojo
dockerfile_lint Integration with DefectDojo
dockerfile_lint is an open source Dockerfile linter from the Project Atomic community, written in Node.js. It checks a Dockerfile against a rule set covering build correctness and image hygiene, including rules with real security weight such as using the floating latest tag, running as root, and adding remote archives over the network. Rule sets are defined in YAML and can be replaced with your own, and the tool groups its results into error, warn, and info buckets. Its JSON output is what DefectDojo imports.
dockerfile_lint Integration with DefectDojo
We lint every Dockerfile before it builds, and dockerfile_lint gives us a rule set we can extend with our own policies, such as required labels for ownership. Importing its JSON into DefectDojo turns each rule violation into a Finding on the Asset that owns the image, with a line number, a severity based on the bucket the rule belongs to, and a link to the relevant documentation. Repeat builds deduplicate instead of piling up, and when someone pins a base image tag, the next reimport closes the finding.
Why dockerfile_lint Matters
The Dockerfile decides what ends up in production images, and small choices there have large effects later.
- A floating
latestbase tag means two builds of the same commit can ship different packages, which makes vulnerability tracking unreliable. - Running as root and fetching remote archives at build time widen the blast radius of a compromised container or a tampered download.
- Required labels, such as name and version, make it possible to trace a running container back to an owner and a release.
- Custom YAML rule files let a platform team encode its own image standards instead of relying only on defaults.
- Lint output on its own stops at the build log. It is easy to ignore and impossible to report on across many repositories.
Advantages of This Integration
What we gained by importing dockerfile_lint results into DefectDojo:
- Severity from the tool's own buckets. error maps to High, warn to Medium, and info to Low, so Dockerfile issues fall under the same SLA rules as any other finding.
- Deduplication on rule and line. DefectDojo hashes dockerfile_lint findings on title and line, so rebuilding an unchanged Dockerfile does not create duplicates.
- Clean handling of file-level rules. Rules that apply to the whole file, like a missing required label, are reported by dockerfile_lint with line
-1. DefectDojo imports these with no line instead of a meaningless one. - Documentation links included. The rule's reference URL is stored in References, so the engineer fixing the issue sees the guidance next to the finding.
- Lifecycle across builds. Reimporting into the same Test mitigates fixed rules and adds new ones.
- Ownership and reporting. Findings can be assigned, risk-accepted, pushed to Jira, and reported per Asset alongside container image CVEs.
How This Integration Works
DefectDojo imports dockerfile_lint output with the dockerfile_lint Scan scan type, which expects JSON.
1. Lint the Dockerfile and write JSON.
dockerfile_lint -f Dockerfile -j > dockerfile_lint.json
The -j flag switches output to JSON. If you maintain your own rule file, pass it on the same command so the report reflects your policy.
2. Import the file. In the UI, open the Engagement, choose Import Scan Results, select dockerfile_lint Scan, and upload the JSON. With the API, available in Community Edition and DefectDojo Pro:
curl "https://YOUR_INSTANCE/api/v2/import-scan/"
-H "Authorization: Token $DD_API_TOKEN"
-F "scan_type=dockerfile_lint Scan"
-F "file=@dockerfile_lint.json"
-F "product_name=orders-service"
-F "engagement_name=Container Builds"
-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 "dockerfile_lint Scan"
--report-path "./dockerfile_lint.json"
--product-name "orders-service"
--engagement-name "Container Builds"
--auto-create-context
3. Reimport on each build. Send later reports for the same Dockerfile to /api/v2/reimport-scan/ against the same Test.
Data Granularity: What Gets Imported
| DefectDojo Field | Source in dockerfile_lint JSON | Notes |
|---|---|---|
| Title | label and message |
Formatted as label: message; message alone when the rule has no label |
| Severity | Bucket (error, warn, info) |
error becomes High, warn becomes Medium, info becomes Low |
| Description | description, label, line, lineContent |
Rule explanation followed by labeled rule, line, and line content |
| Line | line |
Left empty when dockerfile_lint reports -1 for file-level rules |
| References | reference_url |
List entries are rejoined into the original documentation link |
| Vuln ID from Tool | label |
For example is_latest_tag |
| Finding type | Static | Dockerfiles are analyzed without building |
| Deduplication | Hashcode | Title and line |
The parser reads the data list under each of the three buckets. A rule that fires on several lines produces one Finding per line.
Use Cases
In a CI/CD pipeline: Every pull request that touches a Dockerfile runs dockerfile_lint and reimports the result into a Test for that image. Reviewers see new High findings, like a latest tag on the base image, before the change merges.
For platform image standards: A platform team writes a custom rule file requiring ownership labels and a non-root user. Importing results from every repository shows which teams meet the standard and which have open findings, with SLAs to back the policy.
Paired with image scanning: Dockerfile findings sit on the same Asset as container CVE findings from an image scanner. When a team pins a base image tag, the lint finding closes and the image scan shows a predictable package set from then on.
During a container cleanup: A security lead filters all Assets for the latest-tag and root-user rules by Vuln ID from Tool, assigns them by team, and tracks progress to zero.
Operational Tips
- Use one Test per Dockerfile. Repositories with several Dockerfiles should import each into its own Test so line numbers and deduplication stay meaningful.
- Expect duplicates to reappear when lines move. The hash uses title and line, so inserting lines above a finding changes its line number and can make it look new on reimport.
- Review the default bucket assignments. A rule in the error bucket becomes High, so adjust a rule's level in your own rule file if a default does not match your risk view.
- Filter by Vuln ID from Tool to group the same rule across many images, which is the fastest way to decide between fixing at scale and accepting a pattern.
- Use
minimum_severity=Mediumon import if info-bucket hygiene rules, like cache cleanup, would crowd out the security-relevant ones. - Tag imports with the image name (for example
tags=orders-service,dockerfile) so Dockerfile findings can be separated from image CVEs in reports.