Scanning concepts

kube-bench: Scanning Kubernetes Against the CIS Benchmark

Published August 5, 2026 · 8 min read

kube-bench is the tool most teams reach for when an auditor asks “is this cluster hardened to the CIS Benchmark?” It is free, open source, and answers a very specific question — but it is easy to mistake it for something it is not. Here is what kube-bench actually checks, how to run it, and where it stops.

kube-bench scanning a Kubernetes cluster against the CIS Benchmark

What kube-bench is

kube-bench is an open-source project maintained by Aqua Security. It automates the checks described in the CIS Kubernetes Benchmark— a consensus set of security configuration recommendations published by the Center for Internet Security. In plain terms, kube-bench looks at how your cluster is configured and tells you which of the CIS recommendations it currently meets.

It is a Go binary driven by version-specific YAML configuration files. Each file maps a release of the CIS Kubernetes Benchmark to concrete tests: read this config file, check that flag on this process, verify these file permissions. Because the benchmark differs between managed platforms and self-managed clusters, kube-bench ships configs for many targets — generic Kubernetes, plus EKS, GKE, AKS, RKE, and others.

What the CIS Kubernetes Benchmark covers

The benchmark is organized into sections, and kube-bench mirrors them. At a high level it evaluates:

  • Control plane components— the flags and file permissions of the API server, controller manager, and scheduler, such as whether anonymous auth is disabled and whether audit logging is enabled.
  • etcd— whether the datastore is configured with client and peer TLS and restricted access.
  • Control plane configuration— authentication, authorization modes (RBAC), and logging settings.
  • Worker nodes— kubelet configuration and file permissions, which are frequently where real-world clusters drift from the recommendation.
  • Policies— RBAC hygiene, network policy usage, and Pod Security Standards adoption. Many of these are WARN-level because they cannot be fully judged from configuration alone.

Notably, this is all about how the cluster is set up. None of it examines the software running inside your Pods. For that side of the picture, see our Kubernetes vulnerability scanning guide.

How kube-bench works under the hood

kube-bench needs to see the node the way a local process would. That is why it runs with elevated host access: it reads the actual manifests in /etc/kubernetes, inspects running process arguments through the host PID namespace, and checks file ownership and permissions directly on disk. It does not query the Kubernetes API to guess at configuration; it examines the machine.

Each test in the config declares how to gather the evidence (a file to read, a process to match) and what a compliant result looks like. kube-bench runs the test, compares the result, and emits a verdict plus the remediation text straight from the benchmark. Because the logic lives in YAML, you can audit exactly what a check does — and, when a control genuinely does not apply to your environment, skip or override it deliberately.

Running kube-bench as a Job

The most common way to run kube-bench in a real cluster is as a one-shot Job that mounts the host paths it needs. Aqua publishes a ready-made manifest:

# Run the benchmark as a Job, then read the results from its logs
kubectl apply -f https://raw.githubusercontent.com/aquasecurity/kube-bench/main/job.yaml

# Wait for it to finish, then read the report
kubectl wait --for=condition=complete job/kube-bench --timeout=120s
kubectl logs job/kube-bench

On managed platforms you point kube-bench at the right benchmark. For example, on EKS you run the node checks with the EKS config, because the control plane is managed by AWS and you cannot inspect it:

# Pin a benchmark and target only the components you control
kube-bench run --targets node,policies --benchmark eks-1.5.0

# Or let kube-bench auto-detect the Kubernetes version
kube-bench run --targets master,etcd,controlplane,node,policies

For a quick check from a workstation with kubectl access, you can also run it as a container against the host:

docker run --rm --pid=host \
  -v /etc:/etc:ro \
  -v /var:/var:ro \
  -t aquasec/kube-bench:latest --benchmark cis-1.9

Reading the output

kube-bench prints one line per check with a status and the CIS control number, then a summary. The four statuses matter:

  • PASS — the automated check met the recommendation.
  • FAIL — the automated check did not meet it. This is your primary work queue.
  • WARN— kube-bench could not fully automate the check and is asking you to verify manually. Do not treat WARN as “pass”; treat it as “review.”
  • INFO — advisory context with no compliance verdict.

For pipelines, emit machine-readable output and gate on it. kube-bench supports JSON and a configurable exit code so a failing control can fail a job:

# JSON output, and exit non-zero if any check FAILs
kube-bench run --json --exit-code 1 > kube-bench.json

# Summarize failing checks with jq
jq '[.Controls[].tests[].results[] | select(.status=="FAIL") | .test_number] | length' kube-bench.json

What kube-bench does not do

This is the part worth being explicit about, because it is where teams build a false sense of security. kube-bench answers exactly one question: is the cluster configuration aligned with the CIS Kubernetes Benchmark? It says nothing about the vulnerabilities inside the images you deploy. A cluster can score a clean kube-bench report while every Pod runs an image full of critical CVEs, and kube-bench will never notice — that is not its job.

It also does not enforce anything. kube-bench is a point-in-time audit; it reports, it does not block. To keep non-compliant or unscanned workloads out of the cluster you need an admission layer, which we cover in Kubernetes admission control for image scanning. And to keep node and workload configuration hardened beyond the CIS checklist, pair it with a broader container security checklist.

Where ScanRook fits

kube-bench and ScanRook answer different halves of “is this cluster secure.” kube-bench audits configuration; ScanRook scans the artifacts you deploy into that configuration. Before an image ever reaches the cluster, ScanRook reads the actual package databases inside it and matches every component against OSV, NVD, and Red Hat OVAL in parallel, tagging each finding with a source and confidence tier. Run kube-bench to prove the cluster is set up correctly, and run an artifact scan to prove the software you are running into it is not shipping known-vulnerable packages. Neither replaces the other.

Frequently asked questions

Is kube-bench free?

Yes. kube-bench is open source under the Apache-2.0 license and maintained by Aqua Security. There is no paid tier to run the benchmark checks.

Does kube-bench work on EKS, GKE, and AKS?

Yes, with the caveat that managed control planes are not accessible to you. On managed platforms you run the node and policy targets with the platform-specific benchmark (for example eks-1.5.0) and skip the control plane checks the provider owns.

How often should I run kube-bench?

Treat it as continuous rather than one-off. Configuration drifts as nodes are patched and manifests change, so scheduling kube-bench as a recurring Job or a CI step on cluster changes catches regressions before an audit does.

Can kube-bench fix the failures it finds?

No. It reports failures and prints the remediation text from the benchmark, but you apply the changes yourself — usually by editing kubelet flags, control plane manifests, or file permissions and re-running the scan to confirm.

Harden the config, then scan what you deploy

kube-bench proves your cluster is configured to the CIS Benchmark. ScanRook proves the images you run into it are not shipping known-vulnerable packages — matched against OSV, NVD, and vendor advisory data, with every finding tagged by source and confidence.

Related Posts

More on this topic.