BlogKubernetes
Kubernetes RBAC least privilege: from admin to scoped roles
Replace blanket cluster-admin with namespaced Roles, audit who can do what, and test access with kubectl auth can-i.
Most clusters accumulate cluster-admin bindings the way garages accumulate boxes. RBAC least privilege means every human and service account gets exactly the verbs and resources it needs, in exactly the namespaces it operates in — and you can prove it with kubectl auth can-i.
kubectl auth can-i --list --as=system:serviceaccount:shop:webResources Verbspods [get list watch]configmaps [get]if this prints * [*] you have work to doNamespaced Role, not ClusterRole
Prefer a Role (one namespace) over a ClusterRole (whole cluster). Grant specific verbs on specific resources — no wildcards.
role.yaml
apiVersion: rbac.authorization.k8s.io/v1kind: Rolemetadata: { namespace: shop, name: web-reader }rules:- apiGroups: [""]resources: [pods, configmaps]verbs: [get, list, watch]---apiVersion: rbac.authorization.k8s.io/v1kind: RoleBindingmetadata: { namespace: shop, name: web-reader }subjects:- kind: ServiceAccountname: webroleRef:kind: Rolename: web-readerapiGroup: rbac.authorization.k8s.io
Find who has cluster-admin
kubectl get clusterrolebindings -o wide | grep cluster-adminNAME ROLE SUBJECTScluster-admin ClusterRole/cluster-admin Group system:mastersjenkins-deployer ClusterRole/cluster-admin SA ci:jenkinsdefault-dashboard ClusterRole/cluster-admin SA kube-system:dashboardevery name here is a full-cluster takeover if compromisedWildcards are the enemy
verbs ["*"] on resources ["*"] is cluster-admin by another name. Enumerate the verbs you actually use: get/list/watch for readers, add create/update/patch/delete only where needed.
Test before and after
bash
kubectl auth can-i delete pods \--as=system:serviceaccount:shop:web -n shop# no <- exactly what you want