KCSA — Kubernetes Security Associate
The 4Cs — An Outer Layer Cannot Save an Inner One
In one line
Cloud → Cluster → Container → Code. In these four layers, the outer layer wraps the inner one but does not do its job for it. Even if the cloud firewall is perfect, if the code has no authorization check, a legitimate user sees someone else's data.
Why this was needed
"Let's strengthen security" points in no direction at all. Whether to tighten the firewall, fix RBAC, scan images, or do more code review — all of it is security, but the threats they block are completely different.
The 4C model sorts out this confusion. It makes clear what each layer can block and what it cannot block in principle.
How it works
The four layers and what each is responsible for
| Layer | Controls | What it can block here | What it cannot block here |
|---|---|---|---|
| Cloud/Infrastructure | Network perimeter, IAM, node OS, physical security | Direct connections from the internet to the apiserver and etcd | An insider with legitimate credentials |
| Cluster | Authentication/authorization (RBAC), admission, network policy, audit log | Unauthorized API calls, dangerous Pod specs | Misuse that happens within one's permissions |
| Container | Image provenance and scanning, least-privilege execution, read-only root | Vulnerable base images, running as root | Application logic flaws |
| Code | Authorization checks, input validation, secret handling, dependency management | IDOR, injection, hardcoded keys | Configuration mistakes in the layers above |
Why the outer layers cannot save the inner ones
There are three reasons.
First, the outer layers do not know the meaning of a request. A cloud firewall sees only "who opened TCP to where." Whether a legitimate logged-in user calling GET /v1/orders/10422 is asking for their own order or someone else's, the firewall has no basis to judge. The information needed for that judgment lives in the database.
Second, a flaw in an inner layer looks like normal traffic from an outer layer. An IDOR attack's request passes authentication and the response code is 200. There is not a single failed request, so no alarm goes off.
Third, the layers lean on each other's assumptions. No matter how much you run a container with least privilege, if the node is taken over, every container on that node goes down with it. Conversely, even if the node is solid, if the code dumps credentials to a log, that value flows into the log index.
So how do you use it
4C is not a tool for "do it all" but for asking "at which layer is it cheapest and most certain to block this threat?"
- etcd port 2379 is open to the internet → a Cloud layer problem. Closing it with a firewall is the right answer, and strengthening etcd authentication is second best.
- A developer reads a production Secret → a Cluster layer (RBAC) problem. Code cannot block it.
- A Pod runs as root → the Container layer. You block it with PSA or admission.
- Someone else's order form is visible → the Code layer. No infrastructure control can block it.
What it looks like in the field
In the author's homelab, there was an incident in which the layer dependencies of 4C showed up exactly as described.
When a DHCP renewal changed the control plane node's IP from .111 to .120, the whole cluster stopped.
A single event in the Cloud/Infrastructure layer, IP address assignment, disabled the entire Cluster layer.
More precisely, the problem was the certificate. The Subject Alternative Name of apiserver.crt had only .111 and lacked .120. Because TLS trust was tied to an IP, a single address change in the infrastructure layer broke the identity system of the cluster layer.
A similar lesson came up after growing the same cluster to 7 nodes. Quorum was secured with 3 etcd members,
but controlPlaneEndpoint was hardcoded to cp-1's physical IP, so when cp-1 died the data was safe but nobody could connect. "Data availability and access availability are separate" — this is the same story that the layers cannot do each other's jobs.
What to read next
In the readings that follow, we unfold each layer's attack surface into a concrete list of entry points. From the next module, we go down to the Cluster layer and take apart the apiserver, etcd, and kubelet one by one.