Was ist zeilenbasierte Sicherheit (RLS)?

Aktualisiert: September 2026

Zeilenbasierte Sicherheit ist ein Datenbankmechanismus, bei dem Policies bei jeder Abfrage filtern, welche Zeilen jemand sehen oder ändern darf. Das mentale Modell ist eine erzwungene, unsichtbare WHERE-Klausel: Die Bedingung, an die Sie sonst in jeder Abfrage denken müssten, wird zu einer Eigenschaft der Tabelle selbst – angewendet von der Engine, auf jedem Zugriffspfad, auch auf denen, die Ihr Anwendungscode nie zu sehen bekommt.

Das Wichtigste in Kürze

FrageAntwort
Was es istZugriffskontrolle pro Zeile, durchgesetzt von der Datenbank-Engine selbst
Das mentale ModellEine WHERE-Klausel, die niemand vergessen kann
Der wichtigste AnwendungsfallMulti-Tenant-Isolation und Daten pro Benutzer, in der Schicht, die ein Angriff nicht überspringen kann
Das KleingedruckteUmgehungsrollen, Default-Deny, Pooling-Kontext – die Fallstricke sind operativer Natur
Der Fehler, den sie verhindertEin vergessener Filter im Anwendungscode = Datenabfluss zwischen Tenants

RLS in zehn Zeilen SQL

CREATE TABLE invoices (
  tenant_id uuid NOT NULL,
  total     numeric(10,2)
);

ALTER TABLE invoices ENABLE ROW LEVEL SECURITY;   -- ab hier: standardmäßig verboten

CREATE POLICY tenant_isolation ON invoices
  USING      (tenant_id = current_setting('app.tenant')::uuid)   -- was Sie lesen dürfen
  WITH CHECK (tenant_id = current_setting('app.tenant')::uuid);  -- was Sie schreiben dürfen

-- Jede Abfrage verhält sich nun so, als endete sie mit WHERE tenant_id = <Ihrer>.
-- Eine Abfrage, die ihren Filter vergisst, liefert nichts – nicht alles.

Dieselbe Garantie existiert in Dokumentdatenbanken als Zugriffskontrolle auf der Zeile selbst – jedes Objekt trägt seine ACL, und die Plattform setzt sie bei jeder Anfrage durch:

// JavaScript / Node.js — Back4app JS SDK
// Row-level security as data: this row is readable by its owner, period
const note = new Parse.Object('Note');
note.set('text', 'Q3 salary planning');
note.setACL(new Parse.ACL(Parse.User.current())); // owner-only, on the row itself
await note.save();

// Later, any query by any user — the row exists only for its owner
const notes = await new Parse.Query('Note').find(); // others never see it

Was die Engine aus einer Abfrage macht

Wie zeilenbasierte Sicherheit eine Abfrage filtertZwei verschiedene Benutzer führen dieselbe Abfrage gegen eine Tabelle aus; die Engine wendet das Prädikat der Policy pro Zeile vor den Bedingungen des Benutzers an, sodass jeder nur die Zeilen erhält, die seine Policy erlaubt.

SELECT * FROM invoices
(dieselbe Abfrage, beliebiger Benutzer)

Policy-Prädikat
pro Zeile, zuerst angewendet

Tenant A sieht nur
Zeilen von Tenant A

Tenant B sieht nur
Zeilen von Tenant B

Zwei verschiedene Benutzer führen dieselbe Abfrage gegen eine Tabelle aus; die Engine wendet das Prädikat der Policy pro Zeile vor den Bedingungen des Benutzers an, sodass jeder nur die Zeilen erhält, die seine Policy erlaubt.

USING vs. WITH CHECK, permissiv vs. restriktiv

KonzeptRegeltFaustregel
USINGWas für Sie existiert: Lesezugriffe und Zeilen, die für Update/Delete infrage kommen”Darf ich es sehen?”
WITH CHECKWas Sie schreiben dürfen: Inserts und die Werte nach einem Update”Darf ich es so anlegen?”
Permissive Policies (Standard)Mit OR verknüpft – ein Treffer genügtZugriff gewähren
Restriktive PoliciesMit AND darübergelegt – alle müssen passenZwingende Grenzen setzen

