Cloud Security Wire
AWS Azure GCP RSS
Multi-Cloud Hardening Guide

Kubernetes RBAC Pitfalls: Wildcards, cluster-admin Bindings, and Service Account Token Abuse

A hardening guide to the most dangerous Kubernetes RBAC misconfigurations — wildcard rules, overbroad cluster-admin bindings, automounted service account tokens — with detection queries and least-privilege policy templates.

By Cloud Security Wire · ·
#kubernetes#rbac#cluster-admin#service-account#k8s-security

Kubernetes RBAC is the authorization layer that determines what subjects (users, groups, service accounts) can do within a cluster. It’s expressive and powerful, but its flexibility means misconfiguration is common — and the consequences of a misconfigured RBAC policy in a multi-tenant cluster or a cloud-hosted Kubernetes service (EKS, AKS, GKE) can be cluster-wide compromise or cloud credential theft.

The RBAC Model: A Quick Orientation

Kubernetes RBAC has four core object types:

  • Role — namespaced permission set (rules over resources within one namespace)
  • ClusterRole — cluster-wide permission set
  • RoleBinding — binds a Role or ClusterRole to subjects within a namespace
  • ClusterRoleBinding — binds a ClusterRole to subjects cluster-wide

Rules specify apiGroups, resources, and verbs. The danger lies in how broadly each is defined.

Pitfall 1: Wildcard Rules

The most dangerous single RBAC misconfiguration:

rules:
- apiGroups: ["*"]
  resources: ["*"]
  verbs: ["*"]

This is equivalent to cluster-admin. It appears in:

  • Default service accounts in some older Helm charts
  • Developer RBAC copied from examples without pruning
  • Emergency access roles never removed after an incident

A less obvious wildcard that’s still dangerous:

rules:
- apiGroups: [""]
  resources: ["secrets"]
  verbs: ["*"]

verbs: ["*"] on secrets allows listing, reading, creating, and deleting all secrets in scope — this is effectively credential access to every secret in the cluster.

Least-privilege alternative:

rules:
- apiGroups: [""]
  resources: ["secrets"]
  verbs: ["get"]
  resourceNames: ["specific-secret-name"]

Use resourceNames to restrict access to specific named resources, and prefer get over list where the application only needs to fetch a specific secret.

Pitfall 2: Overuse of cluster-admin

cluster-admin is the superuser ClusterRole in Kubernetes. It grants all verbs on all resources. Legitimate use cases are narrow: the control plane itself, break-glass emergency access. Common problematic uses:

# Giving a developer broad access
kubectl create clusterrolebinding dev-admin \
  --clusterrole=cluster-admin \
  --user=developer@company.com

# CI/CD pipeline service account with cluster-admin
kubectl create clusterrolebinding ci-admin \
  --clusterrole=cluster-admin \
  --serviceaccount=ci-namespace:ci-runner

A compromised CI pipeline with cluster-admin binding can:

  • Read all secrets (including cloud credentials and TLS certs)
  • Modify admission webhooks to intercept all pod creation
  • Create privileged pods to escape to the host node
  • Modify RBAC policies to persist access

Audit existing cluster-admin bindings:

kubectl get clusterrolebindings \
  -o json | jq -r '.items[] | select(.roleRef.name=="cluster-admin") | 
  "\(.metadata.name): \(.subjects[]? | "\(.kind)/\(.name)")"'

This one-liner shows every ClusterRoleBinding to cluster-admin and its subjects. Review this list and remove any bindings that aren’t strictly necessary.

Pitfall 3: Automounted Service Account Tokens

By default, Kubernetes mounts a service account token into every pod at /var/run/secrets/kubernetes.io/serviceaccount/token. Any process in the pod can use this token to authenticate to the Kubernetes API server.

# From inside a pod:
TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)
curl -s -k -H "Authorization: Bearer $TOKEN" \
  https://kubernetes.default.svc/api/v1/namespaces/default/secrets

