-- Script de vérification des politiques RLS -- Date : 16 octobre 2025 -- Objectif : Vérifier que les politiques RLS sont correctement configurées -- 1. Vérifier que RLS est activé sur les tables critiques SELECT schemaname, tablename, rowsecurity AS "RLS Activé" FROM pg_tables WHERE schemaname = 'public' AND tablename IN ('cddu_contracts', 'payslips', 'organizations', 'organization_members') ORDER BY tablename; -- 2. Lister toutes les politiques existantes SELECT schemaname, tablename, policyname AS "Nom de la politique", permissive AS "Permissive", roles AS "Rôles", cmd AS "Commande", qual AS "Condition WHERE" FROM pg_policies WHERE schemaname = 'public' AND tablename IN ('cddu_contracts', 'payslips', 'organizations', 'organization_members') ORDER BY tablename, policyname; -- 3. Vérifier les politiques manquantes critiques -- Ces politiques doivent exister pour sécuriser l'accès -- Pour cddu_contracts : -- - Une politique SELECT pour les clients (accès uniquement à leur org) -- - Une politique UPDATE pour les clients (modification uniquement leur org) -- - Une politique INSERT pour les clients (création uniquement dans leur org) -- - Une politique pour service_role (accès global staff) -- Pour payslips : -- - Une politique SELECT pour les clients (accès uniquement à leur org) -- - Une politique pour service_role (accès global staff) -- 4. Test de sécurité : Essayer d'accéder à toutes les lignes (doit être filtré par RLS) -- ⚠️ À exécuter en tant qu'utilisateur authenticated (pas service_role) -- SELECT COUNT(*) FROM cddu_contracts; -- Doit retourner uniquement les contrats de l'org de l'utilisateur -- SELECT COUNT(*) FROM payslips; -- Doit retourner uniquement les paies de l'org de l'utilisateur -- 5. Recommandations de politiques à créer si absentes : /* -- Politique SELECT pour cddu_contracts (clients) CREATE POLICY "clients_select_own_org_contracts" ON public.cddu_contracts FOR SELECT TO authenticated USING ( org_id IN ( SELECT org_id FROM public.organization_members WHERE user_id = auth.uid() ) ); -- Politique UPDATE pour cddu_contracts (clients) CREATE POLICY "clients_update_own_org_contracts" ON public.cddu_contracts FOR UPDATE TO authenticated USING ( org_id IN ( SELECT org_id FROM public.organization_members WHERE user_id = auth.uid() ) ); -- Politique INSERT pour cddu_contracts (clients) CREATE POLICY "clients_insert_own_org_contracts" ON public.cddu_contracts FOR INSERT TO authenticated WITH CHECK ( org_id IN ( SELECT org_id FROM public.organization_members WHERE user_id = auth.uid() ) ); -- Politique DELETE pour cddu_contracts (clients) CREATE POLICY "clients_delete_own_org_contracts" ON public.cddu_contracts FOR DELETE TO authenticated USING ( org_id IN ( SELECT org_id FROM public.organization_members WHERE user_id = auth.uid() ) ); -- Politique ALL pour service_role (staff avec admin client) CREATE POLICY "service_role_all_access_contracts" ON public.cddu_contracts FOR ALL TO service_role USING (true) WITH CHECK (true); -- Politique SELECT pour payslips (clients) CREATE POLICY "clients_select_own_org_payslips" ON public.payslips FOR SELECT TO authenticated USING ( organization_id IN ( SELECT org_id FROM public.organization_members WHERE user_id = auth.uid() ) ); -- Politique ALL pour service_role (staff) CREATE POLICY "service_role_all_access_payslips" ON public.payslips FOR ALL TO service_role USING (true) WITH CHECK (true); */ -- 6. Vérifier les index pour performance SELECT schemaname, tablename, indexname, indexdef FROM pg_indexes WHERE schemaname = 'public' AND tablename IN ('cddu_contracts', 'payslips', 'organization_members') AND (indexdef LIKE '%org_id%' OR indexdef LIKE '%organization_id%' OR indexdef LIKE '%user_id%') ORDER BY tablename, indexname; -- ✅ Résultat de la vérification (16 octobre 2025) : -- -- cddu_contracts: -- ✅ cddu_contracts_org_id_contract_number_key (UNIQUE sur org_id + contract_number) -- ✅ cddu_contracts_org_idx (INDEX sur org_id) -- -- payslips: -- ✅ idx_payslips_org_month (INDEX sur organization_id + period_month) -- ✅ idx_payslips_organization_id (INDEX sur organization_id) -- -- organization_members: -- ✅ organization_members_pkey (UNIQUE PRIMARY KEY sur org_id + user_id) -- ✅ idx_members_org (INDEX sur org_id) -- ✅ idx_members_user (INDEX sur user_id) -- ✅ idx_om_org_revoked (INDEX sur org_id + revoked) -- ✅ idx_om_org_user (INDEX sur org_id + user_id) -- ✅ idx_om_user (INDEX sur user_id) -- ✅ idx_org_members_org (INDEX sur org_id) -- ✅ idx_org_members_org_revoked (INDEX sur org_id + revoked) -- ✅ idx_org_members_user (INDEX sur user_id) -- ✅ idx_organization_members_org_user (INDEX sur org_id + user_id) -- -- VERDICT : ✅ EXCELLENT -- Tous les index nécessaires sont présents et correctement configurés. -- Les performances des requêtes RLS seront optimales. -- -- Note: Il y a plusieurs index redondants sur organization_members, -- ce qui peut légèrement impacter les performances d'écriture mais garantit -- des performances de lecture optimales pour toutes les requêtes possibles.