Datenbankadministration für Sysadmins

Zugriff und Identitäten: Anmeldung, Rollen und effektive Rechte

Eine Datenbank zieht auf eine neue Instanz um. Der Login heißt gleich, das Passwort stimmt, die Anmeldung gelingt — und die Anwendung findet keine einzige ihrer Tabellen. Der Grund ist keine vergessene Rechtevergabe, sondern eine Kennung, die niemand von Hand vergeben hat. Dieses Modul trennt die beiden Fragen, die ständig füreinander gehalten werden: Wer darf herein, und wer darf was — und wo beide Systeme die Antwort speichern.

Lehrtext · 10 Abschnitte · zuletzt geprüft: 2026-09-12

Zwei Fragen, die ständig füreinander gehalten werden

„Der Benutzer hat keinen Zugriff“ beschreibt zwei völlig verschiedene Zustände, und sie werden an verschiedenen Orten entschieden. Wer die falsche Stelle öffnet, löst das Problem entweder gar nicht oder viel zu weit.

AuthentifizierungDarf diese Verbindung überhaupt zustande kommen, und als wer? Entschieden bei PostgreSQL in pg_hba.conf, bei SQL Server über den Login auf Instanz-Ebene.

AutorisierungWas darf die bereits angemeldete Identität tun? Entschieden über GRANT und REVOKE auf einzelnen Objekten, in beiden Systemen.

Die beiden Prüfungen sind hintereinandergeschaltet, nicht alternativ. Die PostgreSQL-Dokumentation hält ausdrücklich fest, dass ein Benutzer für die Verbindung zu einer bestimmten Datenbank nicht nur die Prüfung in pg_hba.conf bestehen, sondern zusätzlich das CONNECT-Recht auf dieser Datenbank besitzen muss. Sie empfiehlt sogar, die Frage „wer darf in welche Datenbank“ über CONNECT zu steuern statt über Einträge in pg_hba.conf — weil Rechte je Datenbank feiner und ohne Neuladen der Konfiguration änderbar sind.

Das Fehlerbild trennt die beiden zuverlässigEine abgelehnte Anmeldung meldet einen Authentifizierungsfehler und kommt gar nicht erst in die Datenbank. Eine fehlende Berechtigung meldet einen Rechtefehler auf einem konkreten Objekt — die Sitzung steht dann bereits. Wer das Fehlerbild liest, weiß, in welcher der beiden Welten er suchen muss.

`pg_hba.conf`: die erste passende Zeile gewinnt — und sonst keine

Die Datei ist eine Liste von Regelsätzen, eine je Zeile. Jeder Satz nennt eine Verbindungsart, einen Adressbereich, eine Datenbank, einen Benutzernamen und die zu verwendende Methode.

local
Verbindung über den lokalen Unix-Socket, ohne Netz.
host
Verbindung über TCP/IP, verschlüsselt oder nicht.
hostssl / hostnossl
Nur verschlüsselte beziehungsweise nur unverschlüsselte TCP-Verbindungen.

Entscheidend ist nicht das Format, sondern die Auswertung. Die Dokumentation formuliert sie unmissverständlich: Der erste Satz, dessen Verbindungsart, Clientadresse, angeforderte Datenbank und Benutzername passen, wird für die Authentifizierung verwendet. Es gibt kein Durchfallen und keinen Ersatzsatz — wenn ein Satz ausgewählt wurde und die Authentifizierung fehlschlägt, werden die folgenden Sätze nicht mehr betrachtet. Passt gar kein Satz, wird der Zugriff verweigert.

Warum das der häufigste Fehler in dieser Datei istDie Regel ist dieselbe wie bei einer Paketfilter-Kette: Die spezifischen Einträge gehören nach oben, die allgemeinen nach unten. Wer eine neue, strengere Zeile unten anhängt, während oben noch eine weite Zeile steht, hat die Datei geändert, ohne etwas zu ändern. Die Konfiguration sieht danach korrekt aus — und genau deshalb fällt der Fehler bei einer Sichtprüfung nicht auf.

Die Dokumentation empfiehlt deshalb ausdrücklich, frühe Sätze mit engen Trefferbedingungen und spätere mit weiteren zu versehen. Dazu kommt eine zweite Reihenfolge, die leicht übersehen wird: Werden über include_dir mehrere Dateien eingebunden, verarbeitet PostgreSQL sie in Dateinamen-Reihenfolge nach den Regeln der C-Locale — Ziffern vor Buchstaben, Großbuchstaben vor Kleinbuchstaben. Eine Datei 10-app.conf wird also vor 90-default.conf gelesen, eine Datei Zusatz.conf vor app.conf.

