Kubernetes Security Hardening: A Practical Baseline
A practical Kubernetes hardening baseline for defenders: control plane, RBAC, workload and network controls, plus detection signals and a checklist.
Kubernetes has become the default control plane for modern workloads, and with that ubiquity it has also become a rich target. A cluster is not a single system but a distributed collection of APIs, controllers, network paths, and identities, and each of those layers can be misconfigured in ways that quietly widen the blast radius of a single compromised container. This article lays out a practical hardening baseline for defenders and platform engineers who own clusters in production. The framing throughout is understand in order to defend: we describe how weaknesses arise, what telemetry reveals abuse, and which controls shrink the attack surface without turning the platform into something nobody can operate.
Why a hardening baseline matters
Default Kubernetes installations optimize for functionality and developer velocity, not for least privilege. Out of the box you may find permissive service account token mounting, containers running as root, no network policy at all, and an API server reachable from more places than anyone intended. None of this is a bug; it is a starting point that assumes you will apply your own guardrails. A baseline gives you a written, testable definition of the minimum posture every cluster must meet, so that security is a property of the platform rather than something each team reinvents. Without it, drift is inevitable and audits become archaeology.
A good baseline is layered. It covers the control plane, the nodes, the workloads, the network, the supply chain, and the identities that tie them together. It is also enforced by machinery rather than by good intentions: admission control, policy-as-code, and continuous configuration scanning turn the baseline into something the cluster refuses to violate.
The control plane and API server
The API server is the front door to everything. Anonymous authentication should be disabled, and every request should carry a verifiable identity backed by short-lived credentials. The kube-apiserver audit log is your single most valuable source of truth; enable it with a policy that records metadata for reads and full request bodies for writes to sensitive resources such as secrets, roles, and role bindings. Store those logs off-cluster so an attacker who lands inside cannot trim their own tracks. Etcd, which holds the entire cluster state including secrets, must be encrypted at rest and reachable only by the API server over mutual TLS.
Restrict who can reach the API endpoint at the network level. A managed control plane with a private endpoint and an allowlist of authorized networks removes a large swath of internet-facing risk. Certificates should rotate automatically, and the cluster's admin kubeconfig should be treated like a crown-jewel credential rather than a file that lives on laptops.
Workload identity and RBAC
Role-based access control is where most real-world clusters leak privilege. The two anti-patterns to hunt for are wildcard verbs or resources in a role, and bindings to the built-in cluster-admin role for humans or service accounts that do not truly need it. Grant the narrowest set of verbs on the narrowest set of resources in the narrowest scope, and prefer namespaced roles over cluster-wide ones. Every service account that can create pods, read secrets, or modify role bindings is effectively a path to broader control, because those verbs can be chained into escalation.
Disable automatic service account token mounting by default and opt workloads in only when they genuinely call the API. Where a workload does need cloud permissions, use the platform's workload identity federation so pods receive short-lived, audience-scoped tokens instead of long-lived static keys baked into secrets. Review RBAC continuously; a binding that was reasonable last quarter may be dangerous after a team reorganization.
Hardening the workloads themselves
At the pod level, the goal is to make a compromised container a dead end rather than a launch pad. Run as a non-root user with a read-only root filesystem, drop all Linux capabilities and add back only what is strictly required, and forbid privilege escalation with allowPrivilegeEscalation: false. Privileged containers, host namespace sharing (hostPID, hostNetwork, hostIPC), and host path mounts are the features attackers most want, because each one erodes the boundary between the container and the node. Treat them as exceptions that require explicit review, not defaults.
Apply a seccomp profile such as RuntimeDefault to constrain the system calls a container may issue, and where your workloads tolerate it, layer AppArmor or SELinux on top. The Pod Security Standards give you three named tiers — privileged, baseline, and restricted — and the built-in Pod Security Admission controller can enforce the restricted tier per namespace. For richer rules, a policy engine such as Kyverno or an OPA/Gatekeeper deployment lets you express and enforce organization-specific constraints as code.
Network segmentation
By default every pod can talk to every other pod, which means one foothold sees the entire east-west surface. A default-deny NetworkPolicy per namespace, followed by explicit allow rules for the flows each application actually needs, is one of the highest-leverage controls you can apply. It converts lateral movement from a trivial hop into an activity that must cross an enforced boundary, and it makes anomalous connections visible. For stronger guarantees, a service mesh can add mutual TLS between services and identity-aware authorization, so that a stolen network position is not the same as a stolen identity.
Do not forget egress. Locking down what pods may reach outbound limits data exfiltration and blunts malware that phones home to a command-and-control host. Combine network policy with DNS and egress logging so that unexpected outbound destinations become detectable events.
Detection: signals that reveal abuse
Hardening reduces the attack surface; detection tells you when someone probes what remains. The richest signal is the API audit log. Watch for requests to enumerate secrets across namespaces, creation or modification of ClusterRoleBinding objects, exec or attach into running pods, and pods spawned with privileged or host-namespace settings. A sudden burst of 403 Forbidden responses from a single service account often means credentials were stolen and are being tested against resources they were never meant to touch.
At runtime, a behavioral sensor such as Falco or an EDR agent with container awareness can flag a shell spawned inside a container, an unexpected process reading /etc/shadow, a write to a normally read-only path, or an outbound connection to a suspicious address. Correlate cluster events with node-level and cloud-provider logs; an attacker escaping to the node or pivoting to the cloud metadata endpoint leaves traces in more than one place, and the correlation is what turns isolated noise into a clear story.
Common pitfalls
Teams frequently ship a strong policy in a staging cluster and then grant broad exceptions in production because a deadline loomed, and the exception never gets revisited. Another recurring mistake is enforcing pod security while leaving the API server reachable from anywhere, so the strongest wall has no gate. Overly broad image pull secrets, secrets passed as environment variables where they surface in logs and crash dumps, and clusters that never rotate credentials are all common gaps. Finally, disabling the audit log because it is noisy trades your best forensic asset for a little less storage — a bargain you will regret during an incident.
A practical checklist
Use this as a starting baseline and adapt it to your risk. Control plane: anonymous auth off, audit logging on and shipped off-cluster, etcd encrypted, private API endpoint with network allowlist. Identity: no standing cluster-admin, no wildcard RBAC, service account token automounting off by default, workload identity for cloud access. Workloads: non-root, read-only root filesystem, capabilities dropped, no privilege escalation, seccomp RuntimeDefault, Pod Security Admission restricted, no host namespaces without review. Network: default-deny ingress and egress per namespace, explicit allow rules, mesh mTLS where feasible. Supply chain: signed images, admission verification, vulnerability scanning as a gate. Detection: audit-log alerts, runtime behavioral sensor, log retention that outlives dwell time.
FAQ: Is Pod Security Admission enough on its own?
It is a strong, built-in foundation for enforcing the restricted profile, and every cluster should use it. But it is deliberately limited to a fixed set of pod-level controls. For organization-specific rules — required labels, allowed registries, image signature checks, or resource quotas tied to policy — you will want a general policy engine like Kyverno or Gatekeeper alongside it. Think of Pod Security Admission as the floor and the policy engine as the walls you build on top.
FAQ: How do I harden without blocking developers?
Start in an audit or warn mode so teams see what would be blocked before anything actually breaks, and publish the baseline with clear remediation guidance. Provide golden paths — hardened base images, ready-made policy exemption processes, and templates that already satisfy the rules — so that the secure option is also the easy one. Enforcement lands smoothly when the platform team removes friction rather than simply saying no.
Conclusion
A Kubernetes hardening baseline is not a one-time project but a living contract between security and the teams who ship on the platform. Lock down the control plane, constrain identity with least-privilege RBAC and workload identity, make compromised containers into dead ends, segment the network by default, verify your supply chain, and instrument everything so that abuse is visible. Enforce it with admission control and policy-as-code so the posture cannot silently drift. Done well, hardening is invisible to the people building on the cluster and decisive against the people trying to break in.

