01TL;DR — What Actually Gets Clusters Compromised

Your last audit passed. Your scanner shows green. Your Kubernetes cluster is wide open.

The CIS Kubernetes Benchmark lists over 200 controls. The NSA/CISA hardening guide runs 66 pages. Compliance teams treat all of them equally — one checkbox is one checkbox. Security engineers know better. An unrotated certificate is not the same as an unauthenticated API server. A missing label is not the same as etcd exposed on 0.0.0.0:2379.

CIS is a benchmark: precise, auditable, scanner-friendly, and strong at hardening components like API server, kubelet, etcd, and file permissions. NSA/CISA is hardening guidance: threat-driven and architecture-oriented, strong at supply chain, network segmentation, identity boundaries, and operational controls. Reality: many organizations "comply" while leaving the easiest compromise paths open.

What matters most in real incidents RBAC blast radius — cluster-admin, wildcards, CI service accounts are the fastest path to full compromise once any identity is stolen. ServiceAccount token discipline — automount everywhere is a gift to attackers. Turns any pod RCE into Kubernetes API access. Default-deny networking — flat cluster networks let attackers pivot workload-to-workload. Without segmentation, compromise spreads. Ingress config injection — snippets/annotations = "code execution at the edge." A bad annotation becomes request smuggling or auth bypass. Cloud pivot prevention — IMDS/metadata + node creds + over-permissive cloud IAM is one of the most common "cluster → cloud account" escalations.

02CIS vs NSA/CISA — What Each Framework Optimizes For

Both frameworks target Kubernetes security. They attack the problem from opposite directions. Treating them as interchangeable produces a compliance program optimized for neither threat prevention nor auditability.

Dimension CIS Benchmark NSA/CISA Guidance
Scope120+ component-level controlsThreat-driven categories + reference architecture
Level structureLevel 1 / Level 2No levels — engineering judgment
Control plane hardening Deep (flags, perms, certs) Covered, less granular
Supply chain / image signing Minimal Explicit requirement
Network segmentation Partial Architecture-level
RBAC / IAM guidance Present Deeper blast-radius framing
Threat modeling context Absent Core design principle
Scanner / audit friendly Optimized for evidence Engineering judgment required
Best used forAuditors, automated scanning, compliance evidenceArchitecture decisions, leadership buy-in, threat modeling
Figure 2.1 — Domain coverage: CIS (blue) vs NSA/CISA (purple). Where one goes deep, the other leaves gaps.
Control Plane Hardening
95%
60%
Network Policy & Segmentation
40%
85%
Pod Security Standards
80%
90%
RBAC & IAM
70%
80%
Supply Chain / Image Security
30%
90%
Logging & Monitoring
50%
75%
Threat Modeling Context
10%
95%
Automated Audit Support
90%
20%
CIS Benchmark
NSA/CISA Guidance

CIS goes deep where exact flags and permissions matter. NSA/CISA goes wide where architecture and threat context matter. If you run only CIS, you are still exposed to supply-chain pivots and lateral movement through flat networks. If you run only NSA/CISA, you lack the granular remediation evidence auditors require.

03Underrated Misconfigurations (High Real-World Impact)

These weaknesses are underweighted in compliance programs because they are harder to scan, hard to fix without breaking workloads, or dismissed as "platform not cluster." In incident response, they repeat. The data below is not CVSS — it is "how often this breaks you" combined with "how often you actually see it in production."

