Protéger les données de vos clients à la racine avec Supabase
Vos données clients vivent dans une base Supabase, et vous savez qu'il faut les protéger. Mais entre les policies, USING, WITH CHECK et les clés d'API, la moindre hésitation se paie cher : une policy hasardeuse, et c'est une table de données privées laissée en lecture publique, ou une application qui refuse l'accès à ses propres utilisateurs. Le vrai blocage n'est pas le SQL : c'est que vous n'avez jamais posé, en français clair, qui a le droit de quoi.
Cette masterclass vous donne une méthode en cinq étapes pour sécuriser vos tables avec Row Level Security : lister vos tables exposées, écrire vos règles d'accès en français, activer RLS, traduire en policies (une par opération, nommée en clair), puis tester chaque policy à la main. Le SQL devient la traduction mécanique de règles que vous maîtrisez déjà.
Ce que vous saurez faire à la fin
- Écrire vos règles d'accès en français clair, table par table, avant la moindre ligne de SQL.
- Choisir sans hésiter entre USING et WITH CHECK pour chaque opération (SELECT, INSERT, UPDATE, DELETE).
- Tester chaque policy à la main, compte en main, pour vérifier qu'elle fait ce qu'elle promet.
- Niveau membre· le prompt prêt à coller qui traduit vos règles en français en policies RLS, et passe en mode interview si vous partez de zéro.
- Niveau Pro· je relis vos règles et vos policies avec vous, table par table, et je tranche vos cas ambigus en direct.
Cinq étapes, dans cet ordre : le SQL vient en dernier, jamais en premier.
Le français d'abord, le SQL ensuite
La plupart des accidents RLS viennent du même réflexe : ouvrir l'éditeur SQL avant d'avoir décidé qui a le droit de quoi. La méthode inverse l'ordre. Vos règles d'accès s'écrivent d'abord en français clair, table par table, et les policies n'en sont que la traduction : une seule par opération et par table quand c'est possible, pour rester lisible et débogable. Ce qui est ambigu en français le restera en SQL, en pire.
1Lister les tables exposéesdoute : « par où commencer ? »
Listez toutes les tables que votre application expose, par exemple : profils, votes, favoris. Tout ce qui est accessible depuis le client doit figurer sur la liste, avec son nom exact : une table oubliée ici, c'est une table sans règle plus loin. La liste tient en quelques lignes, c'est normal.
2Écrire les règles en français, table par tabledoute : « qui a le droit de quoi ? »
Pour chaque table, écrivez une phrase en français qui répond aux quatre opérations : qui peut lire, créer, modifier, supprimer. Exemple : « profils : un utilisateur voit et modifie uniquement son propre profil ». Si vous ne savez pas formuler la règle en français, aucune policy ne la formulera à votre place. Et c'est ici qu'une règle dangereuse se repère : une table de données privées laissée en lecture publique doit vous arrêter avant d'écrire quoi que ce soit.
3Activer RLS sur chaque table
Sur chaque table de votre liste, activez Row Level Security avec la ligne : alter table ... enable row level security;. Cette ligne précède toujours les policies : c'est elle qui met vos règles en service. Une table de la liste sans cette ligne, c'est une règle écrite mais jamais appliquée.
4Traduire chaque règle en policiesdoute : « USING ou WITH CHECK ? »
Écrivez une policy par opération nécessaire (SELECT, INSERT, UPDATE, DELETE), pas une de plus. La règle de choix : USING filtre l'existant (lecture, modification, suppression), WITH CHECK valide une écriture (création). Identifiez l'utilisateur connecté avec auth.uid(), et n'inventez aucune colonne : si la policy a besoin d'un nom comme user_id, vérifiez qu'il existe vraiment. Enfin, nommez chaque policy en clair, en français, pour pouvoir relire sans deviner ce qu'elle fait.
5Tester à la main, compte en maindoute : « comment savoir si ça marche ? »
Après les policies d'une table, déroulez une courte procédure de test : quel compte utiliser, quel résultat attendre. Une policy non testée est une hypothèse, pas une protection. Et une vérification qui ne se négocie jamais : la clé service_role contourne toutes les policies, elle ne doit jamais vivre côté client.
À vous de jouer : vos règles d'accès en français
Prenez une feuille ou un fichier texte. Tout se passe en français, le SQL viendra après. Cochez à mesure.
Le résultat, en 30 secondes
À partir de votre liste de tables et de vos règles en français, le prompt produit pour chaque table : la règle reformulée en une ligne, le SQL complet (la ligne d'activation RLS, puis les policies nommées et commentées), et le test à la main en deux ou trois lignes.
Table profils. Règle comprise : un utilisateur voit et modifie uniquement son propre profil. SQL : la ligne d'activation RLS, puis une policy de lecture nommée en français, conditionnée sur auth.uid(), et son équivalente pour la modification. Test : connecté avec le compte A, vous voyez le profil A et lui seul ; toute modification du profil B échoue. À la toute fin : une ligne d'avertissement sur la clé service_role.
Le prompt prêt à coller
# RÔLE Vous êtes un ingénieur Postgres et Supabase, spécialiste de Row Level Security, rigoureux et pédagogue. Vous traduisez des règles métier écrites en français clair en policies RLS correctes et sûres. Vous ne vous appuyez QUE sur les règles que je vous donne. Ce qui manque, vous me le demandez, vous ne l'inventez jamais. Quand un cas de sécurité est ambigu, vous signalez le doute au lieu de produire une policy hasardeuse. # CONTEXTE Je sécurise les données de mes clients dans une base Supabase. Je veux des policies RLS correctes, faciles à relire, une seule par opération et par table quand c'est possible. Ma stack utilise `auth.uid()` pour identifier l'utilisateur connecté. Ma matière (si j'en ai) :
Le prompt traduit vos règles écrites en français en policies RLS prêtes à exécuter : une par opération, chacune nommée en clair, livrée avec son SQL d'activation et sa procédure de test à la main. Si vous n'avez pas encore vos règles, il passe en mode interview et vous questionne table par table. Laissez votre email, je vous l'envoie.
Vérifiez que c'est à vous
Vos tables sont protégées : RLS activé, policies propres et testées. Un développeur propose d'embarquer la clé service_role dans le code du navigateur, « puisque les policies protègent tout de toute façon ». Que répondez-vous ?
D'abord avec vos mots, sans regarder les options :
Expliquez-le pour l'ancrer
En une phrase, à un collègue qui découvre Supabase : pourquoi écrire ses règles d'accès en français avant la moindre policy ? Si vous savez le dire simplement, c'est à vous.
Ce que vous savez faire maintenant
- Décrire, table par table et en français, qui peut lire, créer, modifier et supprimer, avant d'écrire du SQL.
- Traduire chaque règle en une policy par opération, nommée en clair, avec la bonne clause : USING pour filtrer l'existant, WITH CHECK pour valider une écriture.
- Vérifier chaque policy par un test à la main, et garder la clé service_role loin du client.
Une policy n'est que la traduction d'une règle que vous savez déjà dire en français.
Faites-le avec moi
Je relis vos règles et vos policies avec vous, table par table, je tranche vos cas ambigus et je vérifie vos tests en direct. Vous arrêtez de croiser les doigts à chaque déploiement.