Pourquoi RLS est crucial pour le SaaS

Sans RLS, votre API est la seule barrière entre un utilisateur et chaque ligne de votre base de données. Une requête "fetch all" accidentelle et vous avez une violation de données.

Avec RLS, PostgreSQL applique les règles d'accès au moment de l'exécution de la requête. Peu importe ce qu'envoie votre API, la base de données ne retourne que les lignes que l'utilisateur authentifié est autorisé à voir. C'est la sécurité en profondeur — votre API et votre base de données appliquent indépendamment le contrôle d'accès.

En France, avec le RGPD, une violation de données peut entraîner des amendes pouvant atteindre 4 % du chiffre d'affaires annuel mondial. RLS est votre première ligne de défense technique et un argument solide lors des audits de sécurité.

Activer RLS

Activez RLS sur chaque table orientée utilisateur. Les tables sans politiques RLS sont complètement ouvertes par défaut (si accédées via la clé service role) ou totalement inaccessibles (si accédées via la clé anon sans politiques).

Executez ALTER TABLE projects ENABLE ROW LEVEL SECURITY; dans l'éditeur SQL de Supabase.

Une fois activé, aucune ligne n'est retournée par défaut jusqu'à ce que vous créiez des politiques. C'est la posture de sécurité correcte — fail closed, pas fail open.

Nous recommandons de créer une checklist de démarrage de projet qui inclut "Activer RLS sur chaque nouvelle table" comme étape obligatoire avant la connexion au frontend.

La politique de base : ownership par utilisateur

Le pattern le plus courant — les utilisateurs ne peuvent voir et modifier que leurs propres lignes. Vous créez quatre politiques séparées : une pour SELECT, une pour INSERT, une pour UPDATE, et une pour DELETE. Chacune vérifie que l'auth.uid() de l'utilisateur authentifié correspond au user_id de la ligne.

Pour INSERT, utilisez WITH CHECK plutôt que USING — cela vérifie la valeur insérée, pas une valeur existante.

Ces quatre politiques forment la base de tout système d'ownership. À partir de là, vous pouvez les affiner pour gérer le partage, les rôles, et les accès administrateurs.

Politiques multi-tenant avec workspaces

Pour un SaaS avec des équipes et des workspaces, vérifiez l'appartenance au workspace via une sous-requête dans la politique RLS. La politique vérifie que l'utilisateur courant est membre du workspace associé à la ligne dans la table workspace_members.

Indexez workspace_members(user_id, workspace_id) pour les performances — cette vérification est exécutée sur chaque requête.

Ce pattern est la fondation de tout SaaS B2B multi-tenant : un utilisateur peut être membre de plusieurs workspaces, avec des rôles différents dans chacun, et RLS applique automatiquement les permissions correctes à chaque requête.

Contrôle d'accès basé sur les rôles

Ajoutez la vérification de rôle pour les opérations d'administration. Par exemple, une politique DELETE qui vérifie non seulement que l'utilisateur est membre du workspace, mais aussi qu'il a un rôle 'admin' dans ce workspace.

Stockez les rôles dans votre table workspace_members (role text DEFAULT 'member'). Rôles types : owner, admin, member, viewer.

Soyez précis sur les permissions de rôle dès le début — il est difficile de restreindre les permissions après que les utilisateurs se sont habitués à les avoir. Documentez vos décisions de politique pour chaque table dans un fichier de référence de l'équipe.

Erreurs courantes à éviter

1. Oublier d'activer RLS sur les nouvelles tables. Créez une checklist : chaque nouvelle table reçoit RLS activé avant d'être connectée au frontend.

2. Utiliser la clé service role dans le frontend. La clé service role contourne RLS. Ne l'exposez jamais aux utilisateurs — utilisez la clé anon dans WeWeb/FlutterFlow et la clé service role uniquement dans les fonctions Xano côté serveur.

3. Pas de politique pour INSERT. De nombreux développeurs ajoutent des politiques SELECT et UPDATE mais oublient INSERT. Sans elle, les utilisateurs avec la clé anon ne peuvent pas créer de lignes du tout.

4. Recherches de politique N+1. Si votre politique JOIN une grande table sur chaque requête, vous verrez des problèmes de performance à l'échelle. Matérialisez les vérifications d'appartenance ou utilisez des index agressivement. C'est l'erreur la plus fréquente sur les applications à fort trafic que nous optimisons.