KubeLinter Integration with DefectDojo
KubeLinter Integration with DefectDojo
KubeLinter is an open source static analysis tool for Kubernetes YAML files, Helm charts, and Kustomize manifests. It was created by StackRox, is now backed by Red Hat, and is released under the Apache 2.0 license. KubeLinter checks configuration against security and production readiness rules, such as privileged containers, writable root filesystems, containers running as root, :latest image tags, missing resource requests, and missing anti-affinity. It works on files with no cluster access, prints human-readable output by default, and can write JSON or SARIF.
KubeLinter Integration with DefectDojo
KubeLinter is the lint step we put in front of every Kubernetes change, and DefectDojo is where its results become tracked work. A failed check in CI tells one developer about one pull request. Imported into DefectDojo, each failing check on each object becomes a Finding on the service's Asset, with the remediation sentence KubeLinter ships already in the mitigation field. We can see which services still run containers as root, assign them, and confirm on the next import that they were fixed.
Why KubeLinter Matters
Most Kubernetes security problems start as a default nobody changed in a manifest. KubeLinter catches them before they reach a cluster.
- It runs on files, so it fits into pre-commit hooks and pull request checks without credentials to any cluster.
- It covers Helm charts and Kustomize directly, which is how many teams actually write their manifests.
- Each check comes with a written remediation, so developers know what to change.
- Its default checks mix security rules with reliability rules, which helps platform teams keep both under one process.
Advantages of This Integration
What DefectDojo adds to KubeLinter output:
- Remediation in the right field. KubeLinter's remediation sentence becomes the Finding's mitigation, separate from the diagnostic message in the description.
- Clear object identity. The offending object becomes the component, named
Kind/nameand prefixed with the namespace when one is set, so findings group naturally by workload. - Deduplication across runs. KubeLinter Scan uses hashcode deduplication on title, CWE, line, file path, and description, so rerunning on an unchanged manifest doesn't add new Findings.
- Reimport lifecycle. Reimporting into the same Test mitigates checks that now pass and reopens regressions.
- Triage in one place. Findings can be assigned, risk-accepted, or pushed to Jira, and they sit next to image CVEs and code findings for the same service.
How This Integration Works
DefectDojo imports KubeLinter output with the KubeLinter Scan scan type. The parser reads the JSON report's Reports list. A clean scan sets Reports to null and imports with no Findings.
1. Produce a JSON report. Lint a directory of manifests or a chart:
kube-linter lint --format json ./manifests > kubelinter.json
KubeLinter reports absolute file paths, resolved from the path you give it, so the File Path on each Finding reflects where the manifests were when they were scanned.
2. Import it. In the UI, open the Engagement, choose Import Scan Results, select KubeLinter Scan, and upload the file. With the API, in Community Edition or DefectDojo Pro:
curl "https://YOUR_INSTANCE/api/v2/import-scan/"
-H "Authorization: Token $DD_API_TOKEN"
-F "scan_type=KubeLinter Scan"
-F "file=@kubelinter.json"
-F "product_name=orders-service"
-F "engagement_name=Kubernetes Manifests"
-F "auto_create_context=true"
DefectDojo Pro users can run Universal Importer:
universal-importer import
--defectdojo-url "https://YOUR_INSTANCE.cloud.defectdojo.com/"
--scan-type "KubeLinter Scan"
--report-path "./kubelinter.json"
--product-name "orders-service"
--engagement-name "Kubernetes Manifests"
--auto-create-context
3. Reimport on change. Send later reports to /api/v2/reimport-scan/ against the same Test so closed checks are mitigated.
Data Granularity: What Gets Imported
| DefectDojo Field | Source in KubeLinter Report | Notes |
|---|---|---|
| Title | Reports[].Check |
The check name, for example no-read-only-root-fs |
| Severity | None in the report | Every finding imports at Medium |
| Description | Diagnostic.Message, check, object kind and API version, name, namespace, manifest path |
Namespace shows (not set) when the manifest has none |
| Mitigation | Reports[].Remediation |
KubeLinter's remediation sentence |
| Component Name | Object.K8sObject |
namespace/Kind/name, or Kind/name without a namespace |
| File Path | Object.Metadata.FilePath |
Absolute path to the manifest |
| Line | Not available | KubeLinter identifies the file, not the line |
| Vulnerability ID from Tool | Reports[].Check |
Same as the title |
| Finding type | Static | All KubeLinter findings are static |
| Deduplication | Hashcode | Title, CWE, line, file path, description |
Because there is no line number, findings are told apart by check, manifest, and the diagnostic message, which names the container involved.
Use Cases
In pull request checks: A team runs KubeLinter on every pull request that changes manifests and reimports the result into the service's Test. New Findings point reviewers to exactly what the change introduced, and the mitigation tells the author how to fix it.
For Helm chart owners: A platform team maintaining shared charts lints each chart and imports into one Asset per chart. Findings like a writable root filesystem in the default values get assigned to the chart owners, and every service consuming the chart benefits when they close.
For security baselines: Security engineers filter DefectDojo for checks like privileged-container and run-as-non-root across all Assets to see which teams still need to adopt the baseline.
For combined reporting: Manifest findings sit with SCA, image, and SAST findings for the same service, so release reviews look at code, dependencies, and deployment configuration together.
Operational Tips
- Triage by check name. Every KubeLinter finding imports at Medium, so the title is the main signal for priority. Consider tags or risk acceptance for reliability checks your SLA policy shouldn't cover.
- Run KubeLinter from the same working directory each time. Paths are absolute, and a different checkout location changes the File Path, which is part of the hash.
- Use one Test per service or chart and reimport into it, so mitigations reflect real fixes.
- Don't read file size as a sign of findings. A clean KubeLinter report still contains the full check registry and a summary.
- If you disable checks in KubeLinter's configuration, earlier Findings for them will be mitigated on the next reimport. Record the reason in DefectDojo as well.
- Tag imports with the chart version or Git ref to trace findings to a release.