Tools · Containers and Kubernetes security · 02 / 20
Kubernetes RBAC explained: Roles, ClusterRoles, bindings, and kubectl auth can-i
Read RBAC objects, understand namespace versus cluster scope, find who has dangerous verbs like create pods or get secrets, and test permissions with kubectl auth can-i.
Four objects
A Role grants verbs on resources inside one namespace. A ClusterRole grants verbs cluster-wide or can be reused in namespaces. A RoleBinding attaches a Role or ClusterRole to subjects (users, groups, service accounts) within one namespace. A ClusterRoleBinding attaches a ClusterRole across the whole cluster.
RBAC is allow-only. There are no deny rules, so the effective permission set is the union of every binding that applies to the subject and its groups.
Permissions that equal more power
Some verbs are effectively escalation paths. get or list on secrets reveals service account tokens and credentials. create on pods lets a user run a pod that mounts any service account or host path that admission allows. The escalate, bind, and impersonate verbs let a subject grant or assume more permissions. Wildcards in verbs or resources are always worth a second look.
- secrets: get, list, watch
- pods: create, or pods/exec: create
- roles and clusterroles: escalate, bind
- users, groups, serviceaccounts: impersonate
- nodes/proxy: get
Lab: ask the API
In a kind cluster, create a namespace and a service account, bind it to the built-in edit ClusterRole in that namespace only, and test what it can do. Then list every subject bound to cluster-admin.
kubectl create ns team-a
kubectl -n team-a create sa ci-bot
kubectl -n team-a create rolebinding ci-bot-edit --clusterrole=edit --serviceaccount=team-a:ci-bot
kubectl auth can-i create pods -n team-a --as=system:serviceaccount:team-a:ci-bot
kubectl auth can-i get secrets -n kube-system --as=system:serviceaccount:team-a:ci-bot
kubectl auth can-i --list -n team-a --as=system:serviceaccount:team-a:ci-bot
kubectl get clusterrolebindings -o json | jq -r '.items[] | select(.roleRef.name=="cluster-admin") | .metadata.name + ": " + ([.subjects[]? | .kind + "/" + .name] | join(", "))'Review habits
Bind to groups from your identity provider rather than individual users, prefer RoleBindings over ClusterRoleBindings, and keep cluster-admin for break-glass. Tools such as rbac-tool or kubectl-who-can answer the reverse question, “who can get secrets in this namespace?”, which is often more useful in a review.
Diagram
RoleBinding versus ClusterRoleBinding of the same ClusterRole
The binding decides the reach.
Scope. Every namespace
Can read secrets. Yes, everywhere edit allows
Risk. One compromised CI token touches the whole cluster
Scope. team-a only
Can read secrets. Only in team-a
Risk. Contained to one namespace
Check yourself
1. A user has two RoleBindings in the same namespace. What are their effective permissions?
2. The edit ClusterRole is bound with a RoleBinding in namespace team-a. Where does it apply?
3. Why is create on pods treated as a sensitive permission?