Postgres hat keine echten „Gruppen“ — es gibt nur Rollen. Trotzdem ist das Gruppen-Pattern allgegenwärtig und ist die saubere Art, Rechte zu organisieren: eine NOLOGIN-Rolle bündelt die Privilegien, Login-Rollen werden als Mitglieder hinzugefügt. Wie das technisch funktioniert, klären wir hier.

Das Pattern in vier Zeilen

SQL Gruppe + Mitglieder + Rechte
CREATE ROLE devs;                                    -- Container (NOLOGIN)
CREATE USER alice PASSWORD 'changeme';
CREATE USER bob   PASSWORD 'changeme';
GRANT devs TO alice, bob;                            -- Mitgliedschaft

GRANT USAGE ON SCHEMA app TO devs;
GRANT SELECT, INSERT, UPDATE ON ALL TABLES IN SCHEMA app TO devs;

Damit hat jede Person, die in devs ist, vollen Lese-Schreib-Zugriff auf das app-Schema — ohne dass irgendwo alice oder bob direkt in einem GRANT auftauchen. Will jemand in der Gruppe drin sein, ein einziger GRANT devs TO … reicht.

INHERIT — automatisch oder explizit?

Was passiert, wenn alice jetzt eine Query absetzt? Das hängt von ihrem INHERIT-Attribut ab:

  • INHERIT (Default): Alice nutzt automatisch alles, was Mitglieder von devs dürfen. Sie schreibt einfach SELECT * FROM app.orders; und es funktioniert.
  • NOINHERIT: Alice muss explizit SET ROLE devs; ausführen, dann erst greifen die Gruppen-Rechte.

Beispiel mit NOINHERIT:

SQL NOINHERIT zwingt zu SET ROLE
CREATE USER carol WITH NOINHERIT PASSWORD 'changeme';
GRANT devs TO carol;

-- Carol verbindet sich:
myapp=> SELECT * FROM app.orders;
ERROR:  permission denied for table orders

myapp=> SET ROLE devs;
SET
myapp=> SELECT * FROM app.orders;
-- OK

Welcher Modus? Default INHERIT ist für die meisten Anwendungen richtig — pragmatisch und unbürokratisch. NOINHERIT wird interessant, wenn man eine Audit-Trennung will: in den Logs taucht dann auf, wann jemand bewusst privilegierte Rechte aktiviert hat.

current_user vs. session_user

Sobald du mit SET ROLE arbeitest, stellt sich die Frage: wer macht jetzt eigentlich was?

FunktionRückgabe
session_userDie Rolle, mit der die Session gestartet wurde. Ändert sich nie.
current_userDie Rolle, deren Rechte aktuell wirken. Ändert sich bei SET ROLE.
current_roleSynonym zu current_user.
SQL Wer bin ich gerade?
myapp=> SELECT session_user, current_user;
 session_user | current_user
--------------+--------------
 carol        | carol

myapp=> SET ROLE devs;
myapp=> SELECT session_user, current_user;
 session_user | current_user
--------------+--------------
 carol        | devs

Für Audit-Logs (z. B. via Trigger oder eigene Logging-Funktion) ist session_user meist die richtige Quelle: sie zeigt, wer sich angemeldet hat — unabhängig davon, in welche Rolle dieser Mensch sich gerade verwandelt hat.

RESET ROLE setzt die aktive Rolle wieder auf den session_user zurück.

Verschachtelte Mitgliedschaften

Rollen können in mehreren Gruppen sein, und Gruppen können selbst wieder Mitglied anderer Gruppen sein:

SQL Verschachtelung
CREATE ROLE all_employees;
CREATE ROLE devs;
CREATE ROLE designers;

GRANT all_employees TO devs, designers;   -- devs und designers sind in all_employees
GRANT devs TO alice;                       -- alice ist in devs (und damit in all_employees)
GRANT designers TO bob;                    -- bob ist in designers (und damit in all_employees)

Mit INHERIT (Default) erbt Alice transitiv: devs-Rechte und all_employees-Rechte. Postgres folgt der Mitgliedschafts-Kette beliebig tief.

Wer wissen will, wo eine Rolle drin ist, schaut in den Katalog:

SQL
SELECT r.rolname AS member, g.rolname AS member_of
FROM pg_auth_members m
JOIN pg_roles r ON r.oid = m.member
JOIN pg_roles g ON g.oid = m.roleid
ORDER BY 1, 2;

ADMIN OPTION — wer darf Mitgliedschaften vergeben?

Standardmäßig dürfen nur Superuser und der Eigentümer einer Rolle Mitgliedschaften an ihr verteilen. Wer das delegieren will, nutzt WITH ADMIN OPTION:

SQL
GRANT devs TO team_lead WITH ADMIN OPTION;

Damit darf team_lead selbst andere Rollen in die devs-Gruppe aufnehmen oder rauswerfen, ohne Superuser zu sein. Praktisch in größeren Setups, in denen der DBA nicht jede personelle Änderung manuell machen will.

Mitgliedschaft entziehen

SQL
REVOKE devs FROM bob;

Bob ist ab sofort nicht mehr in der Gruppe. Bestehende Sessions sind davon nicht automatisch betroffen — laufende Verbindungen behalten ihre Rechte, bis sie sich neu authentifizieren. Wenn das wichtig ist, muss man die Sessions manuell beenden (siehe Aktive Sessions beenden).

Besonderheiten

Eine Gruppe ist genauso eine „Rolle“ wie ein User.

Postgres trennt nicht intern. Du kannst einer NOLOGIN-Rolle ein Passwort geben (sinnlos, aber technisch erlaubt) oder ihr LOGIN nachträglich verleihen — und sie wird damit zum normalen User. Diese Flexibilität ist gewollt; das Modell ist absichtlich uniform.

SET ROLE wechselt nur die Rechte, nicht die Identität.

session_user bleibt unverändert. Wer Audit-Trails braucht, sollte in Trigger-Funktionen session_user loggen, nicht current_user — sonst sieht man nur die zuletzt aktivierte Gruppe und nicht den Menschen dahinter.

SET LOCAL ROLE hält den Rollenwechsel auf eine Transaktion begrenzt.

Innerhalb einer Transaktion kannst du mit SET LOCAL ROLE devs temporär eine andere Rolle annehmen — am Ende der Transaktion (COMMIT/ROLLBACK) kehrt Postgres automatisch zurück. Praktisch für „nur für diese Migration als app_owner arbeiten“-Patterns.

Mitgliedschaft + SECURITY DEFINER als Eskalationsleiter.

Eine Funktion mit SECURITY DEFINER läuft mit den Rechten des Owners statt des Aufrufers. Kombiniert mit Mitgliedschaftsregeln lässt sich damit kontrolliertes Privilege-Escalation bauen: ein normaler User ruft eine Funktion auf, die intern mehr darf, als er selbst dürfte. Mächtig, aber auch ein häufiges Sicherheitsleck — der search_path muss in solchen Funktionen unbedingt explizit gesetzt werden.

WITH ADMIN OPTION ist transitiv.

Wer eine Rolle mit ADMIN OPTION bekommt, darf sie weitergeben — auch mit ADMIN OPTION. Das kann zu unerwarteten Eskalationen führen, wenn niemand mehr überblickt, wer eigentlich Admin von wem ist. Regelmäßig auditieren via pg_auth_members.admin_option.

Weiterführende Ressourcen

Externe Quellen

/ Weiter

Zurück zu Server-Administration

Zur Übersicht