"The first thing most attackers look for after gaining a foothold in a Kubernetes cluster is an over-permissioned service account. And more often than not, they find one. Kubernetes RBAC is the primary gatekeeper standing between a compromised pod and full cluster takeover — yet it remains one of the most misunderstood and poorly implemented security controls in production environments. Let's fix that."
Why RBAC Matters More Than You Think
Every Kubernetes cluster ships with a powerful authorization framework, but defaults are dangerously permissive. The system:discovery and system:basic-user ClusterRoles are bound to all authenticated users out of the box. Without deliberate RBAC hardening, a single leaked service account token can enumerate the entire API surface.
RBAC isn't just an admin convenience — it's your primary authorization layer. Network policies, admission controllers, and pod security standards all matter, but RBAC determines who can do what at the API server level. Get it wrong, and everything downstream is compromised.
The Four Building Blocks
Kubernetes RBAC operates on four objects:
- Role – Grants permissions within a single namespace.
- ClusterRole – Grants permissions cluster-wide or across namespaces.
- RoleBinding – Binds a Role (or ClusterRole) to subjects within a namespace.
- ClusterRoleBinding – Binds a ClusterRole to subjects across the entire cluster.
The critical mental model: Roles define permissions. Bindings assign them to users, groups, or service accounts.
Practical Example: Scoping a Deployment Pipeline
Suppose your CI/CD pipeline needs to deploy applications to the staging namespace but should never touch production or modify RBAC policies. Here's a least-privilege implementation:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: staging
name: cicd-deployer
rules:
- apiGroups: ['apps']
resources: ['deployments', 'replicasets']
verbs: ['get', 'list', 'create', 'update', 'patch']
- apiGroups: ['']
resources: ['services', 'configmaps']
verbs: ['get', 'list', 'create', 'update']apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
namespace: staging
name: cicd-deployer-binding
subjects:
- kind: ServiceAccount
name: cicd-pipeline
namespace: staging
roleRef:
kind: Role
name: cicd-deployer
apiGroup: rbac.authorization.k8s.ioNotice what's absent: no delete verb, no access to secrets, no wildcard * permissions, and no cluster-level scope. This service account can deploy to staging and nothing else.
Common Misconfigurations That Create Real Risk
1. Wildcard permissions in production. A rule with resources: ["*"] and verbs: ["*"] is effectively cluster-admin. Audit for these aggressively.
2. ClusterRoleBindings where RoleBindings suffice. Binding a ClusterRole via a ClusterRoleBinding grants those permissions everywhere. Binding the same ClusterRole via a namespaced RoleBinding constrains it. This distinction is subtle and frequently exploited.
3. Forgotten service accounts. Every namespace gets a default service account. If pods don't specify one explicitly, they inherit it — along with whatever permissions it's been granted. Set automountServiceAccountToken: false unless the pod genuinely needs API access.
4. Escalation via bind and escalate verbs. A subject with permission to create RoleBindings can grant themselves any Role that already exists. Guard the bind, escalate, and impersonate verbs carefully.
Auditing Your Current RBAC Posture
Start with visibility. Use kubectl auth can-i to test specific permissions:
kubectl auth can-i delete secrets --as=system:serviceaccount:staging:cicd-pipeline -n production
# Expected output: noFor a broader audit, tools like rakkess, kubectl-who-can, and rbac-police can enumerate effective permissions across all subjects and flag dangerous combinations. Integrate these into your CI pipeline so RBAC drift gets caught before it ships.
Key Takeaways
RBAC isn't a set-and-forget configuration. Treat it as living infrastructure: version it in Git, review it in pull requests, audit it continuously, and default to deny. Every wildcard you eliminate and every ClusterRoleBinding you narrow closes a real attack path. In Kubernetes security, the API server is the crown jewel — and RBAC is the lock on the door.
Have questions about Kubernetes RBAC? I'm always happy to talk shop — reach out or connect with me on LinkedIn.