Zwei Kompositionsregeln aus der PostgreSQL-Referenz lohnen sich zu merken: Wer WITH CHECK weglässt, verwendet USING auch für Schreibzugriffe, und mindestens eine permissive Policy muss passen, bevor die restriktiven überhaupt herangezogen werden – nur restriktive Policies heißt: niemand kommt herein.

Wo RLS unterstützt wird

Engine-FamilieMechanismus
PostgreSQL (9.5+) und DerivateCREATE POLICY – die Referenzimplementierung
SQL Server (2016+)Security-Policies über Inline-Prädikatfunktionen (filter + block)
Verteiltes SQL (CockroachDB, YugabyteDB)PostgreSQL-kompatible Policies
Cloud-Data-WarehousesRow Access Policies, je nach Anbieter unterschiedlich
DokumentdatenbankenNicht policy-basiert – ACLs pro Objekt, durchgesetzt von der Plattformschicht

Die letzte Zeile ist die, um die es in diesem Glossar geht: In Dokumentspeichern ist die Grenze auf Zeilenebene typischerweise ein Datum auf der Zeile (die ACL) statt ein Prädikat in der Engine – dieselbe Garantie, anderer Mechanismus, ausführlich beschrieben im Engineering-Beitrag von Back4app.

Die Fallstricke, endlich an einem Ort

  • Überraschungen durch Default-Deny. RLS ohne Policy zu aktivieren sperrt alle außer dem Eigentümer aus – die Hälfte aller “RLS hat die Produktion lahmgelegt”-Geschichten ist genau das.
  • Die Umgehungsmatrix. Superuser, BYPASSRLS-Rollen und Tabelleneigentümer überspringen Policies – setzen Sie FORCE ROW LEVEL SECURITY, wenn der Eigentümer zugleich der Benutzer der Anwendung ist, und auditieren Sie, wer was hält.
  • Views laufen standardmäßig mit den Rechten ihres Eigentümers – ein View auf eine RLS-Tabelle kann sie still umgehen, sofern er nicht mit den Rechten des Aufrufers erstellt wurde (security_invoker in PostgreSQL).
  • Constraints verraten Existenz. Die Verletzung einer Unique- oder Fremdschlüssel-Constraint kann offenbaren, dass eine unsichtbare Zeile existiert – der dokumentierte verdeckte Kanal; behandeln Sie Eindeutigkeit auf geschützten Werten entsprechend.
  • Fehler können Werte verraten. Gezielt gebaute Ausdrücke, die bei bestimmten Daten fehlschlagen (eine Division durch null, wenn ein verborgener Wert passt), schleusen Informationen über Fehlermeldungen aus – die Klasse von Seitenkanälen, die die SQL-Server-Dokumentation beschreibt.
  • Dumps und Pools haben Modi. Backup-Werkzeuge brauchen unter Umständen die abgeschaltete Zeilensicherheit, um alles zu exportieren; Pooler im Transaktionsmodus brauchen einen transaktionsweiten Kontext (SET LOCAL), sonst färben Tenants von Anfrage zu Anfrage ab.

Performance: Policies sind Code auf dem heißen Pfad

Drei Regeln decken den Großteil der Praxiserfahrung ab: Indizieren Sie jede Spalte, auf die eine Policy verweist (das Prädikat läuft vor den eigenen Filtern Ihrer Abfrage – ohne Index ist es ein voller Table Scan); halten Sie Prädikate frei von Joins, indem Sie das Nachschlagen in Funktionen oder Rollenprüfungen verlagern; und sorgen Sie dafür, dass Funktionen pro Anfrage einmal pro Abfrage ausgewertet werden, nicht einmal pro Zeile, indem Sie sie in eine skalare Unterabfrage kapseln. Sauber gemessen kostet RLS einstellige Prozentwerte; schlecht gemessen ist es die rätselhafte Verlangsamung auf jeder Tabelle, die Sie abgesichert haben.

Typische Anwendungsfälle

  • Multi-Tenant-SaaS. Der kanonische Fall – Tenant-Isolation unterhalb der Anwendung durchgesetzt, dort, wo ein vergessener Filter kein Datenleck werden kann.
  • Daten pro Benutzer. Nachrichten, Dokumente, Gesundheitsakten: Benutzer sehen ihre Zeilen, mehr nicht.
  • Abteilungs- und Regionsgrenzen. Der Vertrieb sieht seine Region; Prüfer sehen alles, nur lesend – Policy-Schichtung in Aktion.
  • Compliance-Anforderungen. Zugriffskontrolle, die sich auf der Datenschicht nachweisen lässt – genau dort, wo Prüfer sie sehen wollen.
  • Geteilter analytischer Zugriff. Analysten fragen Produktionsreplikate direkt ab und sehen nur, was ihre Rolle erlaubt – sicher, weil die Datenbank es durchsetzt, nicht das Dashboard.