Figure 3.1 — Risk vs prevalence. Impact bar = red. Prevalence bar = amber. Scores out of 100.
Over-permissive RBAC bindings (cluster-admin, wildcards)Risk 95/100 · Seen 70/100
Impact
Prevalence
Why it matters: Fastest path to full cluster compromise once any identity is stolen — CI runner, leaked kubeconfig, dev laptop. Stolen token + cluster-admin = game over.
ServiceAccount token auto-mount everywhereRisk 75/100 · Seen 85/100
Impact
Prevalence
Why it matters: Turns any pod RCE into Kubernetes API access. Silent escalation with huge blast radius if RBAC is not tight. The default is automountServiceAccountToken: true — every pod is a potential credential source.
Ingress config injection (snippets/annotations)Risk 90/100 · Seen 45/100
Impact
Prevalence
Why it matters: "Config" becomes "code." A bad annotation becomes request smuggling, auth bypass, or edge RCE depending on CVEs and features enabled. The IngressNightmare CVEs (CVE-2025-1097, CVE-2025-1974) showed exactly this at critical severity.
No default-deny NetworkPoliciesRisk 80/100 · Seen 80/100
Impact
Prevalence
Why it matters: Flat cluster networks let attackers pivot workload-to-workload. Without segmentation, one compromised pod reaches every database, message queue, and internal service in the cluster.
Metadata / node credentials reachable from podsRisk 85/100 · Seen 55/100
Impact
Prevalence
Why it matters: Cloud pivot via IMDS + node IAM is one of the most common "cluster → cloud account" escalation chains. Pod calls http://169.254.169.254, gets node credentials, accesses S3/IAM/RDS.
Exposed control-plane endpoints / weak API perimeterRisk 90/100 · Seen 35/100
Impact
Prevalence
Why it matters: Internet-facing API + RBAC drift + leaked credentials = full compromise with minimal effort. Less common because managed Kubernetes (EKS/GKE/AKS) protects this — but self-managed clusters still miss it.

04Overrated Controls (Effort >> Payoff)

Some controls get disproportionate attention because they are easy to measure or look impressive in audit reports. They are not useless — but they should not be your first milestone if you care about breach prevention and containment. Teams pass compliance by maximizing scanner score, while attackers still win through the same three routes: stolen identity → RBAC abuse, pod RCE → token abuse, flat network → lateral movement.

Figure 4.1 — Security ROI: effort vs payoff. Red border = over-invested. Amber = context-dependent. Green = correct priority.
Perfecting file permissions on every nodeEffort: high  ·  Payoff: medium
Relevant for self-managed control planes, but many teams burn weeks here while leaving RBAC and token sprawl unchanged. File perms on a managed node you cannot SSH into are irrelevant.
Chasing 100% CIS Level 2 immediatelyEffort: very high  ·  Payoff: uneven
Level 2 has valuable items, but applying it blindly breaks workloads. Prioritize attack-path reducers first. CIS Level 2 is a destination, not a starting point.
Admission policy without runtime visibilityEffort: medium  ·  Payoff: medium
Admission prevents future bad deploys — but it does not tell you what is already exploited. Pair with audit logs and runtime signals. Admission alone is a one-way gate with no rearview mirror.
"Encryption everywhere" without identity disciplineEffort: medium  ·  Payoff: depends
mTLS helps, but if your identities are over-permissioned, encryption does not stop authorized abuse. An attacker with a stolen ServiceAccount token does not need to break TLS.

05Control Plane: The Root of All Trust

Every Kubernetes cluster has one control plane. Compromise it and you own everything — every node, every secret, every workload. The API server is the entry point. It is also the most misconfigured component in the wild.

Anonymous Auth Enabled
--anonymous-auth=true allows unauthenticated requests to the API server. Combined with permissive RBAC, this is direct cluster compromise. CIS 1.2.1.
No Admission Controllers
Without NodeRestriction, PodSecurity, and AlwaysPullImages, any workload can request hostPID, hostNetwork, or privileged mode — instant escape to the node.
Disabled Audit Logging
No audit log means no forensic trail. Attackers enumerate secrets, exfiltrate service account tokens, and modify RBAC bindings with zero evidence. CIS 1.2.22.
Insecure Bind Address
--insecure-bind-address exposes an HTTP endpoint on localhost port 8080. Any process on the control plane node can issue unauthenticated API calls.
RBAC Disabled
Clusters running with --authorization-mode=AlwaysAllow — still found in the wild — grant every authenticated request full cluster access.
Hardened kube-apiserver manifest (critical flags)
yaml# /etc/kubernetes/manifests/kube-apiserver.yaml
spec:
  containers:
  - command:
    - kube-apiserver
    # Authentication
    - --anonymous-auth=false
    - --client-ca-file=/etc/kubernetes/pki/ca.crt
    - --tls-cert-file=/etc/kubernetes/pki/apiserver.crt
    - --tls-private-key-file=/etc/kubernetes/pki/apiserver.key
    # Authorization
    - --authorization-mode=Node,RBAC
    # Admission control
    - --enable-admission-plugins=NodeRestriction,PodSecurity,AlwaysPullImages
    # Audit logging
    - --audit-log-path=/var/log/audit.log
    - --audit-log-maxage=30
    - --audit-policy-file=/etc/kubernetes/audit-policy.yaml
    # Disable insecure port
    - --insecure-port=0
    # etcd TLS
    - --etcd-cafile=/etc/kubernetes/pki/etcd/ca.crt
    - --etcd-certfile=/etc/kubernetes/pki/apiserver-etcd-client.crt
    - --etcd-keyfile=/etc/kubernetes/pki/apiserver-etcd-client.key
