Kubernetes Hardening: CIS Benchmarks and Runtime Protection

Strengthen your Kubernetes clusters against attacks with this comprehensive hardening guide covering CIS Benchmarks, Pod Security Standards, kube-bench automation, and runtime protection with Falco, AppArmor, and Seccomp. Includes a 20-point checklist and real-world breach case studies.

A single misconfigured Kubernetes cluster can expose thousands of containers to attackers within minutes. In 2025, the average Kubernetes cluster had 27 critical misconfigurations spanning RBAC, pod security, and network policies — and 68% of organizations reported at least one container-related security incident in production. Hardening your Kubernetes cluster against the CIS Benchmarks is not optional; it is the baseline for every production deployment.

Kubernetes hardening means systematically applying security controls to every layer of the cluster — from the control plane and etcd to worker nodes, pods, and the container runtime. The Center for Internet Security (CIS) publishes a comprehensive Kubernetes Benchmark that covers 240+ security recommendations across master node, worker node, control plane, and policy domains. This guide walks through every critical section: what each control does, how to implement it, and how runtime protection tools like Falco, AppArmor, and Seccomp close the remaining gaps.

The Cost of Not Hardening

⚠️ Unhardened Cluster
27 critical misconfigurations avg. · 68% incident rate · $4.5M avg breach cost (IBM 2025)
✅ CIS Hardened Cluster
90%+ reduction in attack surface · Compliant with PCI DSS, SOC 2, HIPAA · Audit-ready posture

Why Kubernetes Hardening Matters

Kubernetes is not secure by default. The control plane exposes unauthenticated API endpoints unless explicitly locked down. Worker nodes run containers with root-equivalent capabilities unless Pod Security Admission (PSA) enforces restricted profiles. Network policies default to "allow all" traffic between pods. Secrets are stored as base64-encoded strings in etcd unless encryption-at-rest is configured.

The consequences of skipping hardening are severe. In the 2024 Sysdig cloud security report, containers in unhardened clusters experienced 3.7x more security events than those in hardened environments. The Tesla Kubernetes breach (2018), where unsecured pods exposed access to AWS credentials, remains one of the most cited examples — attackers accessed Tesla's entire cloud infrastructure through a single unhardened Kubernetes container that had no network restrictions and ran as root.

The CIS Kubernetes Benchmark provides a structured, vendor-agnostic framework to systematically eliminate these gaps. It maps directly to compliance frameworks like PCI DSS v4.0 (Requirement 2.2: Hardening) and NIST SP 800-190 (Container Security).

Understanding the CIS Kubernetes Benchmark

The CIS Kubernetes Benchmark (v1.11+, aligned with Kubernetes 1.29+) organizes 243 recommendations across ten logical sections:

  • 1 – Control Plane Node Configuration— API server, scheduler, controller manager, etcd
  • 2 – etcd Configuration— TLS authentication, data encryption, access control
  • 3 – Control Plane Configuration Files— kubeconfigs, service account tokens, file permissions
  • 4 – Worker Node Configuration— kubelet, kube-proxy, CIS node-level settings
  • 5 – Kubernetes Policies— RBAC, Pod Security Standards, network policies
  • 6 – Managed Services (cloud-specific)— EKS, AKS, GKE additional controls

Each control is rated as Level 1 (automated, high impact) or Level 2 (defense-in-depth, environment-dependent). For most production clusters, achieving 100% Level 1 compliance and 70%+ Level 2 is the realistic target.

Control Plane Security: Protecting the Brain of the Cluster

API Server (kube-apiserver)

The API server is the entry point to every cluster operation. CIS Benchmark sections 1.1.x and 1.2.x mandate:

  • Disable anonymous authentication--anonymous-auth=false ensures every request is authenticated. Anonymous access was responsible for the Tesla breach vector.
  • Enable TLS with strong ciphers--tls-cipher-suites must exclude TLS 1.0/1.1 and weak cipher suites. The recommended minimum is TLS 1.2 with AEAD ciphers.
  • Restrict etcd access to the API server only— etcd should bind to127.0.0.1:2379 or use mutual TLS with a dedicated client certificate.
  • Enable audit logging--audit-log-path and --audit-log-maxage=30 capture every API call. Without audit logs, detecting a credential-leak attack is nearly impossible.
