Das passende Training Kubernetes Security Training – Cluster hacken, verstehen, absichern (3 Tage)
Das RBAC-Problem ist nicht die Vergabe – es ist, dass nie wieder etwas entzogen wird

Das passende Training Kubernetes Security Training – Cluster hacken, verstehen, absichern (3 Tage)

Das RBAC-Problem ist nicht die Vergabe – es ist, dass nie wieder etwas entzogen wird

Ganz ehrlich: RBAC-Wildwuchs entsteht so gut wie nie dadurch, dass jemand beim ersten Mal zu großzügig war. Er entsteht, weil danach nie wieder jemand nachschaut, ob eine Role, eine ClusterRole oder die Bindung an einen ServiceAccount überhaupt noch gebraucht wird. Und für genau diese Frage hat Kubernetes kein Werkzeug: Es gibt Tools, die dir zeigen, was erlaubt ist. Es gibt keins, das dir zuverlässig zeigt, was tatsächlich benutzt wird.

Ich weiß, RBAC ist nicht das Thema, bei dem im Team die Stimmung steigt. Vermutlich ist es genau deshalb in so vielen Clustern das, was seit Jahren keiner angefasst hat.

Was RBAC überhaupt regelt

RBAC (Role-Based Access Control) ist der Standard-Mechanismus, mit dem Kubernetes steuert, wer über die API was tun darf. Das betrifft nicht nur Menschen, die kubectl tippen - jeder Controller, jede CI/CD-Pipeline und jeder Pod mit eigenem ServiceAccount läuft bei jeder Anfrage an den kube-apiserver durch genau diese Prüfung.

Gesetzt wird das über vier Objekttypen: Role (Rechte innerhalb eines einzelnen Namespace), ClusterRole (clusterweit gültig oder als wiederverwendbare Vorlage über mehrere Namespaces hinweg), RoleBinding (verknüpft eine Role oder ClusterRole mit einem User, einer Group oder einem ServiceAccount innerhalb eines Namespace) und ClusterRoleBinding (dieselbe Verknüpfung clusterweit). Eine Role oder ClusterRole allein tut noch nichts - erst die Bindung an einen konkreten Nutzer, eine Gruppe oder einen ServiceAccount aktiviert sie.

Vergeben ist einfach. Entziehen ist die eigentliche Arbeit.

Rechte vergeben hat einen Auslöser. Jemand kommt und sagt: „Die Pipeline darf keine Deployments anlegen." Ticket, YAML, Merge, fertig. Es gibt einen Anlass, es gibt jemanden, der wartet, und es gibt ein klares Erfolgskriterium - es läuft wieder.

Rechte entziehen hat keinen Auslöser. Niemand meldet sich freiwillig und sagt: „Übrigens, den ServiceAccount von dem Batch-Job aus vorletztem Jahr braucht keiner mehr."

Dazu kommt: Der Kollege, der das Recht damals beantragt hat, ist längst im anderen Team. Das Ticket-System wurde zweimal gewechselt. Und ob dieses eine RoleBinding noch irgendwas tut, kann dir niemand sagen - weil es schlicht niemand weiß.

Und dann ist da die Schieflage beim Risiko. Zu viel vergeben: Es passiert nichts. Jedenfalls nichts, was du siehst. Zu viel entzogen: Der nächtliche Job fällt um, das Deployment steht, und du bist der, der es angefasst hat.

Das ist keine Bequemlichkeit, das ist eine völlig rationale Reaktion. Wenn du nicht nachweisen kannst, dass etwas ungenutzt ist, ist Nichtstun die sichere Wahl. Genau deshalb lässt sich RBAC-Hygiene so schwer sauber strukturieren - es fehlt nicht die Disziplin, es fehlt die Grundlage für eine belastbare Entscheidung.

Es gibt kein „zuletzt genutzt" in Kubernetes-RBAC

Kubernetes speichert an keiner Role, ClusterRole oder keinem RoleBinding, wann sie zuletzt tatsächlich verwendet wurden. Kein lastUsed-Feld, keine Zugriffszählung am ServiceAccount, keine API, die diese Frage beantwortet. Nichts.

Und die üblichen RBAC-Tools schließen die Lücke nicht, auch wenn sie in fast jedem Guide so empfohlen werden:

ToolBeantwortetBeantwortet nicht
kubectl auth can-i (Bordmittel)Darf ich - oder ein anderes Subjekt - das?Ob es je gemacht wurde
rbac-lookup (Fairwinds)Welche Rollen hängen an diesem User, dieser Gruppe, diesem ServiceAccount?Ob diese Rollen je gezogen haben
kubectl-who-can (Aqua Security)Wer darf Verb X auf Ressource Y?Ob es jemand tut
KubiScan (CyberArk)Wo sitzen riskante Muster - Wildcards, cluster-admin-Bindings?Nutzung; ein Risiko-Scanner ist keine Nutzungsanalyse

Alle beantworten dieselbe Frage aus verschiedenen Richtungen: granted. Keins beantwortet: used.

Versteh mich nicht falsch, die Tools sind gut in dem, was sie tun. rbac-lookup erspart dir das Zusammenklauben über alle Namespaces, KubiScan findet Wildcards, die du sonst überliest. Nur lösen sie eben das Vergabe-Problem. Nicht das Aufräum-Problem.

Das Audit-Log des kube-apiserver: der einzige echte Weg. Und der ist unbequem.