Was `trust` wirklich bedeutet

Unter den Methoden in pg_hba.conf ist eine, die keine ist. Die Dokumentation beschreibt trust so: Die Verbindung wird bedingungslos zugelassen; diese Methode erlaubt jedem, der den Server erreichen kann, sich als jeder beliebige PostgreSQL-Benutzer anzumelden, ohne Passwort und ohne jede andere Authentifizierung.

Das ist kein „schwaches Passwort“, sondern gar keinesEin trust-Eintrag für all all bedeutet, dass jeder erreichbare Client sich als Superuser anmelden kann. Der Unterschied zu einem schwachen Passwort ist kategorisch: Es gibt nichts zu raten.

Dazu kommt eine Voreinstellung, die viele Installationen ungeprüft übernehmen. Die Dokumentation zu initdb hält fest, dass die erzeugte Standardkonfiguration für die Client-Authentifizierung es jedem lokalen Benutzer erlaubt, sich zu verbinden und sogar Datenbank-Superuser zu werden. Empfohlen wird deshalb, beim Initialisieren ein Passwort für den Superuser zu vergeben und -A scram-sha-256 zu setzen, damit die Voreinstellung trust nicht verwendet wird — oder die erzeugte pg_hba.conf zu ändern, bevor der Server das erste Mal startet.

trust
Ohne jede Prüfung. Nur vertretbar, wo der Zugang zum Socket bereits vollständig kontrolliert ist.
peer
Vergleicht den Betriebssystem-Benutzer des lokalen Clients mit dem angeforderten Datenbankbenutzer. Nur für local.
scram-sha-256
Passwortverfahren mit Challenge-Response. Das Passwort geht nie im Klartext über die Leitung.
password
Verlangt ein Passwort im Klartext über die Verbindung. Laut Dokumentation nicht für unsichere Netze.
cert
Authentifizierung über ein Client-Zertifikat; nur bei hostssl.
gss / sspi
Kerberos beziehungsweise das Windows-Pendant, für Anmeldung gegen ein Verzeichnis.

Auf der SQL-Server-Seite gibt es keine vergleichbare Datei. Die Entsprechung ist die Wahl zwischen Windows-Authentifizierung und SQL-Server-Authentifizierung je Login, zusammen mit der Frage, ob der Netzwerkzugang zum Port überhaupt besteht.

PostgreSQL kennt keine Benutzer — nur Rollen

Es gibt in PostgreSQL keinen getrennten Objekttyp für Benutzer und Gruppen. Es gibt genau einen: die Rolle. Ob sie sich anmelden darf, ist nur ein Attribut.

Rolle mit LOGINDas, was anderswo „Benutzer“ heißt. createuser ist laut Dokumentation lediglich ein Aufruf-Mantel um CREATE ROLE.

Rolle ohne LOGINDas, was anderswo „Gruppe“ heißt. Rechte werden auf sie vergeben, Anmelde-Rollen werden ihr per GRANT als Mitglied zugeordnet.

Daraus folgt die operativ wichtigste Eigenschaft: Rollen sind clusterweit. Die Dokumentation stellt ausdrücklich fest, dass sie global für die gesamte Cluster-Installation gelten und nicht je einzelner Datenbank. Eine Rolle existiert also einmal, egal wie viele Datenbanken auf der Instanz liegen — die Rechte dagegen hängen an den Objekten und damit an je einer Datenbank.

Und Betriebssystem-Konten sind etwas DrittesDie Dokumentation ist an dieser Stelle deutlich: Datenbankrollen sind begrifflich vollständig getrennt von Betriebssystem-Benutzern. In der Praxis ist eine Entsprechung oft bequem — die peer-Methode lebt davon —, aber sie ist nicht gefordert. Ein Datenbankpasswort ist etwas anderes als ein Systempasswort, selbst wenn beide Konten gleich heißen.

SQL Server trennt Login und Benutzer — und genau dort bricht der Restore

SQL Server löst dieselbe Aufgabe mit zwei Objekten auf zwei Ebenen, und diese Trennung ist die Ursache eines Fehlers, der bei fast jedem Umzug einer Datenbank auftritt.

Login
Lebt auf Instanz-Ebene, verzeichnet in master, sichtbar über sys.server_principals. Er entscheidet, ob eine Verbindung zur Instanz zustande kommt.
Datenbankbenutzer
Lebt in der Datenbank. Er trägt die Rechte auf Tabellen und Schemata.

