Row Level Security am Beispiel — wer darf welche Zeile sehen?
In einer App mit Konten liegen die Daten aller Nutzer in denselben Tabellen. Row Level Security sorgt dafür, dass jedes Konto nur die eigenen Zeilen bekommt, und zwar in der Datenbank selbst, nicht in der App. Im Simulator siehst du, was die Datenbank je nach Regel herausgibt. Die Regeln stammen aus Habloo, meiner Spanisch-App.
Simulator: Wer sieht welche Zeile?
Die Tabelle enthält Vokabeln von drei Konten. Wähle, wer angemeldet ist und welche Regel gilt. Durchgestrichene Zeilen gibt die Datenbank nicht heraus.
| nutzer_id | wort | übersetzung |
|---|
Was Row Level Security ist.
Row Level Security, kurz RLS, ist eine Funktion von PostgreSQL. Für jede Tabelle legst du Regeln fest, welche Zeilen ein Konto lesen, anlegen, ändern oder löschen darf. Die Datenbank wendet diese Regeln bei jeder Abfrage an, egal woher die Abfrage kommt.
Das ist wichtig, weil eine App direkt mit der Datenbank sprechen kann. Der Schlüssel dafür steckt in jeder ausgelieferten App und lässt sich auslesen. Schützen kann deshalb nur, was in der Datenbank selbst entschieden wird. Eine Prüfung im Code der App hält niemanden auf, der die Abfrage von Hand schickt.
Ist der Schutz eingeschaltet, ist alles verboten, wofür es keine ausdrückliche Erlaubnis gibt. Eine fehlende Regel ist also kein Loch, sondern eine geschlossene Tür.
Drei Regeln aus Habloo.
Habloo hat 20 Tabellen. Drei Muster kommen bei ihren Regeln immer wieder vor.
1. Jeder sieht und ändert nur das Eigene
Das Muster für persönliche Daten wie Vokabeln, Lernfortschritt und Statistik. auth.uid() ist die Kennung des angemeldeten Kontos.
CREATE POLICY "eigene_vokabeln" ON vokabeln
FOR ALL USING (auth.uid() = nutzer_id)
WITH CHECK (auth.uid() = nutzer_id);USING bestimmt, welche Zeilen sichtbar sind. WITH CHECK verhindert, dass jemand eine Zeile unter fremder Kennung anlegt.
2. Lesen ja, schreiben nein
Das Muster für die Abo-Tabelle. Jeder darf das eigene Abo ansehen. Eine Regel zum Schreiben gibt es nicht, und das ist Absicht: So kann sich niemand selbst Premium eintragen, auch nicht über die Konsole des Browsers. Schreiben darf nur der Server, nachdem der Zahlungsanbieter den Kauf bestätigt hat.
CREATE POLICY "eigene_abos_lesen" ON abos
FOR SELECT USING (auth.uid() = nutzer_id);
-- Schreiben: keine Richtlinie. Das ist Absicht.3. Öffentlich lesen
Das Muster für Inhalte, die jeder sehen soll, bei Habloo die Videos der Mediathek. Die Regel gibt nur frei, was als aktiv markiert ist.
CREATE POLICY "bibliothek_oeffentlich_lesen" ON videos
FOR SELECT USING (aktiv = true);Öffentliche Daten ohne Leck.
Eine Rangliste braucht Daten fremder Konten: Benutzername und Punkte. Würde man dafür die Profil-Tabelle freigeben, wäre gleich alles lesbar, was dort steht. Habloo geht deshalb über eine Funktion in der Datenbank. Sie darf intern alles lesen, gibt aber nur vier Spalten zurück.
| In den Tabellen steht | Die Funktion gibt zurück |
|---|---|
| Interne Kennung des Kontos | Platz |
| Benutzername | Benutzername |
| Punkte gesamt und je Tag | Punkte im gewählten Zeitraum |
| Datum der Registrierung | Ob die Zeile das eigene Konto ist |
CREATE OR REPLACE FUNCTION rangliste_zeitraum(zeitraum TEXT DEFAULT 'gesamt', anzahl INT DEFAULT 10)
RETURNS TABLE (platz BIGINT, benutzername TEXT, xp INT, ich BOOLEAN)
LANGUAGE sql
STABLE
SECURITY DEFINER
SET search_path = publicSECURITY DEFINER lässt die Funktion mit den Rechten ihres Besitzers laufen. Die feste Angabe search_path gehört dazu, damit ihr niemand eine andere Tabelle gleichen Namens unterschieben kann.
Typische Fehler.
- Schutz nicht eingeschaltet: Eine neue Tabelle ist offen, bis RLS ausdrücklich eingeschaltet wird. Im Simulator ist das die Einstellung „Schutz ausgeschaltet“.
- WITH CHECK vergessen: Dann kann ein Konto zwar keine fremden Zeilen lesen, aber Zeilen unter fremder Kennung anlegen.
- Der mächtige Schlüssel in der App: Der Schlüssel, mit dem der Server alle Regeln umgeht, darf nie in einer App oder Website stecken.
- Regeln nur in der App: Ein ausgeblendeter Knopf ist kein Schutz. Entscheidend ist, was die Datenbank herausgibt.
- Ganze Tabelle für eine Rangliste freigegeben: Für öffentliche Auszüge ist eine Funktion die bessere Wahl.
So prüfst du es.
- Lege zwei Testkonten an und speichere mit beiden etwas.
- Melde dich mit dem ersten Konto an und frage die Tabelle ohne Filter ab. Es dürfen nur die eigenen Zeilen zurückkommen.
- Versuche, eine Zeile des zweiten Kontos zu ändern. Die Datenbank muss das ablehnen oder null Zeilen ändern.
- Frage die Tabelle ganz ohne Anmeldung ab. Bei persönlichen Daten muss die Antwort leer sein.
Wie die Zugriffsregeln mit Server, Abos und KI zusammenspielen, zeigt der Backend-Baukasten. Die ganze Architektur von Habloo und Davaigo steht auf der Seite Meine Apps.
Wer das schreibt.
Ich bin Manuel Killert, Web- und Softwareentwickler aus Quakenbrück und Dozent für Webentwicklung. Habloo und Davaigo, meine beiden Sprach-Apps im App Store, habe ich vom Server bis zum Store selbst entworfen und gebaut, und ich betreibe sie selbst. Wie sie aufgebaut sind, zeigt die Seite Meine Apps.
Echte Projekte — live ansehen.
WordPress-Websites, die ich gebaut habe oder laufend betreue.