Sollten Sie auf Zeilenebene durchsetzen? Entscheidungsmatrix

Mit RLS/ACLs durchsetzen, wenn …Filterung in der Anwendung kann genügen, wenn …
Mehrere Tenants oder Benutzer sich Tabellen teilenDie Datenbank genau einen vertrauenswürdigen Aufrufer hat
Auch anderes als die App die Datenbank berührtKeine BI-Werkzeuge, kein Admin-SQL, kein zweiter Dienst
Ein vergessener Filter ein Leck bedeutet, keinen FehlerDie Eingrenzung Bequemlichkeit ist, keine Sicherheit
Compliance einen Nachweis auf der Datenschicht verlangtDie Daten nicht sensibel sind
Sie die Grenze einmal zentral getestet haben wollenSie es genießen, für immer jede Abfrage zu auditieren

Die ehrliche Zusammenfassung beider Spalten: Behalten Sie die Eingrenzung in der Anwendung, weil sie den Code lesbar hält – und setzen Sie sie trotzdem in der Datenbank durch. Mehrschichtige Verteidigung ist genau der Punkt.

Grenzen und Trade-offs

  • Policies sind von Natur aus unsichtbar – was das Debuggen von “wo sind meine Zeilen hin?” zu einer echten Fertigkeit macht; protokollieren Sie zuerst den Session-Kontext.
  • Komplexe Autorisierung sprengt Prädikate. Regeln, die Workflow-Zustand oder entitätsübergreifende Logik brauchen, gehören in die Autorisierungsschicht der Anwendung, mit RLS als Auffangnetz.
  • Die operative Oberfläche ist real. Umgehungsmatrix, Dump-Modi und Pooling-Kontext sind fortlaufendes Betriebswissen, keine einmalige Einrichtung.
  • Die Auswertung pro Zeile ist eine Steuer – gering, wenn sauber konstruiert, unbegrenzt, wenn nicht.
  • Sie sichert Zeilen, nicht Spalten. Felder zu verbergen ist Sicherheit auf Spaltenebene; kombinieren Sie beides für eine Wirkung auf Zellebene.

Zeilenbasierte Sicherheit mit Back4app

Back4app ist eine Open-Source-Plattform für Backend as a Service (BaaS), die eine verwaltete Datenbank, automatisch generierte REST- und GraphQL-APIs, Authentifizierung, Dateispeicher und Serverless-Funktionen mit Cloud Code kombiniert. Das Modell auf Zeilenebene ist der ACL-als-Daten-Mechanismus aus den Tabs oben: Jedes Objekt trägt seine Zugriffsliste, Rollen bilden Tenants und Teams ab, und die Plattform setzt beides bei jeder Anfrage durch – SDKs, REST, GraphQL und das Dashboard inklusive, mit Klassenberechtigungen als restriktiver Schicht darüber. Es ist die Garantie der erzwungenen WHERE-Klausel, geliefert auf einer Dokumentdatenbank, mit der obigen Fallstrickliste von der Plattform absorbiert statt Ihnen aufgebürdet.

Häufige Fragen

Was ist zeilenbasierte Sicherheit, einfach erklärt?

Eine erzwungene, unsichtbare WHERE-Klausel. Sie hängen Policies an eine Tabelle, und die Datenbank wendet deren Bedingungen automatisch auf jede Abfrage an – jeder Benutzer sieht und ändert nur die Zeilen, die die Policy erlaubt, ganz gleich welche Abfrage er schreibt oder welches Werkzeug er benutzt. Der Filter liegt in der Datenbank, also kann ihn kein Codepfad der Anwendung vergessen.

Wie funktioniert zeilenbasierte Sicherheit?

Sie aktivieren RLS auf einer Tabelle und legen Policies mit booleschen Prädikaten an – die typischerweise die Eigentümer- oder Tenant-Spalte einer Zeile mit dem aktuellen Benutzer oder einer Session-Variablen vergleichen. Zur Abfragezeit wertet die Engine das Prädikat pro Zeile aus, bevor die eigenen Bedingungen des Benutzers greifen, filtert Lesezugriffe und blockiert unerlaubte Schreibzugriffe. Ist RLS einmal ohne Policy aktiviert, gilt standardmäßig: alles verboten.

