Udostępnij za pośrednictwem


Zabezpieczenia na poziomie wiersza w usłudze Azure Cosmos DB for PostgreSQL

DOTYCZY: Usługa Azure Cosmos DB for PostgreSQL (obsługiwana przez rozszerzenie bazy danych Citus do bazy danych PostgreSQL)

Zasady zabezpieczeń na poziomie wiersza bazy danych PostgreSQL ograniczają użytkowników, którzy mogą modyfikować wiersze tabeli lub uzyskiwać do nich dostęp. Zabezpieczenia na poziomie wiersza mogą być szczególnie przydatne w klastrze wielodostępnym. Umożliwia ona poszczególnym dzierżawom pełny dostęp SQL do bazy danych przy jednoczesnym ukrywaniu informacji poszczególnych dzierżaw z innych dzierżaw.

Implementowanie dla aplikacji wielodostępnych

Możemy zaimplementować rozdzielenie danych dzierżawy przy użyciu konwencji nazewnictwa dla ról bazy danych, które łączą się z zasadami zabezpieczeń na poziomie wiersza tabeli. Przypiszemy każdej dzierżawie rolę bazy danych w sekwencji numerowanej: tenant1, tenant2itp. Dzierżawy będą łączyć się z usługą Azure Cosmos DB for PostgreSQL przy użyciu tych oddzielnych ról. Zasady zabezpieczeń na poziomie wiersza mogą porównać nazwę roli z wartościami w tenant_id kolumnie dystrybucji, aby zdecydować, czy zezwolić na dostęp.

Poniżej przedstawiono sposób stosowania podejścia do uproszczonej tabeli zdarzeń dystrybuowanej przez tenant_idprogram . Najpierw utwórz role tenant1 i tenant2. Następnie uruchom następujące polecenia SQL jako citus użytkownik administratora:

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;

Jak widać, każda osoba z uprawnieniami do wybrania tej tabeli może zobaczyć oba wiersze. Użytkownicy z każdej dzierżawy mogą wyświetlać i aktualizować wiersz innej dzierżawy. Możemy rozwiązać wyciek danych przy użyciu zasad zabezpieczeń tabel na poziomie wiersza.

Każda zasada składa się z dwóch klauzul: USING i WITH CHECK. Gdy użytkownik próbuje odczytać lub zapisać wiersze, baza danych oblicza każdy wiersz względem tych klauzul. Usługa PostgreSQL sprawdza istniejące wiersze tabeli względem wyrażenia określonego w klauzuli USING i wierszy, które zostaną utworzone za pomocą instrukcji INSERT lub UPDATE względem klauzuli WITH CHECK.

-- 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;

Teraz role tenant1 i tenant2 uzyskają różne wyniki dla swoich zapytań:

Połączono jako dzierżawa1:

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

Połączono jako dzierżawa2:

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"
*/

Następne kroki