GRANT, Rollen und das Least-Privilege-Prinzip
Wer allen Anwendungen und Entwicklern denselben Datenbank-Account mit vollen Rechten gibt, macht jede zukuenftige Sicherheitsluecke automatisch zu einem Totalschaden. Granulare Datenbank-Benutzerrechte, aufgebaut aus GRANT-Anweisungen, Rollenhierarchien und dem Least-Privilege-Prinzip, begrenzen den Schaden eines einzelnen kompromittierten Accounts auf genau das, was dieser Account wirklich braucht.
Inhaltsverzeichnis
- 1. Warum granulare Benutzerrechte kein Nice-to-have sind
- 2. GRANT und REVOKE im Detail: Objekt- und Spaltenebene
- 3. Rollenhierarchien statt hunderter Einzelrechte
- 4. Das Least-Privilege-Prinzip in der Praxis umsetzen
- 5. Spaltenebene: Column-Level Grants fuer sensible Felder
- 6. Service-Accounts und Anwendungsrollen sauber trennen
- 7. Rechte-Audits: wer darf was, und warum
- 8. Typische Fehler bei der Rechtevergabe
- 9. Rechtemodelle im Vergleich
- 10. Zusammenfassung
- 11. FAQ
1. Warum granulare Benutzerrechte kein Nice-to-have sind
Granulare Datenbank-Benutzerrechte sind die erste Verteidigungslinie, wenn ein Account kompromittiert wird, sei es durch ein gestohlenes Passwort, eine anfaellige Anwendung oder einen Insider mit boesartiger Absicht. Ohne granulare Datenbank-Benutzerrechte hat ein einzelner kompromittierter Account oft vollen Lese- und Schreibzugriff auf jede Tabelle, jede Funktion und manchmal sogar administrative Rechte, mit denen sich neue Accounts anlegen lassen.
Der typische Weg dorthin ist bequem, aber gefaehrlich: Ein Entwickler legt einen Datenbank-Account an, gibt ihm aus Zeitdruck volle Rechte, und dieser Account wird nie wieder eingeschraenkt, weil das Einschraenken spaeter riskant erscheint, etwas zu brechen. So sammeln sich ueber Jahre Dutzende Accounts mit weit mehr Rechten als noetig an. Granulare Datenbank-Benutzerrechte kehren dieses Muster um: jeder Account bekommt von Anfang an nur die Rechte, die er fuer seine konkrete Aufgabe braucht, nicht mehr.
Regulatorische Anforderungen wie DSGVO, PCI-DSS oder ISO 27001 verlangen explizit nachvollziehbare Datenbank-Benutzerrechte mit dokumentierter Begruendung fuer jede Rechtevergabe. Ein Audit, das zeigen soll, wer Zugriff auf personenbezogene Daten hat, scheitert regelmaessig an Datenbanken, in denen zehn verschiedene Accounts pauschal vollen Zugriff auf alle Tabellen haben, ohne dass jemand mehr erklaeren kann, warum.
2. GRANT und REVOKE im Detail: Objekt- und Spaltenebene
GRANT und REVOKE sind die grundlegenden SQL-Befehle, mit denen Datenbank-Benutzerrechte vergeben und entzogen werden. GRANT arbeitet auf mehreren Ebenen: Datenbank, Schema, Tabelle, Spalte und in vielen Systemen auch auf Funktions- und Sequenz-Ebene. Ein haeufiger Fehler ist, Datenbank-Benutzerrechte immer auf Schema-Ebene mit GRANT ALL ON SCHEMA zu vergeben, obwohl ein Account nur drei von zwanzig Tabellen tatsaechlich braucht.
Die granulare Alternative vergibt Datenbank-Benutzerrechte tabellenweise und aktionsweise: ein Reporting-Account bekommt nur SELECT, niemals INSERT, UPDATE oder DELETE. Ein Batch-Job, der ausschliesslich neue Zeilen in eine Log-Tabelle schreibt, bekommt nur INSERT auf genau diese eine Tabelle, keinen Zugriff auf den Rest des Schemas. Diese Praezision macht jeden Account vorhersagbar: wer die Datenbank-Benutzerrechte eines Accounts liest, weiss sofort, was im schlimmsten Fall bei einer Kompromittierung passieren kann.
-- Coarse-grained (avoid): full schema access for a reporting account
GRANT ALL ON SCHEMA sales TO reporting_user; -- too broad
-- Granular database user privileges: table and action specific
GRANT SELECT ON sales.orders TO reporting_user;
GRANT SELECT ON sales.order_items TO reporting_user;
GRANT SELECT ON sales.customers TO reporting_user;
-- No INSERT, UPDATE, DELETE — reporting never writes
-- A batch job only needs to append to one log table
GRANT INSERT ON audit.import_log TO batch_import_user;
REVOKE SELECT, UPDATE, DELETE ON audit.import_log FROM batch_import_user;
-- Revoke a previously overly broad privilege
REVOKE ALL ON SCHEMA sales FROM reporting_user;
Ein oft uebersehenes Detail bei Datenbank-Benutzerrechte-Vergabe: Standardrechte fuer neue Objekte muessen separat konfiguriert werden. Ohne ALTER DEFAULT PRIVILEGES in PostgreSQL erbt eine neu angelegte Tabelle keine der zuvor vergebenen Rechte, was dazu fuehrt, dass Anwendungen nach jeder Migration ploetzlich Zugriffsfehler werfen, weil die neue Tabelle schlicht vergessen wurde.
3. Rollenhierarchien statt hunderter Einzelrechte
Bei mehr als einer Handvoll Accounts wird direkte Datenbank-Benutzerrechte-Vergabe pro Benutzer schnell unpraktikabel. Die Loesung sind Rollenhierarchien: Rechte werden nicht an einzelne Benutzer, sondern an Rollen vergeben, und Benutzer werden Rollen zugewiesen. Aendert sich, was eine Rolle darf, aendert sich das automatisch fuer jeden Benutzer dieser Rolle, ohne dass hundert einzelne GRANT-Anweisungen angepasst werden muessen.
Eine typische Rollenhierarchie fuer Datenbank-Benutzerrechte definiert Basis-Rollen wie app_readonly, app_readwrite und app_admin, denen konkrete Rechte zugewiesen werden, und weist einzelnen Benutzern dann genau eine dieser Rollen zu. PostgreSQL erlaubt sogar verschachtelte Rollen, bei denen eine Rolle die Rechte einer anderen erbt, was komplexe Organisationsstrukturen abbildet, ohne Rechte doppelt pflegen zu muessen.
-- Define base roles once, grant privileges to the role, not the user
CREATE ROLE app_readonly NOLOGIN;
GRANT SELECT ON ALL TABLES IN SCHEMA sales TO app_readonly;
CREATE ROLE app_readwrite NOLOGIN;
GRANT app_readonly TO app_readwrite; -- inherits read access
GRANT INSERT, UPDATE ON ALL TABLES IN SCHEMA sales TO app_readwrite;
-- Actual login users only get assigned to a role, never granted directly
CREATE ROLE analytics_service LOGIN PASSWORD 'change_me';
GRANT app_readonly TO analytics_service;
CREATE ROLE order_service LOGIN PASSWORD 'change_me';
GRANT app_readwrite TO order_service;
-- Changing what app_readonly can do updates every member automatically
GRANT SELECT ON sales.new_reporting_view TO app_readonly;
4. Das Least-Privilege-Prinzip in der Praxis umsetzen
Das Least-Privilege-Prinzip verlangt, dass jeder Account nur genau die Datenbank-Benutzerrechte hat, die fuer seine Aufgabe zwingend notwendig sind, nicht mehr. In der Praxis beginnt die Umsetzung mit einer Inventur: Fuer jeden bestehenden Account wird dokumentiert, welche Operationen er tatsaechlich ausfuehrt, meist ueber Query-Logs oder Anwendungscode-Analyse, und die aktuellen Datenbank-Benutzerrechte werden mit diesem Bedarf abgeglichen.
Ein praktikabler Ansatz fuer neue Systeme ist der umgekehrte Weg: Ein Account startet mit null Datenbank-Benutzerrechte, und Rechte werden erst hinzugefuegt, wenn eine konkrete Fehlermeldung ("permission denied") zeigt, dass eine Operation tatsaechlich gebraucht wird. Dieser reaktive, aber disziplinierte Ansatz verhindert das Ansammeln ungenutzter Rechte, die spaeter niemand mehr zurueckbaut.
Zeitlich begrenzte Datenbank-Benutzerrechte sind eine Ergaenzung fuer Ausnahmesituationen: Ein Entwickler, der einmalig eine Datenkorrektur durchfuehren muss, bekommt ein temporaeres GRANT, das nach einem definierten Zeitfenster automatisch per Cronjob oder Datenbank-Event wieder entzogen wird, statt dauerhaft erhoehte Rechte zu behalten.
5. Spaltenebene: Column-Level Grants fuer sensible Felder
Nicht jede Zugriffsbeschraenkung laesst sich auf Tabellenebene loesen. Eine Kundentabelle enthaelt oft sowohl unkritische Felder wie Namen und Adressen als auch hochsensible Felder wie Kreditkartendaten oder Sozialversicherungsnummern. Column-Level Datenbank-Benutzerrechte erlauben, einem Account Zugriff auf die unkritischen Spalten zu geben, waehrend sensible Spalten vollstaendig unsichtbar bleiben.
In PostgreSQL und den meisten relationalen Datenbanken unterstuetzt GRANT SELECT (spalte1, spalte2) ON tabelle genau diese Einschraenkung. Ein Support-Mitarbeiter-Account kann so Namen und Bestellstatus einsehen, ohne je Zahlungsdaten zu Gesicht zu bekommen, selbst bei einem direkten SELECT *-Versuch, der dann schlicht mit einem Berechtigungsfehler fuer die nicht freigegebenen Spalten abgelehnt wird.
-- Column-level database user privileges: expose only safe fields
GRANT SELECT (id, first_name, last_name, order_status)
ON customers TO support_agent;
-- Sensitive columns remain completely inaccessible
-- SELECT * FROM customers; -- fails: permission denied for column ssn
-- Combine with a view for even cleaner separation
CREATE VIEW customers_support_view AS
SELECT id, first_name, last_name, order_status FROM customers;
GRANT SELECT ON customers_support_view TO support_agent;
REVOKE SELECT ON customers FROM support_agent;
6. Service-Accounts und Anwendungsrollen sauber trennen
Ein Muster, das in gewachsenen Systemen haeufig fehlt: getrennte Datenbank-Benutzerrechte pro Microservice oder Anwendungsteil, statt eines einzigen gemeinsamen Datenbank-Accounts fuer die gesamte Anwendung. Wenn ein Zahlungsservice und ein Produktkatalog-Service denselben Account nutzen, hat eine Schwachstelle im weniger kritischen Katalog-Service automatisch Zugriff auf Zahlungsdaten, weil die Datenbank-Benutzerrechte nicht nach Service getrennt sind.
Getrennte Service-Accounts mit eigenen, minimalen Datenbank-Benutzerrechte pro Service begrenzen den Blast-Radius eines kompromittierten Services auf genau die Tabellen, die dieser Service wirklich braucht. In Kubernetes-Umgebungen laesst sich dieses Muster mit Secrets-Management kombinieren, sodass jeder Pod nur die Zugangsdaten fuer seinen eigenen, minimal berechtigten Service-Account erhaelt, nie einen gemeinsamen Master-Account.
-- Separate service accounts, each with its own scoped privileges
CREATE ROLE payment_service LOGIN PASSWORD 'change_me';
GRANT SELECT, INSERT, UPDATE ON payments, payment_methods TO payment_service;
CREATE ROLE catalog_service LOGIN PASSWORD 'change_me';
GRANT SELECT ON products, categories TO catalog_service;
GRANT INSERT, UPDATE ON products TO catalog_service;
-- catalog_service has zero visibility into payment tables
-- A compromised catalog_service cannot read payments at all
7. Rechte-Audits: wer darf was, und warum
Granulare Datenbank-Benutzerrechte ohne regelmaessiges Audit verfallen ueber Zeit zu genau dem Zustand, den sie verhindern sollen. Rechte, die einmal fuer ein Projekt vergeben wurden, bleiben bestehen, auch wenn das Projekt laengst beendet ist. Ein periodisches Audit fragt die Systemkataloge der Datenbank ab und listet fuer jeden Account genau auf, welche Datenbank-Benutzerrechte aktuell aktiv sind.
In PostgreSQL liefern information_schema.table_privileges und information_schema.role_table_grants genau diese Uebersicht. Ein automatisiertes Skript, das diese Sicht regelmaessig gegen eine dokumentierte Soll-Liste vergleicht, deckt Abweichungen auf, bevor sie zum Sicherheitsrisiko werden, etwa wenn ein Account ploetzlich mehr Rechte hat als in der letzten dokumentierten Pruefung.
-- Audit query: which database user privileges exist per role
SELECT grantee, table_schema, table_name, privilege_type
FROM information_schema.role_table_grants
WHERE grantee NOT IN ('postgres', 'PUBLIC')
ORDER BY grantee, table_schema, table_name;
-- Find accounts with dangerously broad privileges
SELECT grantee, count(*) AS granted_tables
FROM information_schema.role_table_grants
WHERE privilege_type IN ('DELETE', 'TRUNCATE')
GROUP BY grantee
HAVING count(*) > 5
ORDER BY granted_tables DESC;
8. Typische Fehler bei der Rechtevergabe
Der haeufigste Fehler: Alle Datenbank-Benutzerrechte ueber einen einzigen Superuser-Account laufen zu lassen, weil das Einrichten separater Rollen anfangs mehr Aufwand macht. Dieser Aufwand ist minimal im Vergleich zum Schaden eines kompromittierten Superuser-Accounts. Ein zweiter haeufiger Fehler: Rechte werden grosszuegig vergeben, "um Zeit zu sparen", mit der Absicht, sie spaeter einzuschraenken, was in der Praxis fast nie passiert, weil kein konkreter Anlass mehr besteht.
Ein dritter Fehler betrifft vergessene Standardrechte: Neue Tabellen erben in PostgreSQL ohne ALTER DEFAULT PRIVILEGES keine der zuvor vergebenen Datenbank-Benutzerrechte, was zu inkonsistenten Zustaenden fuehrt, in denen aeltere Tabellen restriktiv, neuere Tabellen aber versehentlich offen fuer alle Accounts sind, weil niemand die neue Tabelle explizit in die Rechtevergabe aufgenommen hat.
9. Rechtemodelle im Vergleich
Verschiedene Ansaetze zur Vergabe von Datenbank-Benutzerrechte unterscheiden sich deutlich in Wartungsaufwand und Sicherheitsniveau. Die Tabelle zeigt, welches Muster in welcher Situation die bessere Wahl ist.
| Situation | Riskant | Empfohlenes Muster | Vorteil |
|---|---|---|---|
| Anwendungs-Zugriff | Ein gemeinsamer Superuser-Account | Service-Account je Anwendungsteil | Begrenzter Blast-Radius |
| Rechtevergabe | Pro Benutzer einzeln GRANT | Rollenhierarchie mit Basisrollen | Zentral aenderbar |
| Sensible Spalten | GRANT SELECT auf ganze Tabelle | Column-Level GRANT oder View | Sensible Felder unsichtbar |
| Reporting | Schreibrechte pauschal mit vergeben | Nur SELECT, nie INSERT/UPDATE/DELETE | Kein versehentliches Schreiben |
| Neue Tabellen | Rechte manuell nachziehen | ALTER DEFAULT PRIVILEGES | Konsistente Rechte automatisch |
In allen Faellen gilt: Rollenbasierte, granulare Datenbank-Benutzerrechte mit regelmaessigem Audit sind planbarer und sicherer als individuell vergebene Einzelrechte, die ueber Jahre wuchern und irgendwann niemand mehr vollstaendig ueberblickt.
Mironsoft
Datenbank-Sicherheit, Rechte-Audits und Least-Privilege-Umsetzung
Datenbank-Benutzerrechte endlich granular statt pauschal?
Wir pruefen bestehende Accounts, bauen Rollenhierarchien nach dem Least-Privilege-Prinzip auf und trennen Service-Accounts sauber, damit ein kompromittierter Account nie mehr Schaden anrichtet als noetig.
Rechte-Audit
Bestehende GRANT-Strukturen erfassen und gegen Bedarf abgleichen
Rollen-Design
Rollenhierarchien und Service-Accounts nach Least Privilege aufbauen
Automatisierung
Wiederkehrende Rechte-Audits und Alerts bei Abweichungen einrichten
10. Zusammenfassung
Granulare Datenbank-Benutzerrechte sind kein buerokratischer Selbstzweck, sondern die wirksamste Massnahme, um den Schaden eines kompromittierten Accounts zu begrenzen. GRANT und REVOKE auf Tabellen-, Aktions- und Spaltenebene, kombiniert mit Rollenhierarchien statt Einzelrechten pro Benutzer, machen Rechtevergabe nachvollziehbar und zentral aenderbar.
Das Least-Privilege-Prinzip verlangt, jeden Account mit minimalen Rechten zu starten und nur bei nachgewiesenem Bedarf zu erweitern, nicht umgekehrt. Getrennte Service-Accounts pro Anwendungsteil begrenzen den Blast-Radius einer Kompromittierung, und regelmaessige Audits gegen die Systemkataloge der Datenbank stellen sicher, dass Datenbank-Benutzerrechte nicht ueber Jahre unkontrolliert wuchern.
Datenbank-Benutzerrechte granular vergeben: Das Wichtigste auf einen Blick
GRANT auf Feinebene
Tabellen-, Aktions- und Spaltenebene statt pauschalem Schema- oder Datenbankzugriff.
Rollen statt Einzelrechte
Rechte an Rollen vergeben, Benutzer der Rolle zuweisen, zentral aenderbar ohne Massenanpassung.
Service-Accounts trennen
Ein Account je Anwendungsteil, nie ein gemeinsamer Master-Account fuer alle Services.
Regelmaessiges Audit
information_schema regelmaessig gegen eine dokumentierte Soll-Liste pruefen, Abweichungen alarmieren.