Verbunden werden die beiden über einen Bezeichner, nicht über den Namen. Laut Dokumentation wird die Zuordnung eines Logins zu einem Datenbankbenutzer in der Datenbank gespeichert und enthält den Namen des Benutzers sowie die Sicherheitskennung — die SID — des zugehörigen Logins. Jeder Sicherheitsprinzipal besitzt eine solche SID.

Die Anwendung kommt nach dem Restore nicht mehr an ihre Daten

Szenario

Eine Fachdatenbank wird von der alten Instanz gesichert und auf einer neuen wiederhergestellt. Auf der neuen Instanz wird ein Login mit demselben Namen und demselben Passwort angelegt. Die Anwendung meldet sich an, findet aber keine Objekte.

Anforderungen

  • Sicherung und Wiederherstellung waren fehlerfrei
  • Der Login-Name auf beiden Instanzen ist identisch
  • Der Datenbankbenutzer steht unverändert in der Datenbank

Schritte

  1. Der Benutzer in der wiederhergestellten Datenbank trägt die SID des alten Logins. Der neu angelegte Login auf der Zielinstanz hat eine neue SID — gleicher Name, anderer Bezeichner.
  2. Damit ist der Benutzer verwaist: Die Dokumentation nennt einen Benutzer verwaist, wenn er auf einem Login in master beruht, dieser Login dort aber nicht mehr existiert. Genau das passiert, wenn eine Datenbank auf einen anderen Server verschoben wird, auf dem der Login fehlt.
  3. Die Anmeldung an der Instanz gelingt trotzdem, weil der Login existiert. Nur die Zuordnung in der Datenbank greift ins Leere — deshalb sieht es aus wie ein Rechteproblem und ist ein Identitätsproblem.
  4. Behoben wird es mit ALTER USER ... WITH LOGIN, das den Benutzer auf die SID des neuen Logins umbiegt. Die früher übliche Prozedur sp_change_users_login ist laut Dokumentation veraltet.

Merksatz: Gleicher Name heißt nicht gleiche Identität. Wer nach einem Umzug Rechte neu vergibt, statt die Zuordnung zu reparieren, baut eine zweite Berechtigungsschicht neben der bestehenden auf.

Der Weg, der das Problem gar nicht erst hatDie Dokumentation empfiehlt für Datenbanken, die umziehen könnten, eigenständige Datenbankbenutzer: Sie authentifizieren sich auf Ebene der Nutzdatenbank und sind an keinen Login gebunden, können also nicht verwaisen. Der Preis steht gleich daneben — sie müssen je Datenbank einzeln angelegt werden, was in einer Umgebung mit vielen Datenbanken unpraktisch wird.

Die drei `dbo`, die nicht dasselbe sind

Kaum eine Stelle im SQL-Server-Rechtemodell führt so zuverlässig zu Missverständnissen wie diese drei Begriffe, die fast gleich heißen und drei verschiedene Dinge bezeichnen. Die Dokumentation trennt sie ausdrücklich.

dbo-Benutzer
Ein besonderer Benutzer in jeder Datenbank. Er hat alle Rechte darin, lässt sich nicht einschränken und nicht löschen.
db_owner-Rolle
Eine feste Datenbankrolle, der Benutzer als Mitglieder zugeordnet werden. Nicht dasselbe wie der dbo-Benutzer.
Eingetragener Datenbankeigentümer
Das Konto, das als Eigentümer der Datenbank verzeichnet ist. Wieder etwas anderes als die Rolle.

Zusammengehalten werden sie durch eine Regel, die im Betrieb den Unterschied macht: Alle Administratoren, alle Mitglieder der festen Serverrolle sysadmin, der Login sa und die Eigentümer einer Datenbank betreten diese Datenbank als dbo. Wer also in einer Rechteübersicht nach dem Namen eines Administrators sucht, findet ihn nicht — er erscheint dort als dbo.

Folge für die NachvollziehbarkeitObjekte, die ein Administrator anlegt, gehören dbo, nicht ihm. Aus der Datenbank allein lässt sich hinterher nicht rekonstruieren, welcher Mensch die Tabelle erzeugt hat. Wer diese Spur braucht, muss sie außerhalb führen — im Change-Verfahren oder in einer Auditierung.

`public`: das Recht, das niemand vergeben hat

Beide Systeme kennen eine Sammelrolle, in der jeder automatisch Mitglied ist. Sie ist der häufigste Grund dafür, dass ein Konto mehr kann, als seine Rechteliste vermuten lässt.

