-- Row Level Security als zweite Verteidigungslinie (docs/SPEC.md §2). -- Primäre Isolation ist der Tenant-Guard in src/server/db.ts. -- -- Aktivierungsstand: Policies sind definiert; die App verbindet sich aktuell -- noch als Tabellen-Owner (Policies greifen für Owner ohne FORCE nicht). -- Härtungs-Iteration (SPEC §11 Punkt 8): App-Verbindung auf die Rolle -- "isms_app" umstellen und app.tenant_id pro Transaktion setzen — dann sind -- die Policies scharf. FORCE wird bewusst nicht gesetzt, damit Migrationen, -- Seeds und der mandantenübergreifende Login-Lookup als Owner funktionieren. -- Eingeschränkte Anwendungsrolle (für die Härtungs-Iteration) DO $$ BEGIN IF NOT EXISTS (SELECT FROM pg_roles WHERE rolname = 'isms_app') THEN CREATE ROLE isms_app NOLOGIN NOBYPASSRLS; END IF; END $$; GRANT USAGE ON SCHEMA public TO isms_app; GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO isms_app; ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO isms_app; -- RLS auf allen mandanten-gebundenen Tabellen ALTER TABLE "users" ENABLE ROW LEVEL SECURITY; ALTER TABLE "roles" ENABLE ROW LEVEL SECURITY; ALTER TABLE "audit_logs" ENABLE ROW LEVEL SECURITY; -- Isolation: Zugriff nur auf Zeilen des in app.tenant_id gesetzten Mandanten CREATE POLICY tenant_isolation ON "users" USING ("tenant_id" = current_setting('app.tenant_id', true)); CREATE POLICY tenant_isolation ON "roles" USING ("tenant_id" = current_setting('app.tenant_id', true)); CREATE POLICY tenant_isolation ON "audit_logs" USING ("tenant_id" = current_setting('app.tenant_id', true));