-- Phase 15 (T-15-11, 15-RESEARCH.md Pitfall 4 / Annahme A1) — RLS für -- Group, GroupMembership und ModuleGrant. -- -- Begründung: diese drei Tabellen steuern unmittelbar, wer auf was -- zugreifen darf, und folgen damit dem Muster der Auth-Kerntabellen -- (User, LdapConfig, LdapFieldMapping, PasswordResetToken — siehe -- 20260618112133_rls_policies), NICHT dem App-Layer-Muster der -- Tender*-Tabellen (die bewusst ohne RLS bleiben, D-03). RLS ist hier -- ein zweites Sicherheitsnetz für den Fall, dass irgendwo ein -- `where: { tenantId }` vergessen wird — ModuleAccessService liest über -- unskaliertes `this.prisma`, ohne dass `app.current_tenant` gesetzt -- ist; dieser zweite Netz-Layer greift nur, wenn die Datenbankrolle RLS -- nicht ohnehin umgeht. -- Enable RLS on Group table (direkte tenantId-Spalte) ALTER TABLE "Group" ENABLE ROW LEVEL SECURITY; ALTER TABLE "Group" FORCE ROW LEVEL SECURITY; CREATE POLICY tenant_isolation_policy ON "Group" USING ("tenantId" = current_tenant_id()); -- Enable RLS on GroupMembership table (keine eigene tenantId-Spalte, -- Join-Muster wie PasswordResetToken -> User) ALTER TABLE "GroupMembership" ENABLE ROW LEVEL SECURITY; ALTER TABLE "GroupMembership" FORCE ROW LEVEL SECURITY; CREATE POLICY tenant_isolation_policy ON "GroupMembership" USING ("groupId" IN ( SELECT "id" FROM "Group" WHERE "tenantId" = current_tenant_id() )); -- Enable RLS on ModuleGrant table (direkte tenantId-Spalte) ALTER TABLE "ModuleGrant" ENABLE ROW LEVEL SECURITY; ALTER TABLE "ModuleGrant" FORCE ROW LEVEL SECURITY; CREATE POLICY tenant_isolation_policy ON "ModuleGrant" USING ("tenantId" = current_tenant_id());