Row-Level Security
AiHummer este multitenant, iar cea mai puternică graniță de izolare a sa trăiește chiar în baza de date: PostgreSQL Row-Level Security (RLS). Cu RLS activat, baza de date — nu doar codul aplicației — impune ca o interogare să vadă vreodată doar rândurile aparținând chiriașului curent.
De ce RLS
Filtrarea la nivel de aplicație (WHERE tenant_id = ...) este necesară, dar
fragilă: o singură clauză uitată poate scurge date între chiriași. RLS mută
garanția în PostgreSQL, astfel încât chiar și o interogare nefiltrată returnează
doar rândurile chiriașului curent. Este un strat de apărare în profunzime sub
propriul domeniu al aplicației. Pentru modelul de multitenancy mai larg — și cum
se asociază cu efectele secundare idempotente — vezi
Multitenancy și idempotență.
Rolul restricționat (opțional)
RLS este opțional și este activat dând gateway-ului o a doua conexiune de bază de date care folosește un rol restricționat în loc de proprietar:
# /home/.aihummer/etc/gateway.env
# Owner pool — runs migrations, used for system/bypass operations
AIHUMMER_DATABASE_URL=postgres://owner:...@localhost/aihummer
# Restricted application pool — RLS policies apply (aihummer_app role)
AIHUMMER_DB_APP_URL=postgres://aihummer_app:...@localhost/aihummer
Rolul aihummer_app nu este proprietarul tabelei, așa că PostgreSQL îi aplică
politicile RLS. Interogările aplicației curg prin acest pool restricționat. Pentru
instalările native pe gazdă, programul de instalare conectează automat
AIHUMMER_DB_APP_URL.
[!NOTE] Fără
AIHUMMER_DB_APP_URL, gateway-ul folosește pool-ul de proprietar pentru tot, iar RLS nu este efectiv impus. Setează pool-ul restricționat pentru a porni izolarea la nivel de bază de date.
Domeniu per chiriaș
În cadrul unei cereri, aplicația stabilește chiriașul curent pe conexiune înainte
de a rula interogări cu domeniu de chiriaș — conceptual db.WithTenant. Odată
stabilit domeniul, politicile RLS pe rolul restricționat limitează fiecare citire
și scriere la rândurile acelui chiriaș. Domeniul este legat de unitatea de lucru,
astfel încât nu se scurge între cererile concurente.
request ─▶ resolve tenant ─▶ db.WithTenant(tenant) ─▶ queries see only that tenant
Mod de sistem / bypass pentru workeri
O parte din muncă este în mod legitim între chiriași sau agnostică față de chiriaș — workeri de fundal, planificatoare, outbox-ul și mecanisme similare. Pentru acestea, gateway-ul folosește un mod de sistem (bypass) care rulează pe pool-ul de proprietar, în afara politicilor RLS per chiriaș, astfel încât sarcinile de infrastructură să poată opera asupra întregului set de date.
[!WARNING] Modul bypass este doar pentru workeri interni de încredere. Căile de cod care gestionează cereri și acționează în numele unui utilizator trebuie să ruleze întotdeauna prin pool-ul restricționat, cu domeniu de chiriaș — niciodată prin calea de bypass.
Migrările rulează pe pool-ul de proprietar
Schimbările de schemă necesită privilegii pe care rolul restricționat nu le are,
așa că migrările rulează întotdeauna pe pool-ul de proprietar
(AIHUMMER_DATABASE_URL), sub un lock consultativ, la pornire. Rolul restricționat
aihummer_app este folosit doar pentru traficul obișnuit al aplicației. Aceasta
păstrează separarea privilegiilor curată: operațiunile care schimbă schema
folosesc proprietarul; accesul la datele chiriașului folosește rolul restricționat
cu RLS aplicat.
Unde mergi mai departe
- Multitenancy și idempotență — modelul complet de chiriaș și cum rămân efectele secundare sigure sub recuperare.
- Vault de secrete — DEK-urile per chiriaș întăresc aceeași izolare la nivelul secretelor.
- RBAC și chei API cu domeniu — autorizare deasupra stratului de date.