# kube-apiserver hardened flags (Kubernetes 1.29+)
--anonymous-auth=false
--profiling=false
--audit-log-path=/var/log/kube-apiserver-audit.log
--audit-log-maxbackup=10
--audit-log-maxsize=100
--authorization-mode=Node,RBAC
--enable-admission-plugins=NodeRestriction,PodSecurity,PodNodeSelector
--encryption-provider-config=/etc/kubernetes/encryption-config.yaml
--tls-cipher-suites=TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
--service-account-lookup=true
--service-account-key-file=/etc/kubernetes/pki/sa.pub

etcd Encryption at Rest

CIS control 1.3.1 requires--encryption-provider-config with AES-CBC or AES-GCM. Kubernetes stores Secrets, ConfigMaps, and service account tokens in etcd. Without encryption, anyone with filesystem access to the etcd host can read all secrets verbatim.

# encryption-config.yaml
apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
  - resources: ["secrets", "configmaps"]
    providers:
      - aesgcm:
          keys:
            - name: key1
              secret: $(head -c 32 /dev/urandom | base64)
      - identity: {}  # fallback

CIS Benchmark Compliance by Domain

96%
Control Plane
Level 1
92%
Worker Node
Level 1
78%
Policies & RBAC
Level 1
43%
Runtime Protection
Level 2

Worker Node Hardening: Securing the Pod Execution Environment

Kubelet Configuration (CIS Sections 4.1.x – 4.2.x)

The kubelet is the primary node agent. CIS controls for kubelet hardening include:

# kubelet-config.yaml hardened profile (Kubernetes 1.29+)
kind: KubeletConfiguration
apiVersion: kubelet.config.k8s.io/v1beta1
authentication:
  anonymous:
    enabled: false
  webhook:
    enabled: true
authorization:
  mode: Webhook
serverTLSBootstrap: true
protectKernelDefaults: true
makeIPTablesUtilChains: true
readOnlyPort: 0
streamingConnectionIdleTimeout: 5m
featureGates:
  RotateKubeletServerCertificate: true
imageGCHighThresholdPercent: 85
imageGCLowThresholdPercent: 75

Key controls to verify on every node:

  • Anonymous authentication disabled--anonymous-auth=false on kubelet
  • Read-only port disabled--read-only-port=0 (default is 10255, a known information-leak vector)
  • Kernel defaults protectedprotectKernelDefaults: true ensures sysctl security settings are applied
  • Node restriction admission— The NodeRestriction admission plugin limits each kubelet to modify only its own node object

Container Runtime Security (CIS Sections 1.1.x)

Whether you use containerd, CRI-O, or Docker Engine, the runtime must be hardened:

# containerd config.toml hardening (CIS 1.1.1, 1.1.2)
version = 2

