PostgreSQL Row-Level Security multi-tenant — a biztos védelem
A "tenantId-t minden query-ben benne lesz" ígéret 12 hónap után elbukik. A PostgreSQL RLS az utolsó védvonal.
A legdrágább bug az, amikor egy ügyfél látja egy másik ügyfél adatát. Az RLS az egyetlen, ami ezt mechanikailag kizárja.
A Netorigo stack és a Consulting OS is multi-tenant SaaS. Minden query-nek tartalmaznia kell a tenantId feltételt. A legtöbb cég ezt az application layer-ben oldja meg — egy middleware vagy service layer automatikusan hozzácsapja. Ez 80%-ban jó. A maradék 20%-ban valaki elfelejti, és egy Acme ügyfél látja a Beta adatát. Ez GDPR incident, trust killer, business ending esemény.
Amit az RLS ad
A PostgreSQL Row-Level Security egy adatbázis szintű szabály: egy adott táblán minden SELECT, UPDATE, DELETE automatikusan szűrve van egy session változó alapján. Ha a session változó SET LOCAL app.tenant_id = "acme", akkor a tenantId = "acme" feltétel automatikusan hozzáadódik minden query-hez. Ha egy mérnök elfelejti a WHERE-ből, nem baj — a PG-motor hozzá fogja adni.
Hogyan állítjuk be
- Minden tenant-scoped táblán ALTER TABLE ... ENABLE ROW LEVEL SECURITY
- CREATE POLICY tenant_isolation ON <tbl> USING (tenant_id = current_setting("app.tenant_id"))
- NestJS interceptor: minden request elején SET LOCAL app.tenant_id = <resolved tenant>
- A szuper-admin szerepkörnek külön BYPASSRLS role — csak audit kontextusban
- Migration tesztek: minden új táblán ellenőrizzük, hogy az RLS be van kapcsolva
A trade-off
Az RLS ~5%-kal lassítja a query-t (a query planner több feltételt kombinál). Ez minimális. A nagyobb gond: a PG connection pool-t tenant-enként kell resetelni, különben a következő request örökli az előző tenant változóját. Ezt egy wrapper service-szel oldjuk meg, ami minden connection-t visszaad a pool-ba SET LOCAL nélkül. Ha valaki ezt elfelejti — máris van egy subtle bug.
A legtöbb SaaS projekt az "RLS overkill"-nek tartja, amíg az első cross-tenant incident megtörténik. Nálunk egyetlen ilyen sem volt, mert a 2. naptól bekapcsoltuk. A javaslat: ne válaszd el. Ha multi-tenant a rendszer, az RLS nem extra biztonság — alapvető követelmény.