Sdílet prostřednictvím


Zabezpečení na úrovni řádků ve službě Azure Cosmos DB for PostgreSQL

PLATÍ PRO: Azure Cosmos DB for PostgreSQL (využívající rozšíření databáze Citus do PostgreSQL)

Zásady zabezpečení na úrovni řádků PostgreSQL omezují, kteří uživatelé můžou upravovat řádky tabulky nebo ke kterým řádkům tabulky přistupovat. Zabezpečení na úrovni řádků může být zvlášť užitečné v clusteru s více tenanty. Umožňuje jednotlivým tenantům mít úplný přístup SQL k databázi a zároveň skrýt informace o jednotlivých tenantech z jiných tenantů.

Implementace pro aplikace s více tenanty

Oddělení dat tenanta můžeme implementovat pomocí konvence vytváření názvů pro databázové role, které jsou propojeny se zásadami zabezpečení na úrovni řádků tabulky. Každému tenantovi přiřadíme roli databáze v číslované sekvenci: tenant1, tenant2atd. Tenanti se připojí ke službě Azure Cosmos DB for PostgreSQL pomocí těchto samostatných rolí. Zásady zabezpečení na úrovni řádků můžou porovnat název role s hodnotami v distribučním tenant_id sloupci a rozhodnout se, jestli chcete povolit přístup.

Tady je postup, jak použít přístup na zjednodušenou tabulku událostí distribuovanou pomocí tenant_id. Nejprve vytvořte role tenant1 a tenant2. Pak jako citus uživatel správce spusťte následující příkazy SQL:

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 je vidět, každý s vybranými oprávněními pro tuto tabulku může zobrazit oba řádky. Uživatelé z libovolného tenanta můžou zobrazit a aktualizovat řádek druhého tenanta. Únik dat můžeme vyřešit pomocí zásad zabezpečení tabulek na úrovni řádků.

Každá zásada se skládá ze dvou klauzulí: USING a WITH CHECK. Když se uživatel pokusí číst nebo zapisovat řádky, databáze vyhodnocuje každý řádek s těmito klauzulemi. PostgreSQL zkontroluje existující řádky tabulky s výrazem zadaným v klauzuli USING a řádky, které by se vytvořily pomocí příkazu INSERT nebo UPDATE pro 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;

Teď role tenant1 a tenant2 získání různých výsledků pro své dotazy:

Připojeno jako tenant1:

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

Připojeno jako 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"
*/

Další kroky