Was ist der Unterschied zwischen USING und WITH CHECK?

Die Richtung. USING filtert, was für Sie existiert: Zeilen, die für SELECT sichtbar und für UPDATE oder DELETE zugänglich sind. WITH CHECK prüft, was Sie schreiben: einzufügende Zeilen und die neuen Werte nach einem Update. Lassen Sie WITH CHECK weg, gilt das USING-Prädikat für beides – aber Tabellen, in denen Benutzer breit lesen und eng schreiben dürfen, brauchen beide, unterschiedlich definiert.

Wer kann zeilenbasierte Sicherheit umgehen?

In PostgreSQL: Superuser, Rollen mit BYPASSRLS und – der Fall, den alle vergessen – der Eigentümer der Tabelle, sofern Sie nicht FORCE ROW LEVEL SECURITY setzen. Diese Umgehungsmatrix zu auditieren gehört zum Ausrollen von RLS; eine perfekte Policy schützt nichts, wenn die Anwendung sich als Tabelleneigentümer verbindet.

Kostet zeilenbasierte Sicherheit Performance?

Sie kann es – das Prädikat der Policy wird bei jeder Abfrage gegen die Kandidatenzeilen ausgewertet. Die Gegenmaßnahmen sind über alle Produktionserfahrungen hinweg dieselben: Indizieren Sie die Spalten, auf die Ihre Policies verweisen, halten Sie Prädikate frei von Joins (nutzen Sie stattdessen Funktionen oder Rollenprüfungen) und kapseln Sie Funktionen pro Anfrage so, dass sie einmal pro Abfrage statt einmal pro Zeile ausgewertet werden. Eine Policy auf einer nicht indizierten Spalte ist ein Table Scan mit Sicherheitsabzeichen.

Was ist der Unterschied zwischen RLS und Filterung in der Anwendung?

Wo die Grenze liegt. Filterung in der Anwendung grenzt Abfragen im Code ein – flexibel, aber in jedem Codepfad dupliziert und von allem umgangen, was direkt mit der Datenbank spricht. RLS setzt in der Engine durch und deckt jeden Zugriffspfad ab, Admin-Werkzeuge und andere Dienste eingeschlossen. Der Konsens lautet mehrschichtige Verteidigung: in der Anwendung eingrenzen für die Klarheit, in der Datenbank durchsetzen für die Sicherheit.

Wie funktioniert RLS mit Connection Pooling?

Mit Vorsicht. Anwendungen mit Pool verbinden sich als ein einziger Datenbankbenutzer, deshalb stützen sich Policies auf eine Session-Variable pro Anfrage statt auf die Identität der Verbindung – gesetzt beim Entnehmen, gelesen von der Policy, zurückgesetzt bei der Rückgabe. Bei Poolern im Transaktionsmodus muss die Einstellung transaktionsweit gelten, sonst sickert der Kontext eines Tenants in die nächste Anfrage auf derselben Verbindung. Dieses Zusammenspiel ist der häufigste RLS-Fehler im Produktivbetrieb.

Wie testet man Policies für zeilenbasierte Sicherheit?

Schlüpfen Sie in jede Rolle und führen Sie alle vier Operationen aus – select, insert, update, delete – und prüfen Sie sowohl, was erscheint, als auch, was verweigert wird. Ergänzen Sie die beiden vergessenen Fälle: den ungesetzten Kontext (keine gesetzte Tenant-Variable muss keine Zeilen bedeuten, nicht alle) und die Umgehungsmatrix (Eigentümer, Superuser, Replikationspfade). RLS verdient sich Vertrauen durch feindselige Tests, nicht dadurch, dass die Policy sich gut liest.

Verwandte Begriffe

Vergleichen mit

Weiterführende Quellen

Bereit, Ihr Backend zu bauen?

Starten Sie Ihr Projekt auf Back4app in wenigen Minuten — Datenbank, Authentifizierung, APIs und Cloud Code inklusive. Keine Kreditkarte erforderlich.

Geschrieben und geprüft von Back4app Engineering, Back4app Engineering · Veröffentlicht am 2026-09-24