File Permissions CIS 1.1.1–1.1.8 requires control plane config files owned by root with 600 permissions. Run stat /etc/kubernetes/manifests/kube-apiserver.yaml — if you see 644 or world-readable, fix it now. Privilege escalation starts with readable manifests.

06etcd: The Brain, Unencrypted

etcd stores every Kubernetes object in plaintext by default. That means every Secret, every ServiceAccount token, every certificate request — all readable by anyone with etcd access. The CIS benchmark devotes an entire section to etcd because a single misconfigured endpoint is a full credential dump.

No Encryption at Rest
Without --encryption-provider-config, all Secrets are base64-encoded strings in etcd. Anyone who can read etcd has every credential in the cluster. CIS 1.2.34.
No Peer TLS
etcd peer communication without mutual TLS allows a man-in-the-middle to intercept or inject cluster state. CIS 2.1–2.7 covers the full certificate chain required.
No Backup Encryption
etcd backups saved without encryption are full credential dumps on disk. A misconfigured backup job writing to S3 without SSE-KMS is a data breach waiting to happen.
etcd :2379 Node Compromise etcdctl get / Backup Exfil snapshot save MITM Peer no peer TLS ALL SECRETS COMPROMISED
Three distinct attack paths all terminate in the same outcome: full credential extraction from etcd.

07Worker Nodes: Where Execution Happens

Worker nodes run your workloads. They also run kubelet — the most privileged process outside the control plane. A misconfigured kubelet accepts unsigned webhook requests, allows anonymous API access, and can be coerced into executing arbitrary containers.

Real Attack Scenario Anonymous kubelet access (--anonymous-auth=true) + --authorization-mode=AlwaysAllow = unauthenticated code execution on any node. An attacker reaching port 10250 can exec into any pod, read all secrets from the node filesystem, and spawn new privileged containers. This combination was common in production clusters as recently as 2023.
Anonymous Kubelet Auth
authentication.anonymous.enabled: true allows unauthenticated access to the kubelet API. Combined with permissive authorization, this is remote code execution on any node. CIS 4.2.1.
Webhook Authorization Disabled
Without authorization.mode: Webhook, kubelet self-authorizes all requests. The RBAC policies you crafted on the API server have no effect on direct kubelet calls. CIS 4.2.3.
Read-Only Port Open
Port 10255 exposes pod and node metadata without authentication. Attackers use it for reconnaissance — mapping workloads, reading environment variables, and identifying high-value targets. CIS 4.2.4.
Hardened kubelet configuration
yaml# /var/lib/kubelet/config.yaml
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
authentication:
  anonymous:
    enabled: false           # CIS 4.2.1
  webhook:
    enabled: true            # CIS 4.2.2
  x509:
    clientCAFile: /etc/kubernetes/pki/ca.crt
authorization:
  mode: Webhook              # CIS 4.2.3 - delegate to API server RBAC
readOnlyPort: 0              # CIS 4.2.4 - disable unauthenticated metrics
protectKernelDefaults: true  # CIS 4.2.6
eventRecordQPS: 0
tlsCertFile: /var/lib/kubelet/pki/kubelet.crt
tlsPrivateKeyFile: /var/lib/kubelet/pki/kubelet.key

08RBAC, PSS, and Network Policies

Policy misconfigurations are the most common finding in Kubernetes security assessments. They are also the hardest to remediate after the fact — every change risks breaking production workloads. The three policy layers that matter most are RBAC bindings, Pod Security Standards enforcement, and network segmentation.

RBAC: Wildcards Kill

