Dela via


Säkerhet på radnivå i Azure Cosmos DB för PostgreSQL

GÄLLER FÖR: Azure Cosmos DB for PostgreSQL (drivs av Citus-databastillägget till PostgreSQL)

PostgreSQL-säkerhetsprinciper på radnivå begränsar vilka användare som kan ändra eller komma åt vilka tabellrader. Säkerhet på radnivå kan vara särskilt användbart i ett kluster med flera klientorganisationer. Det gör att enskilda klienter kan ha fullständig SQL-åtkomst till databasen samtidigt som varje klientorganisations information döljs från andra klienter.

Implementera för appar med flera klientorganisationer

Vi kan implementera separation av klientdata med hjälp av en namngivningskonvention för databasroller som är knutna till säkerhetsprinciper på radnivå i tabeller. Vi tilldelar varje klient en databasroll i en numrerad sekvens: tenant1, tenant2osv. Klienter ansluter till Azure Cosmos DB för PostgreSQL med hjälp av dessa separata roller. Säkerhetsprinciper på radnivå kan jämföra rollnamnet med värden i distributionskolumnen tenant_id för att avgöra om åtkomst ska tillåtas.

Så här tillämpar du metoden på en förenklad händelsetabell som distribueras av tenant_id. Skapa först rollerna tenant1 och tenant2. Kör sedan följande SQL-kommandon som administratörsanvändare citus :

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;

Som det ser ut nu kan alla med valda behörigheter för den här tabellen se båda raderna. Användare från endera klientorganisationen kan se och uppdatera raden för den andra klientorganisationen. Vi kan lösa dataläckan med säkerhetsprinciper för tabeller på radnivå.

Varje princip består av två satser: USING och WITH CHECK. När en användare försöker läsa eller skriva rader utvärderar databasen varje rad mot dessa satser. PostgreSQL kontrollerar befintliga tabellrader mot uttrycket som anges i USING-satsen och rader som skulle skapas via INSERT eller UPDATE mot WITH CHECK-satsen.

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

Nu roller tenant1 och tenant2 få olika resultat för sina frågor:

Ansluten som klient1:

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

Ansluten som klient2:

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ästa steg