Skip to content

All posts

KubernetesKyverno

How to run the CIS Kubernetes Benchmark on EKS, AKS and GKE

Ritesh Patel

Kubernetes: How to run the CIS Kubernetes Benchmark on EKS, AKS and GKE with Kyverno

To run the CIS Kubernetes Benchmark on EKS, AKS or GKE, split the checks into three layers. Run kube-bench on each node for host checks, run its cloud target for managed-service checks, and write Kyverno policies for pod and RBAC checks. Choose the benchmark version first. kube-bench’s newest cloud configs may lag the current CIS revision, so check which revision your auditor names and whether a config covers it.

Which checks each layer covers

The kube-bench configs for the three clouds split each benchmark into node, policies and managed-service sections. The table counts the checks in the newest config in kube-bench’s cfg directory for each cloud, using the scored field in each check. Scored checks are the ones kube-bench marks as scored. Not-scored checks are manual, so someone has to verify them by hand. A scored check is not necessarily automated, because some scored checks are skipped in the config, so these counts do not measure automated coverage. Checked against the kube-bench main branch and the CIS Kubernetes Benchmark overview page, both fetched 2026-11-13. The kube-bench links in this post point to main, not a release tag, because no tag was pinned when they were fetched.

Cloud Latest kube-bench config Policy checks (Scored / Not scored) Managed-service checks (Scored / Not scored)
EKS eks-1.8.0 14 / 9 0 / 12
AKS aks-1.8 9 / 15 0 / 13
GKE gke-1.9.0 11 / 9 3 / 30

The policy rows are the section 4 checks, which cover RBAC and pod security and are the ones a Kyverno policy can read from the Kubernetes API. Managed-service checks cover registries, KMS encryption, private endpoints and node images. On AKS and EKS most of these are Manual, so they need evidence you collect yourself.

Pick the benchmark version before you run

The CIS Kubernetes Benchmark overview page lists the current benchmark versions for each cloud, so you know which version is newest. kube-bench names its configs by cloud and version, such as eks-1.8.0 and aks-1.8. Those names may not cover the current CIS revision on that page, so check the revision each config covers.

  1. Ask your auditor which CIS benchmark and version the evidence must match.
  2. Check the CIS Kubernetes Benchmark overview page for the current version of that cloud benchmark.
  3. Look up the matching name in kube-bench’s platform table. If your version is not listed, do not map it to the nearest one without your auditor’s agreement.

Run kube-bench on EKS

kube-bench’s job manifest runs the node, policies, managedservices and controlplane targets against the EKS benchmark. Apply it, wait for the pod to finish, then read its logs. The job runs with host PID access and mounts host paths, so run it in a namespace your platform team controls. The job pod runs on one node, so its node checks cover only the node the pod lands on.

To cover every worker node, run one copy of the job on each node. Pin each copy to a node with nodeName or a nodeSelector, or run the same pod spec as a DaemonSet. Then collect the logs from every pod and record which node each one ran on (kubectl get pods -o wide shows it). Keep the managed-service checks to a single run, since they query the cloud API and do not depend on the node.

kubectl apply -f job-eks.yaml
kubectl get pods
kubectl logs kube-bench-x7k2p

The results sit in the pod’s logs, as the kube-bench README describes. The pod name kube-bench-x7k2p is illustrative. Use the name that kubectl get pods shows for your run. The example job pins the benchmark to eks-1.5.0, so change the --benchmark argument if your version is different.

Run kube-bench on AKS and GKE

The AKS and GKE job manifests differ from the EKS one, and the differences matter. The AKS example runs only the node target. The GKE example runs node, policies and managedservices. Neither example runs the controlplane target. The command lines below are the arguments each example job passes to kube-bench inside its pod, not commands to run from your workstation against the cluster.

# AKS example job entrypoint, run inside the pod: node target only
kube-bench run --targets node --benchmark aks-1.7

# GKE example job entrypoint, run inside the pod: node, policies and managedservices targets
kube-bench run --targets node,policies,managedservices --benchmark gke-1.2.0

If you need the AKS policy or managed-service checks, add those targets yourself and check the result. The example manifests predate the newest cloud configs, so the benchmark name is the first thing to confirm.

Enforce a pod security check with Kyverno

The Kyverno EKS walkthrough maps CIS section 4.2.1, minimize privileged containers, to a ClusterPolicy. The walkthrough’s policy sets the failure action at the policy level, but the current docs move that field into each rule. The version below uses the rule-level field.

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: supported-4.2.1
  annotations:
    policies.kyverno.io/title: Minimize privileged containers
    policies.kyverno.io/category: Pod Security
    policies.kyverno.io/severity: high
    policies.kyverno.io/description: >-
      Ensure that privileged containers are not allowed.
