KubeLinter

KubeLinter checks Kubernetes manifests and Helm charts against a set of configuration checks — privileged containers, writable root filesystems, containers running as root, :latest image tags, missing resource requests, missing anti-affinity.

It runs against files, so it needs no cluster access.

Field mapping

KubeLinterDefectDojo
Reports[].Check (e.g. no-read-only-root-fs)title, vuln_id_from_tool
Reports[].Diagnostic.Messagedescription
Reports[].Remediationmitigation
Object.Metadata.FilePathfile_path
Object.K8sObjectcomponent_name, as namespace/Kind/name
severity, a fixed value; see below

Every KubeLinter check ships a remediation sentence, so that becomes the mitigation rather than being buried in the description.

The offending object is named Kind/name, prefixed with the namespace when KubeLinter reported one. An empty namespace means the manifest did not set one, and the description says (not set) rather than printing nothing — that is a different thing from a namespace called default.

There is no severity and no line number. A report carries no severity, score or confidence, and KubeLinter identifies the manifest but not the line within it. Every finding imports at Medium; triage by check name, which is the title. Bear in mind the default check set mixes security checks (privileged-container, run-as-non-root) with reliability ones (unset-cpu-requirements, no-anti-affinity), so a blanket severity would be wrong either way.

A clean report is not an empty document

KubeLinter always emits its whole enabled-check registry under Checks, plus a Summary. Only Reports holds findings, so a clean scan is a 15 KB document that found nothing. Do not read file size as evidence that something was found.

Note also that a clean scan sets "Reports": null, not []. Anything consuming the report directly has to tolerate that, or it will fail on precisely the case a new user hits first.

Sample Scan Data

Sample KubeLinter files are available at unittests/scans/kubelinter.

Generating an importable file

kube-linter lint --format json ./manifests > kubelinter.json

KubeLinter reports absolute paths, resolved from the path you give it, so file_path reflects wherever the manifests were when they were scanned.

The fixtures committed with this parser were produced with KubeLinter 0.8.3 by three separate runs against the manifests committed alongside them in unittests/scans/kubelinter/:

FixtureFindings
kubelinter_no_vuln.json0 — clean.yaml
kubelinter_one_vuln.json1 — single.yaml, a writable root filesystem
kubelinter_many_vuln.json7 — many.yaml: :latest tag, privileged, root user, no resource requests

Getting a genuinely clean manifest takes more than the security settings. KubeLinter’s defaults also require a declared containerPort matching each probe’s httpGet port, and inter-pod anti-affinity once replicas is above one — a manifest that is secure but omits either is not a zero-finding scan.

Default deduplication hashcode fields

title, cwe, line, file_path, description — the legacy default. With no line number, findings are distinguished by check, manifest and the diagnostic message, which names the container.