Sicherheit auf Zeilenebene in Azure Cosmos DB for PostgreSQL

GILT FÜR: Azure Cosmos DB for PostgreSQL (unterstützt von der Citus-Datenbankerweiterung auf PostgreSQL)

Mit PostgreSQL-Zeilensicherheitsrichtlinien wird eingeschränkt, welche Benutzer welche Tabellenzeilen ändern oder darauf zugreifen können. Sicherheit auf Zeilenebene kann in einem mehrinstanzenfähigen Cluster besonders nützlich sein. Sie ermöglicht einzelnen Mandanten den vollständigen SQL-Zugriff auf die Datenbank, während die Informationen der einzelnen Mandanten für die anderen Mandanten ausgeblendet werden.

Implementierung für mehrinstanzenfähige Apps

Wir können die Trennung von Mandantendaten mithilfe einer Namenskonvention für Datenbankrollen implementieren, die mit den Richtlinien für die Sicherheit auf Tabellenzeilenebene verknüpft ist. Sie weisen jedem Mandanten eine Datenbankrolle in einer nummerierten Reihenfolge zu: tenant1, tenant2 usw. Die Mandanten stellen unter Verwendung dieser separaten Rollen eine Verbindung mit Azure Cosmos DB for PostgreSQL her. Die Richtlinien für die Sicherheit auf Zeilenebene können den Rollennamen mit Werten in der Verteilungsspalte tenant_id vergleichen, um zu entscheiden, ob der Zugriff gewährt werden soll.

Im Folgenden wird aufgezeigt, wie Sie den Ansatz auf eine vereinfachte, gemäß tenant_id verteilte Ereignistabelle anwenden. Erstellen Sie zunächst die Rollen tenant1 und tenant2. Führen Sie dann die folgenden SQL-Befehle als citus-Administratorbenutzer aus:

CREATE TABLE events(
  tenant_id int,
  id int,
  type text
);

SELECT create_distributed_table('events','tenant_id');

INSERT INTO events VALUES (1,1,'foo'), (2,2,'bar');

-- assumes that roles tenant1 and tenant2 exist
GRANT select, update, insert, delete
  ON events TO tenant1, tenant2;

Derzeit werden jedem Benutzer, der über Berechtigungen zum Auswählen für diese Tabelle verfügt, beide Zeilen angezeigt. Benutzer aus beiden Mandanten können die Zeile des anderen Mandanten anzeigen und aktualisieren. Wir können das Datenleck mit Richtlinien für die Sicherheit auf Tabellenzeilenebene beheben.

Jede Richtlinie besteht aus zwei Klauseln: USING und WITH CHECK. Wenn ein Benutzer versucht, Zeilen zu lesen oder zu schreiben, evaluiert die Datenbank jede Zeile anhand dieser Klauseln. PostgreSQL überprüft vorhandene Tabellenzeilen anhand des in der USING-Klausel angegebenen Ausdrucks und Zeilen, die über INSERT oder UPDATE erstellt würden, anhand der WITH CHECK-Klausel.

-- first a policy for the system admin "citus" user
CREATE POLICY admin_all ON events
  TO citus           -- apply to this role
  USING (true)       -- read any existing row
  WITH CHECK (true); -- insert or update any row

-- next a policy which allows role "tenant<n>" to
-- access rows where tenant_id = <n>
CREATE POLICY user_mod ON events
  USING (current_user = 'tenant' || tenant_id::text);
  -- lack of CHECK means same condition as USING

-- enforce the policies
ALTER TABLE events ENABLE ROW LEVEL SECURITY;

Die Rollen tenant1 und tenant2 erhalten jetzt unterschiedliche Ergebnisse für ihre Abfragen:

Verbunden als „tenant1“:

SELECT * FROM events;
┌───────────┬────┬──────┐
│ tenant_id │ id │ type │
├───────────┼────┼──────┤
│         1 │  1 │ foo  │
└───────────┴────┴──────┘

Verbunden als „tenant2“:

SELECT * FROM events;
┌───────────┬────┬──────┐
│ tenant_id │ id │ type │
├───────────┼────┼──────┤
│         2 │  2 │ bar  │
└───────────┴────┴──────┘
INSERT INTO events VALUES (3,3,'surprise');
/*
ERROR:  new row violates row-level security policy for table "events_102055"
*/

Nächste Schritte