spec:
  rules:
    - name: restrict-privileged
      match:
        any:
          - resources:
              kinds:
                - Pod
      validate:
        failureAction: Audit
        message: 'Privileged containers are not allowed.'
        pattern:
          spec:
            =(initContainers):
              - =(securityContext):
                  =(privileged): false
            =(ephemeralContainers):
              - =(securityContext):
                  =(privileged): false
            containers:
              - =(securityContext):
                  =(privileged): false

The policy checks regular, init and ephemeral containers. The equality anchors (=(...)) apply a check only when the field is present, so a container that omits securityContext or privileged passes, and one that sets privileged: true fails.

Apply the policy in Audit mode first, then read the reports. Audit lets a violating pod through and records the failure. The walkthrough shows a noncompliant pod rejected with “Privileged containers are not allowed.”, but the policy file in the same post sets Audit, so test both modes on your own cluster before you rely on either.

  1. Apply the policy in Audit mode.
  2. Read the PolicyReport and ClusterPolicyReport resources for failures.
  3. Fix or record an owned exception for each failure.
  4. Change failureAction to Enforce only for rules with no open failures.

The pattern only checks the fields it names. Test a pod that leaves out securityContext entirely, and decide whether that pod should pass.

Run the kube-bench adapter on a schedule

The kube-bench-adapter Helm chart in the nirmata/kyverno-charts repository runs kube-bench as a cron job and writes the results to a cluster-wide policy report. This section follows the chart README on the main branch, fetched 2026-11-13. A 2022 post on the Nirmata AWS adapter for Kyverno, written for Amazon EKS, also mentions a CIS Kubernetes Benchmark reporting adapter. The chart’s clusterType value selects the embedded job for eks, gke or aks. The default schedule is weekly.

helm repo add nirmata https://nirmata.github.io/kyverno-charts/
helm install kube-bench-adapter nirmata/kube-bench-adapter --set kubeBench.name="cis-k8s-benchmark" --set clusterType=eks
kubectl get jobs --watch
kubectl get clusterpolicyreports

The chart’s README example sets kubeBenchBenchmark to cis-1.7. It is not clear from the README whether that value still applies when clusterType is set, so confirm it with a test install before you rely on the output.

What no single layer covers

Each layer answers different questions. The table below shows where each kind of check lives, based on the examples in the Kyverno walkthrough and the kube-bench configs.

Check Example Where it runs
Node file permissions kubeconfig permissions (CIS 3.1.1) kube-bench on each node
Pod security privileged containers (CIS 4.2.1) Kyverno admission and reports
RBAC cluster-admin only where required (CIS 4.1.1) Kyverno admission and reports
Managed service settings KMS encryption of secrets (EKS 5.3.1) Cloud settings, with manual evidence
Image registries ECR image scanning (EKS 5.1.1) Manual evidence

Enforcing this with Kyverno

Start with one cluster in Audit mode, and keep the manual evidence list next to the policy reports so an assessor can read both. For the control mapping behind these checks, read NIST 800-53 controls for Kubernetes. For handling exceptions, read how to document policy exceptions as audit evidence. For the wider compliance program, see the continuous compliance page. The EKS steps above follow the kyverno.io walkthrough.

Frequently asked questions

Which CIS benchmark version should I run on EKS, AKS or GKE?

Use the version your auditor or compliance program names. The CIS Kubernetes Benchmark overview page lists EKS 2.1.0, AKS 2.1.0 and GKE 2.0.0 as recent versions. The kube-bench configs in its repository go up to eks-1.8.0, aks-1.8 and gke-1.9.0, and its example job manifests name older versions. The newest config may lag the current CIS revision, so confirm which revision each config covers before you compare results against a version.

Can Kyverno check file permissions on worker nodes?

No. The kyverno.io EKS walkthrough says Kyverno cannot access worker node file systems or read kubelet configuration files. Checks such as kubeconfig and kubelet file permissions need kube-bench running on each node. The example EKS job mounts /var/lib/kubelet, /etc/systemd and /etc/kubernetes read-only so the node run can read those files.

Should Kyverno CIS policies start in Audit or Enforce mode?

Start in Audit. The Kyverno docs say Audit allows the resource and records the violation in a PolicyReport or ClusterPolicyReport, while Enforce blocks a create or update that fails. Switch a rule to Enforce only after its reports show no open failures in the namespaces that matter to you.

Does a clean CIS run mean the cluster is compliant?

No. A clean run means the checks that ran passed against the nodes, pods and objects they could read. Manual checks, such as reviewing ECR image scanning or who can read a registry, need evidence from outside the cluster. Only your assessor can say whether a control is satisfied.

Ritesh Patel, Founder & VP Product, Nirmata

Ritesh Patel is a founder of Nirmata and leads its products. He writes about governing AI coding agents, MCP security and Kubernetes policy as code.

LinkedIn

Nirmata Control HubOne control plane for Kyverno policies.
ShareXLinkedIn

Stay up-to-date with the latest in AI, governance, and infrastructure

Subscribe to our free monthly newsletter to get industry news, DevOps tips, and articles right to your inbox on Kyverno, containerization, Kubernetes deployment & management and more.