Bei SQL Server gehört laut Dokumentation jeder Login der festen Serverrolle public an und jeder Datenbankbenutzer der Datenbankrolle public. Wo einem Prinzipal auf einem Objekt weder etwas gewährt noch verweigert wurde, erbt er die Rechte, die public auf diesem Objekt hat — und davon sind ab Werk etliche vergeben. Bei PostgreSQL erfüllt die Pseudo-Rolle PUBLIC dieselbe Aufgabe; das CREATE-Recht auf dem Schema public in hochgezogenen Datenbanken ist der bekannteste Fall.

Warum `DENY` an `public` die falsche Antwort istDie SQL-Server-Dokumentation warnt ausdrücklich davor: Rechte von public zu entziehen wirkt auf alle Logins und Benutzer, und ein DENY überschreibt jedes GRANT, das man einzelnen Konten noch geben möchte. Ein DENY auf public ist damit nicht die strengste Variante einer Einschränkung, sondern eine Sperre, die sich einzeln nicht mehr aufheben lässt. Der richtige Hebel ist REVOKE — das Recht wegnehmen, nicht verbieten.

Kurzcheck

Ein Konto darf eine Tabelle lesen, obwohl in seiner Rechteliste nichts dazu steht. Wo suchst du zuerst?

  • In den Mitgliedschaften und in dem, was public auf dem Objekt hat
  • In pg_hba.conf beziehungsweise in den Einstellungen des Logins
  • Im Besitzverhältnis der Tabelle, weil Eigentümer immer lesen dürfen

Treffer. Richtig. Effektive Rechte sind die Summe aus direkten Vergaben, geerbten Rechten aus Rollenmitgliedschaften und dem, was die Sammelrolle ohnehin trägt.

Superuser und `sysadmin`: hinter dieser Grenze wird nichts mehr geprüft

Beide Systeme haben eine Stufe, auf der die Rechteprüfung nicht streng, sondern gar nicht mehr stattfindet. Das ist ein kategorischer Unterschied zu „viele Rechte“.

Die PostgreSQL-Dokumentation formuliert es so: Ein Datenbank-Superuser umgeht alle Rechteprüfungen — mit der einzigen Ausnahme des Rechts, sich anzumelden. Sie nennt das ein gefährliches Privileg und empfiehlt, die meiste Arbeit unter einer Rolle zu erledigen, die kein Superuser ist.

Auf der SQL-Server-Seite gilt Entsprechendes für den Login sa: Er ist Mitglied der festen Serverrolle sysadmin, hat laut Dokumentation alle Rechte auf dem Server, und diese Rechte lassen sich nicht einschränken. Löschen lässt er sich ebenfalls nicht — wohl aber deaktivieren, sodass ihn niemand mehr verwenden kann.

Was daraus für eine Rechteprüfung folgtAuf dieser Stufe ist die Frage „was darf dieses Konto“ sinnlos, weil die Antwort immer „alles“ lautet. Die einzige sinnvolle Frage ist, wer auf dieser Stufe steht. Eine Rechteübersicht, die Objektrechte auflistet, aber die Mitgliedschaft in sysadmin oder das Superuser-Attribut nicht prüft, prüft an der wichtigsten Stelle vorbei.

Dazwischen liegen Abstufungen, die genau deshalb existieren. CREATEDB und CREATEROLE in PostgreSQL geben eng umrissene Verwaltungsrechte, ohne die Prüfung abzuschalten. Die Dokumentation grenzt CREATEROLE dabei sorgfältig ab: Es erlaubt nicht, Superuser-Rollen anzulegen, und verleiht keine Macht über bereits bestehende Superuser-Rollen. Es erlaubt auch nicht, Replikations-Rollen zu erzeugen oder das Replikationsrecht zu vergeben.

Das Recht für morgen: der Grant, der neue Tabellen nicht erfasst

Ein Muster, das in fast jeder Umgebung mit automatisierten Schemaänderungen einmal zuschlägt: Die Anwendung läuft, eine Migration legt eine neue Tabelle an, und ab diesem Moment meldet die Anwendung auf genau dieser Tabelle einen Rechtefehler.

Der Grund ist, dass GRANT auf vorhandene Objekte wirkt. Ein GRANT SELECT ON ALL TABLES IN SCHEMA fach TO app_ro ist keine stehende Regel, sondern eine Aufzählung zum Zeitpunkt der Ausführung. Was danach entsteht, ist nicht erfasst.

