Back to Cheat Sheets

🔑 Overly Permissive RBAC Configurations

OWASP Kubernetes Top 10 - K03

CRITICAL RISK

📋 What Is It?

Overly Permissive RBAC is the failure mode where Roles and ClusterRoles grant an identity far more than it needs. RBAC is additive and allow-only - there are no deny rules, so every permission granted stays granted until a binding is removed. A single over-broad rule - a wildcard verb, cluster-admin bound to a ServiceAccount, or broad Secret access - turns one compromised container into full control of the cluster. Because the flaw lives in YAML, it is invisible to code review and survives every redeploy.

K03 OWASP Rank
Authorization Focus Area
Medium To Prevent

⚠️ Common Exploits

  • Token Read + Enumerate: Read the mounted SA token, then kubectl auth can-i --list to map the escalation surface
  • Cluster-Wide Secret Read: get/list on Secrets harvests every credential, including other SAs' tokens
  • Pod Creation: create on Pods schedules a Pod running as a more privileged SA to steal its token
  • escalate / bind: Self-grant wildcard rules or bind yourself to cluster-admin in one command
  • impersonate: Act as any user, group, or SA - including the RBAC-bypassing system:masters
  • pods/exec: Run commands inside existing privileged containers to inherit their identity
  • TokenRequest: create on serviceaccounts/token mints fresh tokens for stronger identities

🔴 Attack Flow

1. Obtain identity: read mounted SA token from a Pod
↓
2. Enumerate: kubectl auth can-i --list
↓
3. Find primitive: secrets, create pods, escalate/bind
↓
4. Escalate: mint/steal a higher-privileged token
↓
5. IMPACT: Bind to cluster-admin - full takeover!

❌ Vulnerable Code

# Bad: "give it everything so it works" ClusterRole, bound cluster-wide apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: app-superpowers rules: - apiGroups: ["*"] # every API group, including future CRDs resources: ["*"] # pods, secrets, nodes, rolebindings, ... verbs: ["*"] # get, create, delete, escalate, bind, impersonate --- kind: ClusterRoleBinding metadata: name: app-superpowers-binding subjects: - kind: ServiceAccount name: payments-api namespace: payments roleRef: kind: ClusterRole name: app-superpowers # Effect: this ServiceAccount is cluster-admin. One RCE = full takeover. # Bad: cluster-admin bound to a CI ServiceAccount token living in a Pod roleRef: { kind: ClusterRole, name: cluster-admin } # Bad: binding to "default" leaks the grant to EVERY pod in the namespace subjects: [ { kind: ServiceAccount, name: default, namespace: apps } ]

✅ Secure Code

# Good: only the verbs and resources this app actually uses, in its namespace apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: payments-api-role namespace: payments rules: - apiGroups: [""] # core group only resources: ["configmaps"] resourceNames: ["payments-config"] # a single named object verbs: ["get", "list", "watch"] # read-only, no create/delete --- kind: RoleBinding # namespaced, not ClusterRoleBinding metadata: name: payments-api-binding namespace: payments subjects: - kind: ServiceAccount name: payments-api # dedicated SA, not "default" namespace: payments roleRef: kind: Role name: payments-api-role # Good: read ONE named secret with get (not list, which ignores names) resources: ["secrets"] resourceNames: ["payments-db-credentials"] verbs: ["get"] # Good: disable token automount where the API is not called automountServiceAccountToken: false

✓ Prevention Checklist

  • No * in verbs, resources, or apiGroups for any custom role
  • Never bind cluster-admin to a ServiceAccount or a wide group
  • Give every workload a dedicated SA; leave default unused and unbound
  • Set automountServiceAccountToken: false wherever the API isn't called
  • Grant escalate/bind/impersonate only to reviewed infra identities
  • Scope Secret access by namespace and, where feasible, resourceNames
  • Prefer namespaced Roles unless the resource is genuinely cluster-scoped
  • Enforce admission policy that rejects wildcard rules and dangerous bindings
  • Run kubectl auth can-i allow/deny assertions in CI
  • Audit RBAC on a schedule (rbac-tool, kubectl-who-can, KubiScan) with alerting
  • Enable API server audit logging; alert on new admin bindings and impersonation

🔍 Detection & Tools

RBAC Auditors:

kubectl auth can-i kubectl-who-can rbac-tool KubiScan kubescape kube-bench

Admission Enforcement:

Kyverno OPA/Gatekeeper ValidatingAdmissionPolicy

How to Test:

  • Enumerate as a SA: kubectl auth can-i --list --as=system:serviceaccount:ns:sa
  • Probe: kubectl auth can-i '*' '*' --all-namespaces --as=$SA
  • Find admin bindings: kubectl get clusterrolebindings -o json | jq ...cluster-admin
  • Find wildcard rules across roles with a jq filter on *
  • Ask who can act: kubectl who-can list secrets / create clusterrolebindings

🌍 Real-World

  • Compromised Pod to cluster-admin via a bound role: An app SA with cluster-wide secrets [get,list] plus a CI token stored as a Secret lets one RCE harvest the CI token and authenticate as cluster-admin.
  • escalate/bind self-promotion: An operator SA given bind on clusterrolebindings and escalate on clusterroles can create a binding tying its own identity to cluster-admin - the escalation-prevention check no longer applies.
  • Over-permissioned default ServiceAccount: Binding a broad edit role to default in a shared namespace silently gives every Pod - including internet-facing ones - the ability to create Pods and read Secrets.
  • Note: These are described as incident classes. Over-broad RBAC is common, cheap to find with kubectl auth can-i, and devastating when chained from a single foothold; the takeaway is the mechanism, not a statistic.

📌 Quick Tips

  • DO NOT use * in verbs, resources, or apiGroups
  • DO NOT bind cluster-admin to a ServiceAccount
  • DO NOT bind roles to default or system:authenticated
  • DO grant the minimum verbs on named resources
  • DO use a dedicated SA per workload
  • DO guard escalate / bind / impersonate
  • DO audit RBAC continuously and alert on changes

📜 Compliance

Related Standards:

  • CIS Kubernetes Benchmark - RBAC & Service Accounts
  • NSA/CISA Kubernetes Hardening - Authorization
  • NIST 800-53 AC-6 - Least Privilege
  • SOC 2 CC6.1 - Logical Access
  • PCI-DSS Requirement 7 - Restrict Access