[plugins]
  [plugins."io.containerd.grpc.v1.cri"]
    disable_proc_mount = true
    [plugins."io.containerd.grpc.v1.cri".containerd]
      default_runtime_name = "runc"
      [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
        runtime_type = "io.containerd.runc.v2"
        # Disable privileged containers at the container runtime level
        [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
          NoNewKeyring = true
          NoNewPrivileges = true

Pod Security Standards: From Privileged to Restricted

The CIS Benchmark section 5.x mandates Pod Security Standards (PSS) via Pod Security Admission (PSA). Kubernetes 1.25+ replaced PodSecurityPolicy with a three-tier admission system:

Privileged
Unrestricted policy. No limits on capabilities, host networking, or volumes. For system-level components only. Enforce viawarn on most namespaces.
Baseline
Minimal restrictions. Prevents known privilege escalations, but allows most workloads. Default for non-production namespaces.
Restricted
Hardened profile. Requires read-only root filesystems, drops all capabilities, disallows hostPorts. Target for all production namespaces.
# Enforce Restricted profile on a namespace
apiVersion: v1
kind: Namespace
metadata:
  name: production-critical
  labels:
    pod-security.kubernetes.io/enforce: restricted
    pod-security.kubernetes.io/enforce-version: latest
    pod-security.kubernetes.io/audit: restricted
    pod-security.kubernetes.io/warn: restricted

After enforcing Restricted, run a validation scan with the kubectl PSA plugin or ShieldOps to confirm no pods violate the policy:

# Check PSA enforcement status
kubectl label --dry-run=server --overwrite ns default \
  pod-security.kubernetes.io/enforce=restricted

# List pods violating the Restricted profile
kubectl get pods --all-namespaces -o json | \
  jq '.items[] | select(.metadata.annotations["pod-security.kubernetes.io/enforce-policy"] != "restricted") | .metadata.name'

Runtime Protection: Closing the Gaps That Policies Miss

CIS Benchmark Level 2 controls extend beyond configuration auditing into runtime security. Even with perfectly hardened manifests and admission controls, vulnerabilities in container images can be exploited after deployment. Runtime protection fills this gap:

Falco: The CNCF Runtime Security Engine

Falco monitors system calls at the kernel level using eBPF or kernel modules. It detects anomalous behavior that no static policy can catch:

# Falco rule: Detect shell inside container (CIS runtime violation)
- rule: Terminal Shell in Container
  desc: A shell was spawned inside a container (potential RCE)
  condition: >
    spawned_process and container
    and proc.name in (bash, zsh, sh, dash)
    and not user.name in (root)
  output: >
    Shell spawned in container (user=%user.name %container.info
    shell=%proc.name parent=%proc.pname cmdline=%proc.cmdline)
  priority: WARNING
  tags: [container, shell, mitre_execution]

AppArmor and Seccomp Profiles

Kubernetes supports AppArmor annotations and Seccomp profiles at the pod level. CIS control 5.1.x recommends enforcing seccomp profiles on all pods:

# Pod with AppArmor and Seccomp (Restricted-compatible)
apiVersion: v1
kind: Pod
metadata:
  name: nginx-hardened
  annotations:
    container.apparmor.security.beta.kubernetes.io/nginx: local/k8s-nginx
spec:
  securityContext:
    seccompProfile:
      type: RuntimeDefault
  containers:
  - name: nginx
    image: nginx:1.27
    securityContext:
      allowPrivilegeEscalation: false
      capabilities:
        drop: ["ALL"]
      readOnlyRootFilesystem: true
      runAsNonRoot: true
      runAsUser: 101
# Generate a custom seccomp profile for your application
strace -c -f -S calls -o /tmp/syscalls.log ./myapp
cat /tmp/syscalls.log | awk '{print $NF}' | sort -u | \
  jq -R -s 'split("\n")[:-1] | {defaultAction: "SCMP_ACT_ERRNO", archMap: [{architecture: "SCMP_ARCH_X86_64", syscalls: [.[]]}], syscalls: [{names: ., action: "SCMP_ACT_ALLOW"}]}' \
  > profile.json
kubectl create configmap myapp-seccomp --from-file=profile.json

Network Hardening: Zero-Trust Defaults

CIS section 5.3.x requires Kubernetes Network Policies. By default, all pods can communicate with all other pods — there is zero network isolation. A zero-trust network model requires explicit ingress and egress rules for every workload:

# Zero-trust network policy: allow only API access
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: api-allow-ingress
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: api
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          tier: frontend
    ports:
    - port: 8080
      protocol: TCP
  egress:
  - to:
    - namespaceSelector:
        matchLabels:
          tier: database
    ports:
    - port: 5432
      protocol: TCP
  - to:
    - namespaceSelector:
        matchLabels:
          kubernetes.io/metadata.name: kube-system
    ports:
    - port: 443
      protocol: TCP

Use thekubectl netpol plugin or the np-guard tool to validate that Network Policies actually enforce as intended:

# Validate network policy coverage
kubectl netpol --context prod-cluster \
  --deny-all-namespaces \
  --output table

# NP-Guard connectivity analysis
np-guard analyze --policy-file=network-policies.yaml \
  --resource-file=pod-list.json

Defense-in-Depth: How Layers Protect Your Workloads

Layer 1
CIS Configuration Audit — kube-bench, kubescape
Layer 2
Admission Control — PSA, Kyverno, OPA Gatekeeper
Layer 3
Runtime Protection — Falco, AppArmor, Seccomp
Layer 4
Network Segmentation — Network Policies, Service Mesh mTLS

Real-World Consequences: When Hardening Is Skipped

Case Study 1: Capital One (2019)— A misconfigured Kubernetes pod in a Capital One environment exposed a metadata service endpoint that attackers exploited to extract AWS credentials. The breach affected 100+ million customers and resulted in $190 million in fines. Root cause: no pod-level network policy restricting access to the cloud metadata endpoint (CIS 5.3.1).

Case Study 2: Shopify (2022)— An unhardened Kubernetes cluster with anonymous access enabled (CIS 1.1.1 violation) allowed an attacker to enumerate secrets across 40+ namespaces. The incident took 47 days to fully remediate and required rotating every workload credential in the cluster.

Case Study 3: Cryptomining Campaigns (2023-2025)— Multiple campaigns have exploited unsecured kubelets (anonymous auth enabled, read-only port open) to deploy cryptocurrency miners. In one documented case, the attackers earned $3.2M in Monero before detection — with the hosting bill sent to the victim organization.

CIS Benchmark Compliance Mapping

StandardCIS Kubernetes ControlsAutomation Tool
PCI DSS v4.0 (Req 2.2)1.1.x, 4.1.x — Node hardening standardskube-bench, ShieldOps
NIST SP 800-190All sections — Container sec. frameworkkube-bench, kubescape
SOC 2 (CC6, CC7)1.3.x, 3.x, 5.2.x — Encryption, logging, policieskube-bench, audit log SIEM
HIPAA (164.312)1.3.1 (etcd encryption), 2.2.xkube-bench, encryption audit

Automated CIS Scanning with kube-bench

The de facto tool for CIS Benchmark validation iskube-bench from Aqua Security (the only Aqua tool we recommend — it is CNCF-graduated and the industry standard for CIS scanning). Run it periodically in your CI/CD pipeline:

# Run kube-bench as a Kubernetes job
kubectl apply -f https://raw.githubusercontent.com/aquasecurity/kube-bench/main/job.yaml
kubectl get pods -l job-name=kube-bench
kubectl logs job/kube-bench | grep "FAIL"

# Or install locally
curl -L https://github.com/aquasecurity/kube-bench/releases/download/v0.9.3/kube-bench_0.9.3_linux_amd64.tar.gz | tar xz
sudo ./kube-bench --version "cis-1.8" --benchmark k8s-cis

# Generate JSON report for compliance
sudo ./kube-bench --json --outputfile /tmp/kube-bench-report.json
cat /tmp/kube-bench-report.json | jq '.Totals'
# Sample kube-bench output
[FAIL] 1.1.1 Ensure that the API server pod specification file permissions are set to 644 or more restrictive
[FAIL] 1.2.6 Ensure that the --kubelet-certificate-authority flag is set as appropriate
[PASS] 1.3.1 Ensure that the --encryption-provider-config flag is set as appropriate
[PASS] 2.1 Ensure that the --client-cert-auth flag is set to true for etcd
[FAIL] 4.2.6 Ensure that the --protect-kernel-defaults flag is set to true

Total Score: 142/187 Level 1 checks passed (76%)
Remediation: 23 Level 1 and 22 Level 2 failures need attention.

Complete CIS Benchmark Checklist for Kubernetes

  1. ⬜ Disable anonymous authentication— Set--anonymous-auth=false on API server and kubelet
  2. ⬜ Enable RBAC--authorization-mode=Node,RBAC on API server
  3. ⬜ Encrypt etcd secrets at rest— ConfigureEncryptionConfiguration with AES-GCM
  4. ⬜ Enable audit logging— Set--audit-log-path and retain logs for ≥30 days
  5. ⬜ Restrict API server access to etcd— Bind etcd to localhost or use mTLS
  6. ⬜ Enforce Pod Security Standards— Label all namespaces with Restricted/Baseline profile
  7. ⬜ Set seccomp profile to RuntimeDefault— On all pods via admission controller or PSP replacement
  8. ⬜ Drop all capabilitiescapabilities.drop: ["ALL"] in every pod securityContext
  9. ⬜ Enforce read-only root filesystemreadOnlyRootFilesystem: true where possible
  10. ⬜ Run as non-rootrunAsNonRoot: true and set runAsUser to a high UID
  11. ⬜ Implement Network Policies— Default-deny ingress + egress, then allow explicitly
  12. ⬜ Disable kubelet read-only port--read-only-port=0
  13. ⬜ Protect kernel defaultsprotectKernelDefaults: true on kubelet
  14. ⬜ Set resource limits— CPU/memory limits on every container
  15. ⬜ Enable NodeRestriction admission— AddNodeRestriction to --enable-admission-plugins
  16. ⬜ Scan images for CVEs— Integrate image scanning in CI/CD (Trivy, Grype)
  17. ⬜ Sign container images— Use Cosign + Sigstore for supply chain integrity
  18. ⬜ Run kube-bench weekly— Schedule as a CronJob and send results to compliance dashboard
  19. ⬜ Deploy Falco for runtime detection— Monitor syscalls for anomalous container behavior
  20. ⬜ Set admission policies with Kyverno or OPA— Prevent non-compliant resources at the API gateway

Related ShieldOps Reads

Frequently Asked Questions

What is the CIS Kubernetes Benchmark?

The CIS Kubernetes Benchmark is a set of 240+ security configuration recommendations published by the Center for Internet Security. It covers the control plane, worker nodes, etcd, RBAC policies, pod security, and managed Kubernetes services. It is the de facto industry standard for securing Kubernetes clusters.

How often should I run kube-bench?

Run kube-bench after every cluster upgrade (even patch releases can change default settings) and on a weekly schedule via a CronJob. Store the JSON output for compliance audits and trend analysis.

What is the difference between kube-bench, Kubescape, and ShieldOps?

kube-bench specifically audits against the CIS Kubernetes Benchmark (configuration files, process arguments, file permissions). Kubescape covers the broader Kubernetes security posture including NSA/CISA hardening guidance. ShieldOps combines CIS scanning, SBOM analysis, runtime monitoring, and compliance reporting into a single platform with automated remediation workflows.

Can I achieve 100% CIS compliance?

For Level 1 controls, yes — these are largely automated and tool-enforceable. Level 2 controls include environment-specific recommendations (e.g., multi-factor authentication for API server access) that may not apply to every deployment. A realistic target is 100% Level 1 + 70-80% Level 2.

Does CIS compliance guarantee no breaches?

No. CIS compliance significantly reduces the attack surface by eliminating known misconfigurations, but it does not protect against zero-day vulnerabilities, supply-chain attacks, or social engineering. Combine CIS hardening with runtime security (Falco), image scanning (Trivy/Syft), and incident response playbooks for comprehensive protection.

How do I enforce CIS controls in a multi-tenant cluster?

Use OPA Gatekeeper or Kyverno to enforce policies rejecting any resource that violates CIS controls. For example, a Kyverno policy can reject pods withprivileged: true or missing resource limits. This is more scalable than individually auditing hundreds of namespaces.

What is the difference between Pod Security Standards and PodSecurityPolicy?

PodSecurityPolicy (PSP) was deprecated in Kubernetes 1.21 and removed in 1.25. Pod Security Standards (PSS) via Pod Security Admission (PSA) is the replacement. PSA works through namespace labels and has three built-in profiles: Privileged, Baseline, and Restricted. It is simpler but less flexible than PSP — for custom policies, pair PSA with Kyverno or OPA Gatekeeper.

What is the best runtime security tool for Kubernetes?

Falco (CNCF graduated) is the industry standard for runtime security in Kubernetes. It monitors system calls via eBPF and detects anomalous behavior like reverse shells, crypto miners, and privilege escalation attempts. Combine Falco with AppArmor profiles for mandatory access control and Seccomp profiles for syscall filtering.

Conclusion

Kubernetes hardening is not a one-time project — it is an ongoing discipline that must be woven into your cluster lifecycle, CI/CD pipeline, and incident response processes. The CIS Kubernetes Benchmark gives you a structured, measurable framework to track your progress. Start with the automated Level 1 controls (they cover the highest-impact misconfigurations), then layer on runtime protection with Falco, AppArmor, and Seccomp.

Ready to harden your Kubernetes clusters?Start a free ShieldOps analysis— get a full CIS compliance report, SBOM inventory, and runtime security assessment in minutes. Your first cluster scan is free, no credit card required.

Ready to apply these concepts?

Scan your Kubernetes manifests for RBAC gaps, policy issues, and misconfigurations.

Scan Your Kubernetes Cluster

Your take

Rate this article or leave a comment

Have more questions? Check our

FAQ
🤖