Das Gegenstück heißt ALTER DEFAULT PRIVILEGES. Die Dokumentation beschreibt es als das Setzen von Rechten, die auf künftig erzeugte Objekte angewendet werden — und stellt im selben Satz klar, dass es die Rechte bereits vorhandener Objekte nicht berührt. Beide Befehle zusammen sind nötig: einer für den Bestand, einer für den Zuwachs.

Die Feinheit, die den zweiten Anlauf kostetStandardrechte hängen an der Rolle, die das Objekt erzeugt. Die Dokumentation hält fest, dass die Rechte eines neuen Objekts nur von den Standardrechten der aktuellen Rolle beeinflusst werden und nicht von denen der Rollen geerbt werden, in denen die aktuelle Rolle Mitglied ist. Wer die Standardrechte für admin setzt, die Migration aber unter deploy laufen lässt, hat sie für den falschen Erzeuger gesetzt — und merkt es erst bei der nächsten neuen Tabelle.

Praktisch heißt das: Die Standardrechte gehören auf genau die Rolle, unter der die Migrationen tatsächlich laufen, und diese Rolle gehört getrennt von der Rolle, unter der die Anwendung arbeitet.

Rollentrennung: Daten ändern und Sicherungen verwalten gehören nicht in eine Hand

Aus allem Vorherigen folgt ein Zuschnitt, der weniger mit Misstrauen zu tun hat als mit Fehlertoleranz: Wer Daten ändern und die Sicherungen verwalten kann, kann einen Fehler auf beiden Seiten gleichzeitig machen. Ein falsches UPDATE ist ärgerlich; ein falsches UPDATE plus eine überschriebene Sicherungskette ist ein Datenverlust.

Anwendungsrolle
Nur SELECT, INSERT, UPDATE, DELETE auf den Fachtabellen. Kein CREATE, kein Eigentum, kein Superuser.
Migrationsrolle
Darf Strukturen ändern und ist Eigentümerin der Objekte. Wird nur vom Auslieferungsprozess verwendet, nie von der laufenden Anwendung.
Sicherungsrolle
Darf lesen und Sicherungen anlegen, aber keine Fachdaten ändern und keine Sicherungen löschen.
Administrationsrolle
Superuser beziehungsweise sysadmin. Persönlich zugeordnet, nicht geteilt, und nicht für tägliche Arbeit.
Preis dieser TrennungSie kostet im Störungsfall Zeit und erzeugt mehr Konten, mehr Passwörter und mehr Stellen, an denen etwas ablaufen kann. Wer nachts allein Bereitschaft hat, wechselt dann zwischen Konten, statt zu handeln. Die Trennung ist trotzdem richtig, weil ihr Nutzen genau in dem Moment anfällt, in dem alles andere schon schiefgegangen ist — aber sie ist kein kostenloser Gewinn, und ein Notfallzugang mit dokumentiertem Ausleihverfahren gehört dazu.
Fehlerbild lesen: Anmeldung oder Berechtigung?Identität prüfen, bevor Rechte vergeben werdenEffektive Rechte rechnen: direkt, geerbt, über publicBestand und Zuwachs getrennt regelnErgebnis mit dem betroffenen Konto nachstellen
Identität vor Recht
AbgrenzungVerschlüsselung, Datenklassifikation und der Umgang mit Produktivdaten außerhalb der Produktion stehen im Modul über Datenschutz und Datenhaltung. Wie eine Sicherung konfiguriert und nachgewiesen wird, steht im Modul über Backup und Recovery. Hier ging es nur um die Frage, wer etwas darf — und woher das System das weiß.

Jetzt anwenden

Diesen Stoff gibt es als Modul mit bewerteten Entscheidungs-Checks — dieselbe Einführung, danach die Übungen.

Zum Modul →
Quellen & Aktualität9 Primärquellen · zuletzt geprüft:
  1. 01postgresql.org/docs/current/auth-pg-hba-conf.html
  2. 02postgresql.org/docs/current/database-roles.html
  3. 03postgresql.org/docs/current/role-attributes.html
  4. 04postgresql.org/docs/current/sql-grant.html
  5. 05postgresql.org/docs/current/sql-alterdefaultprivileges.html
  6. 06postgresql.org/docs/current/creating-cluster.html
  7. 07postgresql.org/docs/current/ddl-schemas.html
  8. 08learn.microsoft.com/en-us/sql/relational-datab…pals-database-engine
  9. 09learn.microsoft.com/en-us/sql/sql-server/failo…ned-users-sql-server