feat: implement tenant isolation with PostgreSQL RLS
- users + tenant_memberships tables (tenant-scoped)
- RLS policy on tenant_memberships using set_config('app.current_tenant_id', ...)
- withTenantContext() helper for transaction-scoped tenant context
- separate non-superuser app role (b2bcall_app): the default Docker postgres
user is SUPERUSER and always bypasses RLS even with FORCE, so the app must
never connect through the migration/owner role. Documented in
docs/TENANT_ISOLATION.md.
- automated isolation test proving tenant A never sees tenant B's data
This commit is contained in:
10
TODO.md
10
TODO.md
@@ -19,8 +19,14 @@
|
||||
- [x] Tabela `tenants` criada via migration (seção 29 do agente.md)
|
||||
|
||||
## PHASE 03 — Tenant Isolation
|
||||
- [ ] Tabela `tenants` + RLS
|
||||
- [ ] Tenant context em transação PostgreSQL
|
||||
- [x] Tabelas `users` + `tenant_memberships` (tenant-scoped)
|
||||
- [x] RLS (`ENABLE`/`FORCE ROW LEVEL SECURITY` + policy) em `tenant_memberships`
|
||||
- [x] Tenant context via `set_config('app.current_tenant_id', ..., true)` (transaction-local)
|
||||
- [x] Helper `withTenantContext()` em `packages/database`
|
||||
- [x] Role de banco separado para runtime (`b2bcall_app`, sem SUPERUSER/BYPASSRLS) —
|
||||
achado crítico: o role padrão do Docker Postgres é SUPERUSER e SEMPRE ignora RLS,
|
||||
até com FORCE. Ver `docs/TENANT_ISOLATION.md`.
|
||||
- [x] Teste automatizado de isolamento (`pnpm --filter @b2bcall/database run test:isolation`)
|
||||
|
||||
## PHASE 04 — Authentication / RBAC
|
||||
- [ ] Login (Argon2id), access/refresh tokens
|
||||
|
||||
Reference in New Issue
Block a user