Audit wildcard RBAC bindings and token sprawl
bash# Find ClusterRoles with wildcard permissions
kubectl get clusterroles -o json |   jq '.items[] | select(.rules[]?.verbs[]? == "*") | .metadata.name'

# Find ClusterRoleBindings to cluster-admin
kubectl get clusterrolebindings -o json |   jq '.items[] | select(.roleRef.name == "cluster-admin") | {name: .metadata.name, subjects: .subjects}'

# Find ServiceAccounts with automount enabled (the dangerous default)
kubectl get sa --all-namespaces -o json |   jq '.items[] | select((.automountServiceAccountToken // true) == true) | {ns: .metadata.namespace, name: .metadata.name}'

# Find pods with unexpected SA token + network access to API server
kubectl get pods --all-namespaces -o json |   jq '.items[] | select(.spec.automountServiceAccountToken != false) | {ns: .metadata.namespace, name: .metadata.name}'
Dangerous RBAC pattern — wildcard on all resources
yamlrules:
- apiGroups: ["*"]
  resources: ["*"]   # Full cluster access
  verbs: ["*"]
Least-privilege pattern — read-only pods in one namespace
yamlrules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list", "watch"]

Pod Security Standards

PodSecurityPolicy was deprecated in 1.21 and removed in 1.25. Its replacement — Pod Security Admission (PSA) — enforces three built-in profiles via namespace labels. The NSA/CISA guide explicitly requires enforcing the restricted profile on all non-system namespaces.

Privileged Profile

No restrictions. Pods run as root, mount the host filesystem, use hostPID, hostNetwork. This is the default if no PSA label is set — a misconfigured namespace is a privileged namespace.

Baseline Profile

Blocks the most egregious misconfigurations: privileged containers, host namespace sharing, most dangerous volume types. Suitable for most workloads without modification.

Restricted Profile

The NSA/CISA recommended target. Requires non-root user, read-only root filesystem, drops all capabilities, blocks privilege escalation. Some legacy workloads will break — that is the point.

Enforcement Strategy

Label critical namespaces enforce=restricted, warn+audit others. Never label kube-system — it will break system workloads that legitimately need elevated privileges.

NetworkPolicy: Default Deny

Default-deny NetworkPolicy — drop all ingress and egress
yamlapiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-all
  namespace: production
spec:
  podSelector: {}     # applies to all pods in namespace
  policyTypes:
  - Ingress
  - Egress
  # No rules = deny all. Add explicit allows per workload.
Falco rule — detect ServiceAccount token access
yaml- rule: ServiceAccount Token Read
  desc: Detect process reading SA token from well-known mount path
  condition: >
    open_read and
    fd.name startswith /var/run/secrets/kubernetes.io/serviceaccount and
    not proc.name in (allowed_sa_consumers)
  output: >
    SA token read (user=%user.name proc=%proc.name
    file=%fd.name ns=%k8s.ns.name pod=%k8s.pod.name)
  priority: WARNING
  tags: [T1078.004, k8s, rbac]

09NSA/CISA Gap Analysis: What CIS Misses

CIS Kubernetes Benchmark is a configuration posture guide. It tells you what flags to set, what file permissions to apply, what to enable and disable. What it does not cover is the operational security posture that NSA/CISA hardening guidance addresses: supply chain integrity, runtime detection, network encryption in transit, and workload identity at scale.

If your compliance program only covers CIS, you have a hardened attack surface with no detection capability. Attackers get in through supply chain compromise, move laterally through pod-to-pod traffic, and exfiltrate data over encrypted outbound connections your NetworkPolicy never blocked because you never implemented egress filtering for HTTPS:443.

NSA/CISA Beyond CIS Supply Chain SBOM / Sigstore Runtime Detection eBPF / syscall audit Tamper-proof Logs WORM / SIEM sink mTLS Everywhere Istio / Linkerd Workload Identity SPIFFE / IRSA Immutable Infra distroless / no-shell
Six critical security domains covered by NSA/CISA guidance that have no equivalent control in the CIS Kubernetes Benchmark.
Falco rule — detect container escape via nsenter/chroot
yaml- rule: Container Escape via Namespace Enter
  desc: Detect nsenter or chroot used to escape container namespace
  condition: >
    spawned_process and
    proc.name in (nsenter, chroot, unshare) and
    container.id != host
  output: >
    Potential container escape (user=%user.name proc=%proc.name
    args=%proc.args pod=%k8s.pod.name ns=%k8s.ns.name)
  priority: CRITICAL
  tags: [T1611, container_escape, k8s]

