Have the hardening state of your cluster reviewed? The cluster audit compares your cluster with the CIS Kubernetes Benchmark and the BSI module APP.4.4 and delivers a report with prioritized measures. It is a configuration review, not a penetration test. From €1,490 net one-time, credited against the first month of operations (as of October 2026). View the cluster audit
The CIS Kubernetes Benchmark is the common template for hardening Kubernetes clusters, and kube-bench is the tool that checks it. This guide answers the questions that come up after the first run: which version is right, what PASS, FAIL, WARN and INFO mean, which findings come first and what changes on EKS, AKS, Talos, k3s and RKE2. Status 29 October 2026. The nine hardening layers with kubectl checks are in the hardening guide and are not repeated here.
Contents
- Which version applies: benchmark, kube-bench and Kubernetes
- Running kube-bench: job, targets and output
- Reading findings: PASS, FAIL, WARN and INFO
- Prioritizing findings: a sequence
- Section overview: responsibility by operating model
- Managed clusters: EKS and AKS
- Talos, k3s and RKE2
- Comparison with BSI APP.4.4
- Our approach at WZ-IT
- Status and methodology
- Further guides
Which version applies: benchmark, kube-bench and Kubernetes
Three version levels interlock and do not match.
| Component | Status 29 Oct 2026 | Source |
|---|---|---|
| CIS Kubernetes Benchmark | 2.1.0 (EKS and AKS: 2.0.0) | CIS |
| kube-bench, latest release | v0.16.0 of 5 Aug 2026, licence Apache-2.0 | Release, LICENSE |
| Generic configuration in the release | up to cis-1.12, mapped to Kubernetes 1.32 to 1.34 | image v0.16.0, /opt/kube-bench/cfg |
| Generic configuration on main | cis-2.0 since 18 Aug 2026, mapped to 1.34 and 1.35; no mapping for 1.36 and 1.37 | config.yaml, commit |
The consequence: the image aquasec/kube-bench:latest equals v0.16.0 and does not contain cis-2.0 (checked in the image on 29 October 2026). To test against cis-2.0, build kube-bench from the main branch. Otherwise set --benchmark cis-1.12 and name the version in the report. The platform table does not map Kubernetes releases 1:1 to benchmarks, and its rows for EKS, AKS and RKE2 lag behind the directories under cfg.
Running kube-bench: job, targets and output
kube-bench inspects processes, configuration files and file permissions on the node and needs the host PID and read access to host paths for that (README). It runs as a job. The targets (--targets) are master, etcd, controlplane, node and policies (architecture).
If Pod Security Admission enforces baseline or restricted in the cluster, the job (host PID, hostPath volumes) needs a namespace with the level privileged:
kubectl create namespace kube-bench
kubectl label namespace kube-bench pod-security.kubernetes.io/enforce=privileged
curl -sLO https://raw.githubusercontent.com/aquasecurity/kube-bench/v0.16.0/job.yaml
In the job.yaml, give each run its own metadata.name (here kube-bench-control-plane) and change nodeSelector and tolerations in the pod template for the control plane (guide), plus targets and benchmark in the command. Apply it with kubectl apply -n kube-bench -f job.yaml.
spec:
hostPID: true
nodeSelector:
node-role.kubernetes.io/control-plane: ""
tolerations:
- key: node-role.kubernetes.io/control-plane
operator: Exists
effect: NoSchedule
containers:
- name: kube-bench
image: docker.io/aquasec/kube-bench:v0.16.0
command: ["kube-bench", "run", "--targets", "master,etcd,controlplane,policies", "--benchmark", "cis-1.12"]
For the worker nodes (name kube-bench-worker), drop nodeSelector and tolerations; the command is ["kube-bench", "run", "--targets", "node", "--benchmark", "cis-1.12"]. Fetch the output with kubectl logs -n kube-bench job/kube-bench-control-plane | grep -E '^\[(FAIL|WARN)\]'. Three options from the flag reference belong in every run:
--json --outputfile <file>writes a machine-readable report. It contains the totals under.Totalsand, per control,test_number,statusandscored.--skip "<IDs>"skips controls. They appear as INFO and belong in an exception register with a reason.--exit-code 42returns this exit code if at least one control fails, which works as a pipeline gate. A WARN does not trigger it.
From the JSON report, jq -r '.Controls[].tests[].results[] | select(.status=="FAIL") | "\(.test_number) \(.test_desc)"' yields the FAIL list.
Reading findings: PASS, FAIL, WARN and INFO
The reference defines four states. PASS and FAIL rate a control that was executed. WARN means further attention is needed, for example because the control must be checked manually. INFO is information without required action, which includes skipped controls. Two rules explain most surprises:
- Scored controls (
scored: true) end in FAIL if they deviate or cannot be executed. Unscored controls (scored: false) end in WARN in that case and in PASS on success. Controls of typemanualalways produce WARN. - A WARN does not count as FAIL: the exit code and the FAIL total do not reflect WARN.
This matters for security-critical controls. In cis-2.0, 1.2.1 (--anonymous-auth on the API server) is labelled manual in the benchmark and unscored in kube-bench. In a test with a simulated API server process (kube-bench v0.16.0, configuration cis-1.12), 1.2.1 returned PASS with --anonymous-auth=false and WARN with =true, while the scored control 1.2.2 (--token-auth-file) reported FAIL with the parameter set. Open anonymous access therefore triggers neither FAIL nor the exit code. 4.2.4 (read-only port of the kubelet) is likewise unscored (scored: false). Evaluate these WARN messages instead of skipping them.
In an empty container, cis-1.12 with all five targets gives 1 PASS, 64 FAIL and 66 WARN. The 66 WARN are the unscored controls; 28 of them are of type manual (always WARN, they fall only through assessment). The other 38 turn to PASS through hardening. By the definition in the Microsoft documentation on the benchmark, only automated recommendations affect the benchmark score. A figure such as "85 percent" is therefore comparable only if version, targets, skip list and the treatment of WARN are stated.
Prioritizing findings: a sequence
The sequence is our assessment by impact and not part of the benchmark. Numbers follow cis-2.0.
| Level | Type of finding | Controls (examples) | Action |
|---|---|---|---|
| 1 | Access without authentication or authorization | 1.2.1, 1.2.2, 1.2.6 to 1.2.8, 2.1 to 2.6, 4.2.1 to 4.2.4 | fix or evidence a compensating measure; 1.2.1 and 4.2.4 report deviations only as WARN |
| 2 | Data and traceability | 1.2.16 to 1.2.19, 1.2.27, 1.2.28, 3.2.1, 3.2.2 | set up secrets encryption and audit log and evidence them with a sample |
| 3 | Policies in section 5 | 5.1.x (RBAC), 5.2.x (Pod Security), 5.3.2 (NetworkPolicies) | entirely manual in the benchmark (kube-bench runs 11 of 34 as unscored checks): kubectl checks in the hardening guide |
| 4 | File permissions and the rest | 1.1.x, 4.1.x | fix, lower impact than levels 1 to 3 |
| 5 | Controls with operational impact | 1.2.9 (EventRateLimit), 1.2.11 (AlwaysPullImages) | decide deliberately, document as exception or measure |
On level 5: Microsoft lists both controls for AKS as "Fail" with the reason "Operational impact". The benchmark separates Level 1 (basic, little restriction) from Level 2 (stricter, may restrict functionality).
An exception register holds, per entry, control ID, finding, reason, compensating measure, responsible person and review date. False alarms caused by the architecture of the distribution (see below) belong in it.
Section overview: responsibility by operating model
The table summarizes the cis-2.0 configuration (kube-bench, main branch), counted by the labels "Automated" and "Manual" in the control titles.
| Section | Content | Target | Controls | of which automated | Self-managed | EKS and AKS |
|---|---|---|---|---|---|---|
| 1.1 | Control plane configuration files | master | 21 | 17 | operator | provider |
| 1.2 | API server | master | 30 | 22 | operator | provider |
| 1.3 | Controller manager | master | 7 | 6 | operator | provider |
| 1.4 | Scheduler | master | 2 | 2 | operator | provider |
| 2 | etcd | etcd | 7 | 6 | operator | provider |
| 3.1, 3.2 | Authentication, logging | controlplane | 5 | 0 | operator | shared: provider feature, to be enabled by the operator |
| 4.1 | Worker configuration files | node | 10 | 6 | operator | operator |
| 4.2 | kubelet | node | 14 | 5 | operator | operator |
| 4.3 | kube-proxy | node | 1 | 1 | operator | operator |
| 5.1 | RBAC and service accounts | policies | 13 | 0 | operator | operator |
| 5.2 | Pod Security Standards | policies | 12 | 0 | operator | operator |
| 5.3 | NetworkPolicies and CNI | policies | 2 | 0 | operator | operator |
| 5.4 to 5.6 | Secrets, admission control, general policies | policies | 7 | 0 | operator | operator |
| Total | 131 | 65 |
The "EKS and AKS" column follows the statement in the kube-bench documentation that the control plane nodes of managed clusters cannot be inspected (guide) and the AWS shared responsibility model, under which AWS is responsible for the control plane nodes and the etcd database. "Provider" means: the operator cannot check it and evidences it with the provider documentation.
Managed clusters: EKS and AKS
On EKS and AKS, kube-bench checks the operator's part. There are dedicated configurations: eks-1.8.0 (50 controls, 27 automated) and aks-1.8 (51 controls, 16 automated) with the targets node, policies, controlplane and managedservices. The managedservices controls on image registry, IAM, key management and networking are manual throughout (12 on EKS, 13 on AKS). The CIS page lists version 2.0.0 for both, and kube-bench main goes up to eks-1.8.0 and aks-1.8. The example jobs are older: job-eks.yaml sets eks-1.5.0, job-aks.yaml sets aks-1.7. Check the benchmark line before you run.
For the control plane, the provider supplies the evidence:
- AKS: Microsoft publishes the status per recommendation of Kubernetes benchmark v1.12.0 for AKS 1.32 to 1.34 (documentation). The table has 125 recommendations: 54 Pass, 37 "Depends on Environment", 23 "N/A", 7 Fail and 4 "Equivalent Control". All 21 recommendations in 1.1 are N/A because AKS deploys the control plane pods with a Helm chart and uses no files on a node VM. For 1.2.2 (
--token-auth-file) it says Fail, noting that AKS sets and rotates the parameter and it is not configurable. The 33 recommendations in 5.1, 5.2, 5.3.2, 5.4 and 5.6 (RBAC, Pod Security, NetworkPolicies, secrets, general policies) are "Depends on Environment", so they sit with the operator. - EKS: Control plane logs, including the audit log, are off by default and are enabled per log type (documentation).
aws eks update-cluster-config --name <cluster> --logging '{"clusterLogging":[{"types":["api","audit","authenticator","controllerManager","scheduler"],"enabled":true}]}'enables all five. From Kubernetes 1.28, EKS encrypts all Kubernetes API data by default with envelope encryption (documentation). That is the provider evidence for secrets encryption (controls 1.2.27 and 1.2.28).
Record the provider status with a date in the evidence; it changes with the Kubernetes version.
Talos, k3s and RKE2
Here paths and processes differ from kubeadm. The table lists, per distribution, the configuration in kube-bench main, the number of controls (of which automated) and the documented deviation.
| Distribution | kube-bench configuration (main) | Controls (automated) | Typical deviation | Source |
|---|---|---|---|---|
| Talos Linux | none of its own; docs use cis-1.10 (tested with Kubernetes 1.35) | No kubeadm paths: 1.1.x and 4.1.x report FAIL or WARN, as do 1.2.5 to 1.2.8 and 4.2.1 to 4.2.3. Defaults per docs: anonymous auth off, audit policy at Metadata level, secrets encryption (secretbox), Pod Security baseline (enforce) and restricted (audit, warn). |
Talos docs | |
| RKE2 | rke2-cis-1.9 | 130 (82) | profile: "cis" applies network and pod security settings itself (restricted, exemptions for system namespaces); the host needs a sysctl file and an etcd user. Self-assessment 2.0 (RKE2 v1.35 to v1.37): 91 PASS, 35 WARN, 5 N/A of 131 controls. |
Hardening, self-assessment |
| k3s | k3s-cis-1.11 (k3s v1.29 to v1.32) | 132 (68) | Single binary: 9 file controls in 1.1 are N/A. Pod security, audit policy and secrets encryption must be enabled by configuration (psa.yaml, audit.yaml, secrets-encryption: true). Self-assessment 2.0 (k3s v1.34 to v1.37): 81 PASS, 31 WARN, 14 N/A of 126 assessed controls; section 3 does not appear in the guide. |
Hardening, self-assessment |
Licences per LICENSE file: kube-bench, RKE2 (LICENSE) and k3s (LICENSE) are Apache-2.0, Talos Linux is MPL-2.0 (LICENSE).
Talos. Talos has no SSH, no shell and an immutable root file system; management goes through the Talos API. Controls that expect manifest files or kubeadm paths find nothing there. The Talos documentation treats these results as false alarms and provides skip lists for control plane and workers that lead to a run without FAIL. The lists were tested with Kubernetes 1.35 and cis-1.10; with another benchmark version, re-check the numbers. Workload controls stay with the operator (Pod Security exemptions, NetworkPolicies, RBAC).
RKE2 and k3s. The self-assessments apply to the hardened state following the instructions and explain "Not Applicable" per control. kube-bench main has no CIS 2.0 configuration for either: for k3s from v1.34 and RKE2 from v1.35, their audit commands serve as the basis.
Comparison with BSI APP.4.4
APP.4.4 Kubernetes (2023 edition, German) provides in A13, a requirement for elevated protection needs (SHOULD), for an automated audit of the settings of nodes, Kubernetes and pods against a defined list of permitted settings and against standardized benchmarks. The module lists the CIS Benchmark under further information. kube-bench can supply the dated report for it. A run covers only part of the module, though.
| APP.4.4 | Content | Reference in the benchmark (cis-2.0) |
|---|---|---|
| A1 (basic) | Planning the separation | planning requirement; touchpoint 5.6.1 (namespaces) |
| A2 (basic) | Planning CI/CD automation | planning requirement; touchpoints 5.4.1, 5.4.2 (secrets) |
| A3 (basic) | Identity and authorization management | 1.2.1, 1.2.6 to 1.2.8, 3.1.x, 4.2.1, 4.2.2, 5.1.x |
| A4 (basic) | Separation of pods | indirect: 5.2.x (Pod Security Standards) |
| A5 (basic) | Data backup in the cluster | no control; "backup" appears in the files only as --audit-log-maxbackup |
| A7, A18 | Network separation, micro-segmentation | 5.3.1, 5.3.2 |
| A9 | Service accounts | 5.1.5, 5.1.6 |
| A20 (elevated) | Encrypted data storage (etcd) | partial: 1.2.27, 1.2.28 encrypt API data in etcd, A20 refers to the file systems |
The layers with pass criteria per requirement are in the hardening guide; the NIS2 evidence is in Kubernetes NIS2 and ISO 27001: cluster evidence.
Our approach at WZ-IT
The cluster audit compares the cluster with the CIS Kubernetes Benchmark and APP.4.4. The result is a report with findings by priority and recommended measures. The audit is a configuration review without changes to the cluster, not a penetration test. It costs from €1,490 net one-time and is credited against the first month of operations.
Managed Kubernetes from €590 net per cluster per month including three worker nodes takes over operations, with monitoring, upgrades, backups with restore test and hardening. Monitoring runs 24/7, and the response to P1 incidents follows the service level. Alternatively we implement measures from a report through Kubernetes support, €120 net per hour without a contract. Prices net, as of October 2026.
Status and methodology
- Status: 29 October 2026. All linked sources were retrieved that day.
- kube-bench: release v0.16.0 and main branch (commit e278a591 of 5 October 2026). The control counts come from the YAML files under
cfg/. The flags--benchmark,--targets,--skip,--exit-code,--json,--outputfileand the jq path ran locally in the containeraquasec/kube-bench:v0.16.0. The test for 1.2.1 and 1.2.2 (configuration cis-1.12) used a simulated API server process that mimics the output of ps, and the job changes are only checked for valid YAML. No run in a cluster took place. - AKS figures: Microsoft's status table for benchmark v1.12.0 and AKS 1.32 to 1.34, counted by us (125 rows). It does not apply to the numbering of cis-2.0. The page carries the change note 2025-08-05.
- RKE2, k3s, Talos: count of the "Result" lines in the self-assessment guides for CIS 2.0. The Talos statements come from its documentation (version 1.14) and are not tested by us.
- Assessment: the priority levels are our judgement. According to CIS, the benchmark PDF is freely available for non-commercial use and requires an account; version 2.1.0 was not evaluated.
Further guides
- Kubernetes hardening checklist: CIS, BSI and NIS2 - nine layers with pass criteria and kubectl commands
- Kubernetes go-live checklist: 25 checks - 25 checks before production
- k3s vs. RKE2 vs. Talos - distributions compared
- What is Talos Linux? An OS for Kubernetes - the operating system at a glance
- Taking over a Kubernetes cluster: audit checklist - the operations side of a takeover
Cluster review or operations handover? The audit delivers the report, managed Kubernetes implements the measures. Cluster audit · Managed Kubernetes











