KubeTW All articles
Architecture & Strategy

RBAC Looks Great on Paper—Your Cluster Tells a Different Story

KubeTW
RBAC Looks Great on Paper—Your Cluster Tells a Different Story

There's a particular kind of confidence that comes from finishing your RBAC configuration. You've got ClusterRoles, RoleBindings, a spreadsheet someone made in Q3 that documents who has access to what. Your security team signed off. Your auditor nodded. You shipped.

And then a penetration tester gets into your cluster in forty-five minutes using permissions you were certain were harmless.

This isn't a rare edge case. It's the default outcome for teams that treat RBAC as a checklist rather than a security posture. The gap between "we have RBAC" and "our RBAC actually protects us" is wider than most people want to admit, and the consequences of getting it wrong aren't theoretical—they're lateral movement, privilege escalation, and eventually, a very bad Friday afternoon.

Let's talk about where it actually breaks down.

The * Wildcard Problem Nobody Talks About

Open up your ClusterRoles right now and search for resources: ["*"] or verbs: ["*"]. If you find them, you've probably already lost the plot on least-privilege access.

Wildcard permissions are the RBAC equivalent of giving someone a master key because you couldn't figure out which doors they actually needed to open. They're common in default roles, they get copy-pasted into custom roles during crunch time, and they almost never get cleaned up afterward.

The sneaky part is that these roles often look scoped. They're bound to a specific namespace. They're attached to a service account that only runs one workload. Everything seems fine until that workload gets compromised and suddenly an attacker has the ability to read Secrets, create Pods, or modify ConfigMaps across everything in that namespace—which is usually a lot more than you'd expect.

Audit your roles with kubectl get clusterroles -o yaml and pipe it through a grep for wildcards. What you find will probably ruin your afternoon.

Escalation Through bind and escalate

Here's one that catches even experienced teams off guard. If a principal has the bind verb on a RoleBinding or ClusterRoleBinding resource, they can bind any role to any subject—including themselves. That's privilege escalation with a Kubernetes-native bow on top.

Similarly, the escalate verb on Role or ClusterRole resources lets a user modify roles to include permissions they don't currently have. It's a direct path from limited access to cluster admin, and it's sitting quietly in plenty of production environments right now.

These aren't obscure attack vectors. They're documented in the Kubernetes security documentation and well-known in the security community. The reason they persist is that they're easy to miss in a manual audit and don't trigger obvious alerts in most observability setups.

The fix is straightforward in principle: treat bind and escalate like you'd treat cluster-admin. Restrict them aggressively, document every exception, and review those exceptions on a schedule.

Service Account Tokens: Your Cluster's Skeleton Key Problem

Every Pod in your cluster gets a service account token mounted by default. You probably know this. What's less appreciated is how often those tokens carry permissions that far exceed what the workload actually needs.

The classic scenario looks like this: a developer needs a deployment pipeline to apply manifests, so they attach a service account with broad apply permissions. Six months later, that same service account is running a web application that has no business touching the Kubernetes API at all. The token is still mounted. The permissions are still there.

An attacker who compromises that application container now has a credential that can interact with your cluster's API server. Depending on what that service account can do, the blast radius ranges from "annoying" to "catastrophic."

Start by disabling automatic token mounting for service accounts that don't need API access: automountServiceAccountToken: false at the Pod or ServiceAccount spec level. Then audit what your active service account tokens can actually do using kubectl auth can-i --list --as=system:serviceaccount:namespace:name.

The Audit Log Gap

RBAC tells Kubernetes what to allow. It doesn't tell you what's actually happening. If you're not running audit logging with a policy that captures RBAC-relevant events, you're flying blind on whether your permission model is being abused.

A lot of teams enable audit logging and then configure it so conservatively that it captures almost nothing useful. The None audit level on resource requests is common. The result is that privilege escalation attempts, unusual API calls from service accounts, and repeated authorization failures disappear into the void.

Your audit policy should at minimum capture RequestResponse level logging for sensitive resource types—Secrets, RoleBindings, ClusterRoleBindings, and Pods. Yes, this generates more data. That's the point. Run it through something like Falco or feed it into your SIEM, and set up alerts for the patterns that matter: new ClusterRoleBindings being created, service accounts accessing Secrets they've never touched before, exec calls into running containers.

Building RBAC That Actually Holds Up

Least-privilege access isn't a configuration you finish—it's a practice you maintain. Here's a practical framework that doesn't require a security engineering background to implement:

Start with namespace isolation as your foundation. Most workloads don't need cluster-scoped permissions. Default to Roles and RoleBindings instead of ClusterRoles and ClusterRoleBindings unless you have a specific, documented reason to go broader.

Enumerate permissions explicitly. Never use wildcards in production roles. Yes, it's more verbose. Yes, it's worth it. List exactly the resources and verbs each principal needs, and revisit that list every time the workload's responsibilities change.

Treat service accounts like user accounts. Every service account should have a documented purpose, the minimum permissions required for that purpose, and a review date. Service accounts that no longer have active workloads should be deleted.

Run automated RBAC audits. Tools like rbac-tool, rakkess, and kubectl-who-can make it practical to audit your permission model on a regular cadence. Integrate them into your CI pipeline so new roles get reviewed before they hit production.

Simulate attacks before attackers do. Red team exercises focused specifically on RBAC escalation paths are one of the highest-value security investments a Kubernetes team can make. You don't need a dedicated red team—even a structured internal review using known escalation techniques will surface issues that automated tools miss.

The Compliance Trap

Here's the uncomfortable truth underneath all of this: RBAC compliance and RBAC security are not the same thing. Auditors check for the presence of RBAC configuration. They rarely validate whether that configuration actually enforces least-privilege access, whether escalation paths exist, or whether audit logging is capturing meaningful data.

You can pass a SOC 2 audit with a permission model that a competent attacker would tear through in under an hour. This isn't a knock on auditors—it's a structural limitation of compliance frameworks that can't fully account for the operational complexity of a live Kubernetes environment.

The teams that actually get this right aren't the ones with the most sophisticated tooling. They're the ones that treat their RBAC configuration as a living document, review it regularly, and resist the organizational pressure to grant broad permissions because it's faster and easier than figuring out exactly what's needed.

Your cluster is only as secure as the permissions you've actually thought through. Everything else is theater.

All Articles

Keep Reading

GitOps Looked Great on the Whiteboard—So Why Is Your Cluster Still a Mess?

GitOps Looked Great on the Whiteboard—So Why Is Your Cluster Still a Mess?

Your API Server Is Quietly Choking—Here's How to Catch It Before Your Cluster Does

Your API Server Is Quietly Choking—Here's How to Catch It Before Your Cluster Does

Pod Placement Roulette: Taking Back Control of Your Kubernetes Scheduler

Pod Placement Roulette: Taking Back Control of Your Kubernetes Scheduler