Website under construction feedback appreciated at [email protected]
← Terug naar blog
kubernetes

Kubernetes RBAC begrijpen in een uur

Yair Knijn · · 5 min lezen

Kubernetes RBAC klinkt ingewikkelder dan het is. Als je het model eenmaal snapt, kun je elk RBAC-probleem redeneren. Dat model leg ik hier uit. Daarna behandel ik de twee tools die je dagelijks nodig hebt.

Het model in vier lagen

RBAC werkt via een keten van vier objecten. Lees het van rechts naar links: wat mag je doen, en voor wie geldt dat.

Resources en verbs zijn het eindpunt van de keten. Een resource is een Kubernetes-object (pods, deployments, secrets). Een verb is een actie (get, list, watch, create, update, patch, delete). RBAC gaat over de combinatie: wie mag get doen op pods?

Roles en ClusterRoles bevatten de regels: welke combinaties van resources en verbs zijn toegestaan. Een Role werkt binnen een namespace. Een ClusterRole werkt clusterbreed.

Subjects zijn de identiteiten die access krijgen: een User, een Group of een ServiceAccount. In de praktijk gebruik je bijna altijd ServiceAccounts voor workloads.

RoleBindings en ClusterRoleBindings koppelen een Role of ClusterRole aan een subject. Hier zit de valkuil die verderop aan bod komt.

Role versus ClusterRole

Een Role werkt alleen in de namespace waar hij is aangemaakt. Als je een Role pod-reader aanmaakt in namespace staging, dan geldt die alleen voor pods in staging.

Een ClusterRole geldt voor alle namespaces, of voor clusterscoped resources (zoals nodes, persistentvolumes, namespaces zelf). Je hebt een ClusterRole nodig als je iemand toegang wil geven tot nodes, of als je een generieke rol wil definiëren die je in meerdere namespaces hergebruikt.

Een voorbeeld van een ClusterRole die alleen pods mag lezen:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: pod-reader
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list", "watch"]

De cross-namespace valkuil bij RoleBinding

Dit is het onderdeel waar vrijwel iedereen een keer op struikelt.

Een ClusterRole definiëren is niet hetzelfde als clusterwide toegang geven. Wat je bindt, bepaalt de scope.

  • RoleBinding + ClusterRole: de ClusterRole wordt gebonden in de namespace van de RoleBinding. Niet clusterbreed. Dit is handig als je een generieke ClusterRole (bijv. view) wil hergebruiken in specifieke namespaces.
  • ClusterRoleBinding + ClusterRole: de ClusterRole geldt clusterbreed voor het gebonden subject.

Concreet: als je een ClusterRoleBinding maakt voor een serviceaccount met de rol pod-reader, kan dat serviceaccount pods lezen in elke namespace, inclusief kube-system. Dat is zelden wat je wil.

Gebruik bij twijfel een RoleBinding, geen ClusterRoleBinding. Verlies de minste scope die volstaat voor het doel.

ServiceAccounts zijn de subjects die je eigenlijk gebruikt

Users en Groups in Kubernetes RBAC zijn externe identiteiten. Kubernetes beheert ze niet zelf. Ze komen uit je authenticatiesysteem (certificates, OIDC, LDAP via een webhook). In een managed cluster (EKS, GKE, AKS) is dat doorgaans de cloud-IAM.

ServiceAccounts zijn Kubernetes-native. Je maakt ze zelf aan, ze staan als object in de cluster, en je koppelt ze aan Pods:

apiVersion: v1
kind: ServiceAccount
metadata:
  name: app-reader
  namespace: production
spec:
  serviceAccountName: app-reader

Als je een Pod geen serviceAccountName opgeeft, krijgt hij de default ServiceAccount van de namespace. Die heeft in de meeste clusters geen permissions, maar het is slordig om hierop te vertrouwen. Wees expliciet.

Elke applicatie die de Kubernetes API aanroept (bijv. om zijn eigen ConfigMap te lezen, of om andere Pods te discoveren) heeft een ServiceAccount met de juiste RBAC nodig.

Namespace-strategie

RBAC is alleen nuttig als je namespaces het ook ondersteunen. Een cluster met alles in default maakt RBAC-isolatie moeilijk.

Een werkbare basislayout:

  • kube-system: clustercomponenten, harde RBAC-grens.
  • monitoring: Prometheus, Grafana, alert-tooling.
  • <team>-production, <team>-staging: per team, per omgeving.

Als een team een aparte namespace heeft, kan je een RoleBinding maken die die teamleden alleen toegang geeft tot hun eigen namespace. Dat werkt beter dan clusterwide rechten uitdelen en hopen dat mensen netjes blijven.

Tools: kubectl auth can-i en rakkess

kubectl auth can-i is de snelste manier om te controleren of een subject een actie mag uitvoeren:

# Mag ik pods verwijderen in production?
kubectl auth can-i delete pods -n production

# Mag serviceaccount app-reader secrets lezen?
kubectl auth can-i get secrets -n production \
  --as=system:serviceaccount:production:app-reader

Gebruik dit tijdens debugging als een Pod klaagt over access denied. Het antwoord is yes of no, geen ambiguïteit.

rakkess (ook bekend als kubectl-access-matrix) geeft een matrix van alle resources en welke verbs een subject erop mag uitvoeren. Handig voor een audit of als je een nieuwe rol wil valideren:

rakkess --sa production:app-reader

Dat geeft een tabel van alle resources met vinkjes en kruisjes per verb. In een oogopslag zie je of een role te breed of te smal is.

Wil je RBAC in de bredere context van Kubernetes security leren? Bekijk het overzicht van Kubernetes-trainingen op ict-trainingen.com.

Samengevat

Het model: subject + binding + role + resources/verbs. ClusterRole is een definitie, pas de binding bepaalt de scope. ServiceAccounts zijn de subjects voor workloads. RoleBinding boven ClusterRoleBinding tenzij je echt clusterwide access nodig hebt.

Als je dit model scherp hebt, los je elk RBAC-probleem op met kubectl auth can-i en een blik op de betrokken binding.

kubernetes rbac security