Markenfest
Stärkerer Online-Shop — Webdesign, Content und individuelle Shop-Funktionen.
Website ansehen ↗
KT Bodenteam
Professioneller Auftritt für einen Bodenleger — Vorher-Nachher-Slider und regionale SEO.
Website ansehen ↗
Potassco Solutions
Klare Website für ein KI-Unternehmen, die komplexe Technologie verständlich macht.
Website ansehen ↗FAQ — Row Level Security am Beispiel erklärt.
Was ist Row Level Security?
Eine Funktion von PostgreSQL, mit der du je Tabelle festlegst, welche Zeilen ein Konto lesen, anlegen, ändern oder löschen darf. Die Datenbank prüft das bei jeder Abfrage.
Warum reicht eine Prüfung in der App nicht?
Weil der Schlüssel der App in jeder ausgelieferten App steckt. Wer ihn ausliest, kann die Datenbank direkt abfragen und umgeht jede Prüfung im Code der App.
Was passiert, wenn der Schutz an ist, aber keine Regel existiert?
Dann ist jeder Zugriff verboten. Row Level Security erlaubt nur, was eine Regel ausdrücklich freigibt.
Wie zeigt man eine Rangliste, ohne Daten preiszugeben?
Über eine Funktion in der Datenbank, die nur die nötigen Spalten zurückgibt, zum Beispiel Platz, Benutzername und Punkte, aber keine E-Mail und keine interne Kennung.
Manuel Killert · Webentwickler & DozentErzähl mir von deiner App-Idee.
Beschreib kurz, was die App können soll — du bekommst eine ehrliche Einschätzung zu Bausteinen, Aufwand und Betrieb.
Antwort meist innerhalb von 24 Stunden · hallo@manuelkillert.de