Thème
Politiques RLS
Présentation
Row Level Security (RLS) est un mécanisme de sécurité natif de PostgreSQL qui filtre automatiquement les données selon l'utilisateur authentifié. Toutes les tables de BTP Chantier Pro ont RLS activé.
Principe de fonctionnement
Sans RLS, un utilisateur authentifié pourrait accéder à toutes les données de la base. Avec RLS, chaque requête est automatiquement filtrée selon des règles définies par table.
Le flux est le suivant :
- L'utilisateur envoie une requête avec son JWT
- Supabase vérifie le JWT et identifie l'utilisateur via auth.uid()
- PostgreSQL applique les politiques RLS avant de retourner les données
- Seules les données autorisées sont retournées
Fonction utilitaire
Une fonction utilitaire vérifie si un utilisateur est membre d'une organisation.
CREATE OR REPLACE FUNCTION est_membre_org(p_user_id uuid)
RETURNS boolean AS $$
SELECT EXISTS (
SELECT 1 FROM membres_organisation
WHERE user_id = p_user_id
AND statut = 'actif'
);
$$ LANGUAGE sql SECURITY DEFINER;
Politiques par table
Table chantiers
Un utilisateur accède aux chantiers dont il est propriétaire ou membre de l'organisation.
CREATE POLICY "acces chantiers" ON chantiers
USING (
user_id = auth.uid()
OR est_membre_org(auth.uid())
);
Table employes
CREATE POLICY "acces employes" ON employes
USING (
chantier_id IN (
SELECT id FROM chantiers
WHERE user_id = auth.uid()
OR est_membre_org(auth.uid())
)
);
Table presences
CREATE POLICY "acces presences" ON presences
USING (
chantier_id IN (
SELECT id FROM chantiers
WHERE user_id = auth.uid()
OR est_membre_org(auth.uid())
)
)
WITH CHECK (
chantier_id IN (
SELECT id FROM chantiers
WHERE user_id = auth.uid()
OR est_membre_org(auth.uid())
)
);
Table depenses
CREATE POLICY "acces depenses" ON depenses
USING (
chantier_id IN (
SELECT id FROM chantiers
WHERE user_id = auth.uid()
OR est_membre_org(auth.uid())
)
)
WITH CHECK (
chantier_id IN (
SELECT id FROM chantiers
WHERE user_id = auth.uid()
OR est_membre_org(auth.uid())
)
);
Vérification des politiques
Pour vérifier les politiques actives sur une table :
SELECT policyname, cmd, qual
FROM pg_policies
WHERE tablename = 'nom_de_la_table';
Erreurs courantes
new row violates row-level security policy
Cette erreur apparaît lors d'un INSERT refusé par la politique WITH CHECK. Vérifier que WITH CHECK est bien défini sur la table.
permission denied for table
Les droits GRANT ne sont pas accordés au rôle authenticated. Exécuter :
GRANT ALL ON nom_de_la_table TO authenticated;
Bonnes pratiques
- Toujours définir USING et WITH CHECK pour les tables recevant des insertions
- Tester les politiques avec un compte utilisateur standard
- Ne jamais désactiver RLS sur une table en production
- Documenter chaque nouvelle politique
