Delegierte Benutzerverwaltung mit Keycloak: Fine-Grained Admin Permissions (FGAP v2) in der Praxis
September 8, 2026
Tags: #keycloak #fine-grained-admin-permissions #authorization #delegated-administration
Wer in Keycloak Administrationsrechte an andere abgeben möchte, landet schnell bei einem Problem: Die klassischen Admin-Rollen sind grob. Sehr grob.
Wer manage-users bekommt, verwaltet alle Benutzer eines Realms – nicht nur die, um die er sich eigentlich kümmern soll.
Mit den Fine-Grained Admin Permissions (FGAP) in Version 2 lässt sich genau das sauber eingrenzen.
In diesem Artikel zeige ich anhand eines konkreten Beispiels, wie das funktioniert und wo die Stolpersteine liegen.
Das Problem: Alles oder nichts
Stellen wir uns ein typisches Szenario vor: In einem Realm gibt es viele Benutzer aus unterschiedlichen Quellen – aus einem LDAP, aus einem angebundenen Entra ID, aus anderen externen Identity Providern oder lokal angelegt. Ein Teamleiter, eine Fachabteilung oder ein Mandant soll nun „seine“ Benutzer selbst verwalten können: Daten pflegen, Passwörter setzen, neue Kolleg:innen anlegen.
Mit den Standard-Rollen bleibt mir dafür nur ein Weg: Ich gebe dem Benutzer Rollen wie view-users und manage-users.
Das funktioniert – aber eben für alle Benutzer des Realms. Eine Einschränkung auf einen Teil der Benutzer, etwa nur auf die Mitglieder einer bestimmten Gruppe, ist damit nicht möglich.
Für das Beispiel in diesem Artikel verwende ich folgendes Szenario:
Im Realm demo gibt es die Gruppe doe-family mit den Mitgliedern jane.doe und john.doe.
John soll in der Admin-Konsole ausschließlich die Mitglieder dieser Gruppe sehen und verwalten können – und sonst niemanden.
Admin-Zugriff in Keycloak: Drei Stufen
Bevor wir einsteigen, lohnt ein kurzer Blick darauf, welche Möglichkeiten Keycloak grundsätzlich bietet, um administrativen Zugriff zu vergeben. In der Server-Administrationsdokumentation ist das im Kapitel Managing access to realm resources beschrieben.
Master-Realm-Zugriff: Der master-Realm ist ein besonderer Realm. Benutzer mit der Rolle admin sind hier Super-User und haben Zugriff auf den gesamten Server, also auf alle Realms.
Dedizierte Realm-Admin-Konsolen: Jeder Realm hat seine eigene Admin-Konsole unter /admin/{realm-name}/console.
Benutzer dieses Realms können dort Administrationsrechte erhalten, indem ihnen Client-Rollen des eingebauten Clients realm-management zugewiesen werden – etwa create-client, impersonation, manage-clients, manage-users, query-groups oder query-users.
Das ist vermutlich der Weg, den die meisten von euch kennen. Die Rechte gelten aber immer für einen kompletten Ressourcentyp: alle Clients, alle Benutzer, alle Gruppen.
Fine-Grained Admin Permissions: Die dritte und feinste Stufe. Hier vergebe ich Rechte nicht mehr auf ganze Ressourcentypen, sondern bei Bedarf auf einzelne Ressourcen – zum Beispiel auf eine bestimmte Gruppe und deren Mitglieder.
Version 1 vs. Version 2
FGAP gibt es schon eine ganze Weile in Keycloak. Die erste Version war allerdings sehr komplex, schwer zu verstehen und in der Praxis kaum sinnvoll nutzbar. Sie ist inzwischen deprecated, standardmäßig nicht mehr aktiviert und wird sehr wahrscheinlich demnächst entfernt.
Seit Keycloak 26.2 gibt es die komplett überarbeitete Version 2, und das ist die Version, mit der wir weiterarbeiten wollen. Alles, was ich in diesem Artikel zeige, habe ich mit Keycloak 26.7 umgesetzt, der zum Zeitpunkt aktuellen Version.
Die Bausteine von FGAP v2
FGAP v2 basiert auf zwei Konzepten: Permissions und Policies.
Eine Permission beschreibt, worauf und mit welchen Operationen zugegriffen werden darf. Sie besteht aus:
- einem Resource Type – zur Auswahl stehen Clients, Groups, Organizations, Roles und Users,
- einem oder mehreren Authorization Scopes, also den erlaubten Operationen (z. B.
viewodermanage-members), - der Angabe, ob die Permission für alle Ressourcen dieses Typs gilt oder nur für bestimmte (Enforce access to),
- einer oder mehreren Policies.
Eine Policy beschreibt, wer die Permission nutzen darf. Als Policy-Typen stehen Aggregate, Client, Client-scope, Group, Regex, Role, Time und User zur Verfügung. So lässt sich eine Permission etwa an einen einzelnen Benutzer, an alle Mitglieder einer Gruppe oder an eine Rolle binden – oder auch zeitlich einschränken, z. B. nur zwischen 8 und 10 Uhr. Jede Policy hat außerdem eine Logic: Positive (die Policy greift für die ausgewählten Benutzer) oder Negative (sie greift für alle außer den ausgewählten).
Am Rande: Organizations sind als Resource Type ebenfalls dabei. Was es mit dem Organizations-Feature auf sich hat, habe ich in einem eigenen Video gezeigt.
Schritt 1: Feature im Realm aktivieren
FGAP v2 wird pro Realm aktiviert und ist standardmäßig ausgeschaltet. In den Realm settings findet sich der Schalter Admin Permissions. Diesen auf On stellen und speichern.
Danach erscheint im linken Menü ein neuer Eintrag: Permissions. Dahinter liegen die drei Tabs Permissions, Policies und Evaluation – anfangs natürlich alle leer.
Schritt 2: Die Basisrollen für den delegierten Admin
Ganz ohne klassische Rollen kommen wir auch mit FGAP nicht aus.
Damit John überhaupt in die Admin-Konsole des Realms kommt und dort die Bereiche Users und Groups nutzen kann, braucht er zwei Client-Rollen des realm-management-Clients:
query-users– damit er auf den Benutzerbereich zugreifen und Benutzer suchen kann,query-groups– damit er auf Gruppen und deren Mitglieder zugreifen kann.
Die query-*-Rollen sorgen dafür, dass John die Admin-Konsole überhaupt nutzen kann und dort die zu den Rollen passenden Menüeinträge sieht – hier also Users und Groups. Außerdem darf er damit suchen. Was John bei einer Suche tatsächlich zu sehen bekommt, ist aber eine andere Frage.
Das lässt sich schön ausprobieren: Melde ich mich mit John an der Admin-Konsole des Realms (/admin/demo/console) an und suche nach allen Benutzern, bekomme ich – nichts. John darf zwar suchen, hat aber keine Berechtigung, Benutzer anzusehen.
Weise ich John testweise zusätzlich die Rolle view-users zu und lade die Konsole neu, liefert die Suche nach * alle Benutzer des Realms.
Das ist das reguläre und erwartbare Verhalten der globalen Rolle – und genau das, was wir nicht wollen. Also entferne ich view-users wieder und es bleibt bei query-users und query-groups.
Die Rollen müssen übrigens nicht einzelnen Benutzern zugewiesen werden. Sollen mehrere Personen dieselben delegierten Rechte bekommen, weise ich die Rollen sinnvollerweise einer Gruppe zu. In diesem Beispiel bleibt es bei John.
Schritt 3: Die Permission anlegen – Groups statt Users
Jetzt kommt der eigentliche Kern. Im Bereich Permissions klicke ich auf Create permission und muss zuerst den Resource Type auswählen.
John soll Benutzer verwalten, also liegt der Resource Type Users nahe. Das ist aber nicht der richtige Weg! John soll ja nicht beliebige Benutzer verwalten, sondern die Benutzer einer bestimmten Gruppe. Deshalb brauchen wir den Resource Type Groups. Innerhalb dieses Typs gibt es eigene Authorization Scopes, die sich auf die Mitglieder einer Gruppe beziehen.
Die Permission konfiguriere ich wie folgt:
- Name:
doe-family - Authorization scopes:
view,view-members,manage-members - Enforce access to: Specific Groups
- Groups:
/doe-family
Mit view darf John die Gruppe selbst sehen, mit view-members deren Mitglieder und mit manage-members die Mitglieder auch verwalten.
Was ich bewusst nicht vergebe, ist der Scope manage. Der würde John erlauben, die Gruppe selbst zu verändern.
John soll die Gruppe aber nur sehen und sich um ihre Mitglieder kümmern – mehr nicht.
Schritt 4: Die Policy – wer darf das?
Jetzt fehlt noch die Antwort auf die Frage, wer diese Permission nutzen darf. Gäbe es schon passende Policies, könnte ich sie über Assign existing policies zuweisen. Da wir gerade erst mit dem Feature starten, lege ich über Create new policy direkt aus der Permission heraus eine neue an.
Da die Permission nur für einen einzelnen Benutzer gelten soll, wähle ich als Policy-Typ User – nicht Group:
- Name:
john doe - Policy type: User
- Users:
john.doe - Logic: Positive
Negative würde hier bedeuten: jeder Benutzer außer John. Das ist natürlich nicht das, was wir wollen.
Nach dem Speichern wird die Policy automatisch der Permission zugeordnet. Jetzt muss ich nur noch die Permission selbst speichern.
In der Übersicht sehe ich anschließend die Permission doe-family mit dem Resource Type Groups und den drei Scopes.
Über den Tab Evaluation könnte ich Permissions und Policies jetzt theoretisch durchtesten. Das ist hilfreich, wenn man das Ergebnis nicht direkt live ausprobieren kann.
Ich schaue mir das Ergebnis lieber direkt in der Admin-Konsole an.
Das Ergebnis aus Johns Sicht
Nach einem Reload der Admin-Konsole sieht John im Menü jetzt Users und Groups.
Unter Groups taucht ausschließlich doe-family auf, alle anderen Gruppen des Realms – etwa die aus dem LDAP – sind für ihn nicht sichtbar.
Unter Users werden zunächst keine Benutzer angezeigt, weil im Realm eine User Federation aktiv ist. In diesem Fall muss explizit gesucht werden.
Eine Suche nach *, die vorhin mit view-users noch alle Benutzer geliefert hat, liefert jetzt genau zwei Treffer: jane.doe und john.doe.
Innerhalb dieser Gruppe hat John dank manage-members weitreichende Rechte. Er kann:
- Benutzerdetails bearbeiten, z. B. eine Telefonnummer bei Jane ergänzen,
- Credentials setzen, also Jane ein (temporäres) Passwort vergeben,
- Role Mappings und Gruppenzugehörigkeiten pflegen,
- Benutzer löschen.
UI und API sind nicht immer deckungsgleich
Was John nicht kann, ist die Gruppe selbst verändern – wir haben ihm manage ja bewusst nicht gegeben.
Interessant ist dabei: In der Gruppe doe-family zeigt die Admin-Konsole auf dem Tab Child groups trotzdem einen aktiven Button zum Anlegen einer Untergruppe.
Versuche ich, damit eine Child-Gruppe anzulegen, bekomme ich eine Fehlermeldung.
Die Admin-Konsole bildet die tatsächlichen Berechtigungen also nicht immer exakt ab. Entscheidend ist, was die Admin-API erlaubt – und die verhindert die Aktion korrekt.
Stolperstein: Neue Benutzer anlegen
Bleibt noch die Frage: Kann John auch neue Benutzer zur Familie hinzufügen?
Im Benutzerbereich gibt es den Button Add user. Ich lege also jack.doe an, Janes Bruder, und klicke auf Create – und bekomme Could not create user: HTTP 403 Forbidden.
Der erste Gedanke: Klar, John darf ja nur Mitglieder der doe-family verwalten, also muss der neue Benutzer direkt dieser Gruppe zugeordnet werden.
Über Join Groups wähle ich /doe-family aus – und bekomme trotzdem wieder einen 403.
Der Grund: Es fehlt eine Berechtigung. Mit unserer Permission darf John die Gruppe sehen, ihre Mitglieder sehen und ihre Mitglieder verwalten. Was er nicht darf, ist die Mitgliedschaft in der Gruppe verwalten. Ein neuer Benutzer ist aber noch kein Mitglied – er muss erst zum Mitglied gemacht werden.
Dafür gibt es den Authorization Scope manage-membership. Diesen ergänze ich in der Permission doe-family und speichere.
Die Änderung wirkt übrigens sofort, ein Reload der Admin-Konsole ist nicht nötig. Das liegt daran, dass sich nur die Permission geändert hat und nicht die Rollen des Benutzers.
Jetzt kann John jack.doe anlegen und direkt der doe-family zuordnen.
Bei der Gruppenauswahl wird ihm auch nur diese eine Gruppe angeboten – andere Gruppen sieht er ja nicht.
Die Gruppe hat jetzt drei Mitglieder: John, Jane und Jack. Und weil John die Mitglieder vollständig verwalten darf, kann er Jack auch wieder löschen.
Überblick: Die Authorization Scopes für Groups
Zum Abschluss noch eine kurze Übersicht über alle Scopes, die für den Resource Type Groups zur Verfügung stehen:
| Scope | Bedeutung |
|---|---|
view |
Die Gruppe selbst sehen. |
manage |
Die Gruppe selbst verwalten, also ihre Konfiguration ändern. |
view-members |
Die Mitglieder der Gruppe sehen. |
manage-members |
Die Mitglieder der Gruppe verwalten: Details ändern, Credentials setzen, Rollen zuweisen, löschen. |
manage-membership |
Mitglieder zur Gruppe hinzufügen oder aus ihr entfernen – nötig z. B. beim Anlegen neuer Benutzer in der Gruppe. |
manage-membership-of-members |
Die Gruppenzugehörigkeiten der Mitglieder verwalten, also Mitglieder dieser Gruppe anderen Gruppen zuordnen oder aus ihnen entfernen. |
impersonate-members |
Mitglieder der Gruppe impersonieren. Gilt auch für alle Untergruppen in der Hierarchie, sofern das nicht für einzelne Untergruppen explizit verweigert wird. |
Für das Szenario „ein Benutzer verwaltet die Mitglieder einer Gruppe inklusive Neuanlage“ reicht also die Kombination view, view-members, manage-members und manage-membership – zusammen mit den beiden Rollen query-users und query-groups.
Fazit
Mit den Fine-Grained Admin Permissions in Version 2 ist delegierte Administration in Keycloak endlich praxistauglich. Statt realm-weiter Rollen, die immer gleich für alle Benutzer gelten, vergebe ich gezielt Rechte auf einzelne Ressourcen – zum Beispiel auf die Mitglieder einer einzigen Gruppe.
Die wichtigsten Punkte noch einmal kompakt:
- FGAP v2 wird pro Realm über Realm settings → Admin Permissions aktiviert.
- Der delegierte Admin braucht weiterhin die Basisrollen
query-usersundquery-groups, aber keine globalenview-*- odermanage-*-Rollen. - Wer die Benutzer einer Gruppe verwalten soll, bekommt eine Permission auf den Resource Type Groups, nicht auf Users.
- Zum Anlegen neuer Benutzer in der Gruppe ist zusätzlich
manage-membershipnötig. - Die Admin-Konsole zeigt nicht immer exakt das an, was erlaubt ist – maßgeblich ist die Admin-API.
Probiert es aus und spielt mit den verschiedenen Resource Types, Scopes und Policies. Und haltet eure Keycloak-Umgebung immer auf dem aktuellen Stand – nicht nur wegen neuer Features wie diesem, sondern vor allem wegen der Fixes für Sicherheitslücken (CVEs).
Das komplette Beispiel zeige ich Schritt für Schritt in meinem Video zu diesem Artikel.
Ihr wollt delegierte Administration in eurer Keycloak-Umgebung einführen oder ein tragfähiges Berechtigungsmodell entwerfen? Dabei unterstütze ich euch gerne mit Beratung und Trainings.
Du bist auf der Suche nach Keycloak Beratung, Unterstützung, Workshops oder Trainings?
Nimm Kontakt mit mir auf!« Keycloak DevDay 2027 - Save the date! Delegated User Management with Keycloak: Fine-Grained Admin Permissions (FGAP v2) in Practice »