If the pod’s service account has broad RBAC permissions, this token is equivalent to those permissions. Attackers who achieve container escape or exec access into a pod will immediately check for this token.

Disable automount globally on a service account:

apiVersion: v1
kind: ServiceAccount
metadata:
  name: myapp-sa
  namespace: production
automountServiceAccountToken: false

Disable automount per-pod (overrides service account setting):

spec:
  automountServiceAccountToken: false

For applications that don’t need to call the Kubernetes API (most web services, batch jobs, databases), there is no reason to mount the token. Setting automountServiceAccountToken: false on service accounts is a zero-cost hardening step with no application impact.

Pitfall 4: Permissive Pod Security — Privilege Escalation via exec

A ClusterRole that allows pods/exec is more dangerous than it appears:

rules:
- apiGroups: [""]
  resources: ["pods/exec"]
  verbs: ["create"]

kubectl exec into a privileged pod or a pod running as root is often a path to node compromise. Combined with hostPath mounts or hostPID: true, an exec into any pod on a node can become full host takeover.

Treat pods/exec permissions with the same scrutiny as cluster-admin. If your CI pipeline needs it for debugging, scope it to a specific namespace and add audit logging.

Pitfall 5: Namespace Isolation Failures

A common misconception: creating separate namespaces provides isolation. RBAC provides isolation; namespaces are just a scope boundary. A ClusterRoleBinding to a wide role nullifies namespace boundaries:

# This grants access to ALL namespaces, not just 'dev'
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: developer-binding
subjects:
- kind: User
  name: developer@company.com
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole  # <-- ClusterRole, not Role
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io

If you want namespace-scoped access, use a RoleBinding (not ClusterRoleBinding), even if the Role or ClusterRole referenced is cluster-scoped.

Detection and Auditing

kube-audit log analysis — enable audit logging and ship to a SIEM. Key events to alert on:

  • clusterrolebindings POST/PUT with cluster-admin roleRef
  • pods/exec or pods/portforward create events for production namespaces
  • secrets LIST events from unexpected service accounts

rbac-tool audit:

kubectl krew install rbac-tool
kubectl rbac-tool who-can get secrets -n production
kubectl rbac-tool who-can create clusterrolebindings

who-can shows every subject that has a given permission — invaluable for finding overpermissioned identities.

KubiScan:

python3 KubiScan.py -rba  # Enumerate risky role bindings
python3 KubiScan.py -rs   # Enumerate risky subjects

Hardening Checklist

  1. Audit all cluster-admin bindings — remove all except break-glass and control-plane subjects.
  2. Disable automountServiceAccountToken on all service accounts that don’t call the K8s API.
  3. Replace wildcard rules with explicit verb+resource combinations.
  4. Use RoleBinding over ClusterRoleBinding wherever possible.
  5. Restrict pods/exec to dedicated debug namespaces; remove from CI service accounts.
  6. Enable Kubernetes Audit Logging and ship to centralized logging.
  7. Run kubectl rbac-tool who-can get secrets monthly and review output.
  8. Use OPA/Gatekeeper or Kyverno to enforce RBAC policies as code, preventing drift.

Sample Kyverno policy to block new cluster-admin bindings:

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: restrict-clusteradmin-binding
spec:
  validationFailureAction: Enforce
  rules:
  - name: block-cluster-admin-binding
    match:
      any:
      - resources:
          kinds: [ClusterRoleBinding, RoleBinding]
    validate:
      message: "Binding to cluster-admin is not allowed. Use scoped roles."
      deny:
        conditions:
          any:
          - key: "{{ request.object.roleRef.name }}"
            operator: Equals
            value: cluster-admin

Kubernetes RBAC misconfigurations are among the most commonly exploited issues in managed Kubernetes breach reports. The controls above are not complex — the challenge is maintaining discipline as clusters grow and teams add permissions incrementally without removal hygiene.

← All Analysis Subscribe via RSS