10Customize Your Compliance Benchmark

"One benchmark fits all" is false. You customize by mapping controls to your threat model, blast radius, and operational constraints. Treat the benchmark as a control library, then classify each control into one of three tiers — not by CIS section number, but by what it actually blocks.

Mandatory
Stops critical compromise paths immediately. Low risk of breaking workloads (or has a safe rollout pattern). Strong evidence and easy to verify continuously.
RBAC restrictions, API auth settings, default-deny networking baseline, token discipline, disabling dangerous ingress features.
Suitable (Context-Dependent)
Valid only under certain architectures (managed vs self-managed). Or compensating controls already reduce the same risk. Or cost is high relative to top attack paths.
Deep node file permission tuning in fully managed clusters. CIS L2 everywhere without segmentation and RBAC hygiene first.
Control scoring rubric — classify each CIS check (0–5 per dimension)
text# Score each control on five dimensions (0–5 each):

1) Exploitability reduction   — does it remove a common attacker primitive?
2) Blast radius reduction     — does it contain compromise to namespace/workload?
3) Coverage                   — does it protect many workloads/teams by default?
4) Operational cost           — how hard to deploy and maintain without breaking apps?
5) Verifiability              — can you continuously prove it (policy/audit evidence)?

Classify:
  Mandatory       (1+2+3) high,          (4) manageable,  (5) high
  Recommended     (1+2+3) medium-high,   (4) medium-high, (5) medium
  Suitable        (1+2+3) variable,      strongly context-dependent
Managed cluster (EKS, GKE, AKS) or self-managed?
Managed clusters hide the control plane. You cannot modify kube-apiserver flags directly. Focus CIS remediation on worker node, RBAC, and policy sections. The cloud provider owns control plane hardening — verify their shared responsibility model before auditing controls you cannot change.
Single-tenant or multi-tenant cluster?
Multi-tenant clusters require namespace isolation, strict RBAC, and NetworkPolicy enforced at namespace level. Pod Security Admission at restricted should be the default. Single-tenant clusters can tolerate baseline if workloads have legitimate privileged requirements — document and accept deviations explicitly.
What is your blast radius if a control breaks production?
Apply changes in staging first. Use warn and audit modes for Pod Security Admission before enforce. Test admission controller changes against your full workload manifest set. A compliance change that takes down production erodes trust in the entire security program.

11Security Roadmap vs Compliance Roadmap

Compliance is a snapshot. Security is a system. You do not win by "being compliant." You win by continuously shrinking attack paths and shortening detection and response time. Treat your security program like an engineering system with feedback loops — not a checklist you complete once a year.

P1
Phase 1 — 0 to 30 Days: Eliminate Critical Paths
RBAC blast radius reduction (ban cluster-admin for humans and CI SAs), token defaults (automountServiceAccountToken: false), API server perimeter (disable anonymous auth, close insecure port), ban ingress config injection features, baseline default-deny NetworkPolicy per namespace. These are Mandatory controls — they stop the three most common attack routes immediately.
P2
Phase 2 — 30 to 90 Days: Supply Chain Integrity
Image pinning by digest in all production workloads, SBOM generation in CI pipeline, signature verification via admission webhook (Sigstore/Cosign), Pod Security Admission aligned with NSA/CISA restricted profile, egress control with explicit allowlists. These are Recommended controls that require engineering sequencing and app team coordination.
P3
Phase 3 — 90 to 180 Days: Detection and Response Maturity
Audit logs with high-signal alert rules (secret access, RBAC mutations, privilege escalation), eBPF-based runtime detection (Falco, Tetragon), incident playbooks per attack category, chaos validation of detection coverage. This phase answers "are we detecting what we think we are detecting?"
High-signal operational checks — run these continuously, not just at audit time
bash# Identity / RBAC
# Find cluster-admin bindings (humans + CI service accounts)
kubectl get clusterrolebindings -o json | jq '.items[] | select(.roleRef.name == "cluster-admin") | .subjects'

