Kubernetes RBAC: Interview-Deep-Dive für Platform Engineers
Roles, Bindings, least privilege und Multi-Tenant-Patterns — was du in Architektur-Runden erklären musst.
von PlatPrep
“Erklär mir kurz RBAC in Kubernetes.” Wer diesen Satz in einem Interview hört, läuft Gefahr, in eine Antwort zu gleiten, die zwar richtig ist, aber nichts zeigt. Ja, es gibt Roles und RoleBindings, ja, ClusterRoles wirken cluster-weit. Das weiß auch jemand, der die Doku fünf Minuten angelesen hat.
Die interessanten Fragen kommen danach: Wie organisierst du RBAC, wenn zwanzig Teams auf einem Cluster arbeiten? Wie verhinderst du, dass Teams auf Ressourcen anderer zugreifen? Und welche RBAC-Rechte sind heimliche Privilege-Escalation-Pfade?
Die Patterns, die den Unterschied machen
Ein häufiges Antipattern: für jeden Use Case eine neue ClusterRole schreiben. Das klingt sauber, wird aber schnell unübersichtlich. Besser ist das Aggregation-Pattern — du baust Basisrollen mit Labels und kombinierst sie via aggregationRule zu zusammengesetzten Rollen:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: team-developer
aggregationRule:
clusterRoleSelectors:
- matchLabels:
rbac.platform.example.com/aggregate-to-developer: "true"
rules: [] # wird vom Controller automatisch befüllt
Jede ClusterRole mit dem passenden Label fließt automatisch in team-developer ein. Ändert sich ein Default — etwa “Entwickler dürfen jetzt auch Events lesen” —, fasst du eine kleine Basisrolle an statt zwanzig Team-Rollen. Genau so funktionieren übrigens auch die eingebauten Rollen admin, edit und view, die du mit eigenen Regeln erweitern kannst, statt sie zu kopieren.
Der Unterschied zwischen Role und ClusterRole ist nicht nur der Scope. Eine ClusterRole kann per RoleBinding namespace-scoped gebunden werden: Du definierst eine generische “pod-reader”-ClusterRole einmal und bindest sie in beliebig vielen Namespaces, ohne cluster-weiten Zugriff zu vergeben. Das ist das Standardmuster für Multi-Tenancy — die Rollendefinition ist zentral, die Wirkung pro Team begrenzt. Wie das mit NetworkPolicies und Quotas zur vollständigen Namespace-Isolation wird, ist dann die Anschlussfrage.
Eskalationspfade: wo RBAC heimlich kippt
Hier trennt sich im Interview die Spreu vom Weizen. Ein paar harmlos aussehende Rechte sind effektiv Admin-Rechte:
create auf Pods in einem Namespace heißt: Ich kann einen Pod starten, der einen beliebigen ServiceAccount dieses Namespaces mountet — und erbe dessen Rechte. Liegt dort ein hoch privilegierter ServiceAccount, ist die Namespace-Grenze Makulatur. get auf Secrets liefert mir alle Tokens und Credentials des Namespaces. Die Verben escalate, bind und impersonate sind explizit gefährlich: bind erlaubt, anderen (oder sich selbst) Rollen zuzuweisen, die man selbst nicht hat; impersonate erlaubt, als anderer User zu agieren. Und Wildcards (verbs: ["*"], resources: ["*"]) in einer Rolle, die “nur für Debugging” gedacht war, sieht man häufiger, als einem lieb ist.
ServiceAccounts verdienen in dem Zusammenhang mehr Aufmerksamkeit, als sie meist bekommen. Jeder Pod bekommt ohne weiteres Zutun einen Token gemountet. Seit Kubernetes 1.22 sind das immerhin zeitlich begrenzte, projizierte Tokens statt der alten ewig gültigen Secrets. Trotzdem gilt: automountServiceAccountToken: false als Default, Token nur dort mounten, wo der Pod tatsächlich mit der API redet. Die meisten Workloads brauchen das nämlich gar nicht.
RBAC als Code, Debugging als Handwerk
Was Interviewende wirklich interessiert: Wie werden RBAC-Änderungen reviewed und deployed? “Wir schreiben das direkt mit kubectl” ist eine Antwort — keine gute. RBAC-Objekte ins GitOps-Repo, PR-Review (idealerweise mit Pflicht-Review durch das Security- oder Platform-Team für alles, was ClusterRoles anfasst), Deploy über Argo CD oder Flux. Sicherheitskonfiguration wie Code zu behandeln heißt auch: Der Audit-Trail ist die Git-History.
Zum Review-Prozess gehört auch ein periodischer Audit: Welche Bindings existieren, und werden sie noch gebraucht? RBAC-Regeln werden praktisch nur hinzugefügt, nie entfernt — nach zwei Jahren liegen Bindings für Personen herum, die das Team längst verlassen haben, und für “temporäre” Debug-Rollen, die nie temporär waren. Ein vierteljährlicher Blick auf alle ClusterRoleBindings ist unspektakulär, findet aber zuverlässig die unangenehmsten Funde.
Für Debugging gibt es zwei Werkzeuge, die jede Antwort aufwerten:
# Was darf dieser ServiceAccount alles?
kubectl auth can-i --list --as system:serviceaccount:team-a:backend-deployer
# Darf er diese eine Sache?
kubectl auth can-i create deployments -n team-a --as system:serviceaccount:team-a:backend-deployer
Das macht Troubleshooting deterministisch statt ratend — und --as zeigt nebenbei, dass du Impersonation kennst.
Noch zwei Klassiker für die Abgrenzung: Authentication prüft, wer du bist (Zertifikat, OIDC-Token, ServiceAccount-Token) — in Cloud-Umgebungen kommt die Gruppenzuordnung typischerweise aus dem Identity Provider, bei EKS etwa via IRSA und Access Entries. Authorization prüft, was du darfst — da setzt RBAC an. Und: RBAC ist rein additiv. Es gibt kein “Deny”; was nicht explizit erlaubt ist, ist verboten. Wer ein Verbot über RBAC “aussprechen” will, sucht eigentlich eine Admission Policy à la Kyverno.
Wer im Interview zeigen will, dass er RBAC wirklich versteht, spricht über Aggregation, Eskalationspfade, ServiceAccount-Hygiene und den can-i-Workflow. Das ist eine andere Qualität als das Aufzählen von Objekttypen — und genau die Qualität, die in Architektur-Runden erwartet wird. Die Grundlagen dazu, systematisch aufgebaut: Kubernetes-Lernpfad.