Echte Nutzungsdaten gibt es an genau einer Stelle - nicht in Kubelet-Logs, nicht in Anwendungs-Logs, nicht im normalen API-Server-Log, sondern im separat konfigurierten Audit-Log des kube-apiserver, gesteuert über --audit-log-path oder --audit-webhook-config-file plus eine Audit-Policy. Und das ist sogar präziser, als die meisten denken: Der RBAC-Authorizer schreibt in die Audit-Annotation authorization.k8s.io/reason die konkrete Bindung rein - der Quellcode zeigt das exakte Format: RBAC: allowed by RoleBinding "deployer-binding/demo" of Role "pod-reader" to ServiceAccount "deployer/demo". Da steht also tatsächlich drin, welches Binding den Zugriff durchgewinkt hat. Ab Audit-Level Metadata, du brauchst dafür nicht mal die vollen Request-Bodies.

Klingt nach Lösung. Ist in der Praxis meistens keine.

Erstens ist dieses Audit-Log nicht an. Der kube-apiserver schreibt es nur, wenn du ihm eine Audit-Policy und ein Ziel vorgibst - fehlt das, wird gar nichts geschrieben. Bei EKS musst du den Log-Typ audit (neben api, authenticator, controllerManager, scheduler) explizit aktivieren, dann landet er in CloudWatch Logs. Bei AKS legst du dafür ein Diagnostic Setting an, das in einen Log Analytics Workspace schreibt - und dort gibt es zwei Kategorien: kube-audit-admin lässt get und list bewusst weg, kube-audit enthält sie, ist dafür aber deutlich teurer. Bei GKE laufen Admin-Activity-Audit-Logs immer mit, aber genau die lesenden Zugriffe (get, list, watch) stecken in den Data-Access-Logs, die du separat aktivieren musst.

Und da wird es fast schon komisch: Wer bei AKS aus Kostengründen zu kube-audit-admin greift, spart Geld, indem er genau die Verben wegwirft, die den größten Teil davon ausmachen, was ein ServiceAccount im Alltag überhaupt tut - und die er später bräuchte, um „ungenutzt" von „genutzt" zu unterscheiden.

Zweitens, und das wiegt schwerer: Selbst wenn das Audit-Log läuft, korreliert das niemand automatisch zurück zu deinen RBAC-Bindings. Kubernetes bringt dafür nichts mit. Kein kubectl rbac unused, keine Aggregation, kein Report. Du müsstest die Events wochenlang sammeln, den reason-String parsen, gegen deinen Bestand an Bindings halten - und selbst dann weißt du nur, welches Binding benutzt wurde, nicht welche einzelne Regel darin. Und ob „seit 60 Tagen nicht gesehen" bei einem Quartalsjob wirklich „ungenutzt" heißt, entscheidest immer noch du.

Ja, es gab Anläufe. audit2rbac baut aus Audit-Events eine minimale Rolle - das letzte Release war im Februar 2023, seitdem Stillstand. kubectl-rbac von VMware konnte genau den Abgleich granted gegen used, ist aber schon 2019 archiviert worden. Mit Audicia ist 2026 ein neuer Operator dazugekommen, der genau das versucht - generiert Least-Privilege-RBAC direkt aus Audit-Logs. Nur: Keins dieser Projekte hat annähernd die Reife oder Verbreitung, dass ich dir sagen würde, bau deine Rechte-Hygiene fest darauf auf. Das Rohmaterial liegt da. Ein etabliertes Werkzeug dafür gibt es nicht.

Was in der Praxis hilft: Konventionen statt Tool-Hoffnung

Und jetzt der Teil, den ich ungern schreibe, weil er so unspektakulär ist: Was hilft, ist organisatorisch. Nicht technisch.

Konkret: Jeder ServiceAccount und jedes RoleBinding bekommt beim Anlegen drei Labels mit auf den Weg. Wer ist der Owner, wofür ist das da, und wann schaut jemand wieder drauf.

metadata:
  labels:
    owner: team-payment
    purpose: ci-deploy-payment-api
    review-by: "2027-02-01"

Der Trick daran ist nicht das Label. Der Trick ist das Datum. Es ersetzt genau das, was oben fehlt: den Auslöser. Aus „irgendwann müsste man da mal ran" wird ein Termin, an dem eine Person mit Namen gefragt wird, ob das noch gebraucht wird.

Und ja - das ist ein Workaround, kein Ersatz für die fehlenden Nutzungsdaten. Ein Datum in einem Label beweist überhaupt nichts. Es erinnert nur. Es beantwortet die Frage „wird das genutzt" nicht, es sorgt bloß dafür, dass die Frage überhaupt jemals gestellt wird. Das ist wenig - aber es ist mehr als das, was die meisten heute haben.

Wer es macht, sollte es klein halten: drei Labels, ein Termin im Quartal, fertig. Baut da bloß keinen Governance-Apparat drumherum. Sonst macht es nach dem zweiten Durchlauf keiner mehr, und ihr habt am Ende beides nicht - weder Ordnung noch Ruhe.

Was du dir bei so einem Termin dann konkret anschaust, und wie du RBAC aufräumst, ohne dir dabei die halbe Pipeline abzuschießen, üben wir im Kubernetes-Security-Training am echten Cluster. Inklusive der Momente, in denen etwas umfällt. Genau dafür ist es ja da.

Fazit

Die meisten RBAC-Guides hören genau da auf, wo es unangenehm wird. Sie erklären dir Least Privilege, zeigen dir eine saubere Role, und tun so, als wäre die Sache damit erledigt.

Ist sie nicht. Der Teil, an dem es tatsächlich scheitert, kommt danach - und dafür gibt es kein Kommando. Kubernetes weiß sehr genau, was du darfst. Was du tatsächlich tust, weiß es nur, wenn du es ihm selbst beibringst - und dafür separat konfigurierst.

Bleibt eine unbefriedigende Wahrheit: RBAC-Hygiene ist Handarbeit mit Kalendereintrag. Nicht schön. Aber ehrlicher als ein Cluster, in dem seit drei Jahren nur dazugekommen ist.