# Detect wildcard roles: verbs: ["*"] or resources: ["*"]
kubectl get clusterroles -o json | jq '.items[] | select(.rules[]? | (.verbs[]? == "*") or (.resources[]? == "*")) | .metadata.name'

# Token discipline — find pods with automount enabled
kubectl get pods --all-namespaces -o json |   jq '.items[] | select(.spec.automountServiceAccountToken != false) | "\(.metadata.namespace)/\(.metadata.name)"'

# Network containment — find namespaces with no NetworkPolicy
kubectl get namespaces -o json | jq -r '.items[].metadata.name' | while read ns; do
  count=$(kubectl get networkpolicies -n $ns --no-headers 2>/dev/null | wc -l)
  [ "$count" -eq 0 ] && echo "NO POLICY: $ns"
done

# Run kube-bench and filter only FAIL findings
kubectl apply -f https://raw.githubusercontent.com/aquasecurity/kube-bench/main/job.yaml
kubectl wait --for=condition=complete job/kube-bench --timeout=120s
kubectl logs job/kube-bench | grep -E '\[FAIL\]' | awk '{print $2, $3, $4, $5}'
kubectl delete job kube-bench

12Priority Tier Matrix: Security Over Compliance

Not every CIS control blocks a real attack. When you cannot fix everything at once, use this matrix — ranked by exploitability, blast radius, and operational feasibility.

Tier 1 — 24hr
Immediate: Authentication and Authorization Gaps
Disable anonymous auth on API server and kubelet. Enable RBAC. Close insecure port. Remove wildcard ClusterRoleBindings. Audit and remove unnecessary cluster-admin bindings. Set automountServiceAccountToken: false by default. These controls block unauthenticated access — the fastest path to full cluster compromise.
Tier 2 — 1 Week
Critical: etcd Security and Audit Logging
Enable etcd encryption at rest with AES-GCM-256. Enforce mutual TLS for etcd peer and client communication. Enable API server audit logging with a policy capturing secret access and RBAC mutations. Without these, credential exfiltration is undetectable and forensics are impossible.
Tier 3 — 1 Month
High: Pod Security, Admission Control, and Networking
Enable Pod Security Admission with baseline enforced on all namespaces and restricted where feasible. Add NodeRestriction and AlwaysPullImages admission plugins. Implement default-deny NetworkPolicy across all application namespaces. Block IMDS/metadata access from pods. Disable ingress config snippets and audit annotations.
Tier 4 — Next Quarter
Medium: Runtime Detection and Supply Chain
Deploy eBPF-based runtime detection (Falco, Tetragon). Enforce image signing verification via admission webhook. Implement SBOM generation in CI pipeline. Enable Sigstore policy enforcement for production namespaces. Add high-signal Falco rules for container escape, token exfil, and RBAC mutation.
Tier 5 — Hygiene
Hygiene: Rotation, Expiry, and Configuration Drift
Automate certificate rotation with cert-manager. Set up kubeconfig expiry alerts. Run CIS scanner weekly and fail CI on new findings. Drift detection matters less than the first four tiers but compounds over time. This is where you verify continuous compliance, not achieve it.
Final Word

Use CIS for the precision — auditable, scanner-friendly, granular flag-level controls that give your audit team evidence they can reproduce. Use NSA/CISA for the threat model — architecture-first thinking that tells you why controls matter and what attacker behavior they prevent. Then customize: classify every control as Mandatory, Recommended, or Suitable based on exploitability and blast radius in your environment, not checkbox comfort.

Compliance frameworks are a floor, not a ceiling. The controls that matter most — anonymous auth, RBAC wildcard removal, etcd encryption, default-deny networking, token discipline — are not the ones that take the most effort to implement. They take effort to justify because they break things. Breaking things in staging is how you build a cluster that does not break under attack. Every control you defer is a bet that your attacker has not read the same benchmark you have. They have. And they are checking faster than your scanner runs.

Compliance is what you show auditors. Security is what you show attackers.
Riad DAHMANI — k8sec Security Research

K8SEC continuously monitors your cluster posture against CIS, NSA/CISA, and runtime behavioral baselines — giving you the prioritized remediation queue your compliance scanner cannot.

Explore K8SEC on GitHub

Related Research