How to Secure a Kubernetes Cluster: RBAC, Pod Hardening, and Runtime Protection

How to Secure a Kubernetes Cluster: RBAC, Pod Hardening, and Runtime Protection

How to Secure a Kubernetes Cluster: RBAC, Pod Hardening, and Runtime Protection

In 2018, RedLock’s cloud security research team discovered that Tesla’s Kubernetes dashboard was exposed to the public internet with no password on it. An attacker had found it, deployed pods inside Tesla’s cluster, and was using them to mine cryptocurrency – all on Tesla’s AWS bill. The cluster had no authentication on the dashboard, no network restrictions on egress, and nothing monitoring for intrusion. Any one of those controls would have stopped the attack. None of them were in place.

This wasn’t a sophisticated zero-day exploit. It was a misconfigured default.

The Kubernetes Threat Landscape

To understand what you’re defending against, you need to understand where Kubernetes exposes attack surface. There are six main areas, and most production incidents trace back to at least one of them.

The API server is the front door to your cluster. Every kubectl command, every CI deploy, and every controller reconciliation loop sends requests here. Unauthenticated or over-privileged access to the API server is effectively game over: an attacker who can talk to it can create pods, read secrets, and modify workloads freely.

etcd is the key-value store where all cluster state lives, including your Secrets. Kubernetes Secrets are base64-encoded by default, not encrypted. Anyone with direct access to etcd can read every password, token, and certificate in the cluster without going through the API server at all.

The kubelet runs on each node and manages the pods assigned to it. If its API is reachable without authentication – which is the default on older clusters – an attacker can exec into any pod on that node and read its memory without ever touching the API server.

The container runtime is the layer that actually runs your containers. A container that escapes its isolation boundary lands directly in the host OS. A privileged container with hostPID: true can read the memory of every other process on the node, including other containers.

Your supply chain (base images, third-party dependencies, Helm charts, operators) is a potential entry point at every step. The XZ Utils backdoor discovered in 2024 showed how close a well-positioned supply chain attack can come to widespread infrastructure compromise.

Finally, the network: by default, every pod in a Kubernetes cluster can reach every other pod on any port. There are no internal firewalls between workloads unless you explicitly create them with NetworkPolicy.

Real-World Breaches

These three incidents are worth understanding before you write a single line of YAML. They’re not theoretical – they’re documented post-mortems from real production clusters.

Incident Year Root cause What was missing

Tesla cryptomining 2018 Kubernetes dashboard exposed with no authentication, Unrestricted egress RBAC on the dashboard endpoint + default-deny NetworkPolicy

Capital One data breach 2019 SSRF vulnerability in a WAF let an attacker reach the EC2 metadata API, which returned credentials for an over-privileged IAM role Pod-level IAM restrictions (IRSA) + blocking metadata API egress

Shopify bug bounty (Kubernetes) 2021 A researcher accessed internal Kubernetes metadata through a misconfigured internal service, exposing pod environment variables containing secrets Secret management outside environment variables + network segmentation

The pattern across all three: not zero-day exploits, but misconfigured defaults and missing controls that should have been standard practice.

This article addresses the RBAC and pod security gaps directly.

What You’ll Build

Before the first command, here is the security posture you’ll have by the end of this article:

You’ll start by running kube-bench to get a CIS Benchmark baseline – a concrete score showing where a default cluster stands before any hardening. From there you’ll build a least-privilege RBAC policy for a CI pipeline service account and verify its permission boundaries, then audit the full cluster to confirm no over-privileged accounts exist.

On the pod security side, you’ll enforce the restricted Pod Security Admission profile on your workload namespace and apply a hardened securityContext to a deployment: non-root user, read-only root filesystem, dropped capabilities, and seccomp profile. To close out, you’ll deploy Falco in eBPF mode with a custom detection rule that fires when suspicious tools are run inside a container.

Start to finish, with a kind cluster already running, the demos take about 45–60 minutes.

Prerequisites

Before you begin, make sure you have the following:

kubectl installed and configured

Docker Desktop or a Linux machine (to run kind)

Basic Kubernetes familiarity – you know what a Pod, Deployment, and Namespace are

No prior security experience needed

Demo 1: Run a Cluster Security Baseline with kube-bench

Before hardening anything, it’s a good idea to measure where you are. kube-bench runs the CIS Kubernetes Benchmark against your cluster and reports which checks pass and which fail. A baseline run gives you a concrete picture of your cluster’s default security posture – and a reference point you can re-run after applying any hardening changes.

Step 1: Create a kind cluster

Save the following as kind-config.yaml:

# kind-config.yaml

kind: Cluster

apiVersion: kind.x-k8s.io/v1alpha4

nodes:

– role: control-plane

r

Target: 1000 words.