6 novembre 2026 · 8 min de lecture
Supabase : la Row Level Security expliquée sans jargon (et comment la tester)
Avec Supabase, votre base de données est interrogeable depuis le navigateur avec une clé publique. Seule la Row Level Security (RLS) décide qui peut lire ou modifier quelles lignes. Sans RLS, ou avec une règle trop large, n’importe quel visiteur peut accéder aux données. Elle s’active table par table et se teste avec deux comptes.
Supabase expose votre base PostgreSQL par une API que le navigateur appelle directement. C’est pratique, et c’est ce qui permet à des outils comme Lovable de construire une application sans serveur. La contrepartie : la sécurité ne repose plus sur un serveur que vous contrôlez, mais sur des règles écrites dans la base — la Row Level Security.
Une faille répertoriée en 2025 (CVE-2025-48757) décrit exactement ce cas : des tables d’applications générées avec Lovable étaient lisibles avec la clé publique, faute de règles RLS. Le problème n’était pas la plateforme de base de données, mais l’absence de règle.
Comment ça marche, en trois phrases
La RLS se active par table. Une fois active, aucune ligne n’est accessible tant qu’une règle (« policy ») ne l’autorise pas. Chaque règle précise l’opération (lire, insérer, modifier, supprimer) et une condition, par exemple « la ligne appartient à l’utilisateur connecté ».
-- Activer la RLS sur une table
alter table public.factures enable row level security;
-- Chaque utilisateur ne lit que ses propres factures
create policy "lecture de ses factures"
on public.factures for select
to authenticated
using ( (select auth.uid()) = user_id );
-- Et ne peut créer que des factures à son nom
create policy "création de ses factures"
on public.factures for insert
to authenticated
with check ( (select auth.uid()) = user_id );Les erreurs que nous voyons le plus
RLS jamais activée
La table est créée, l’application fonctionne, personne n’a pensé à activer la protection : tout est ouvert à la clé publique.
Règle « true »
using (true) rend la table lisible par tous. Souvent écrit pour « débloquer » une erreur de permission pendant le développement, puis oublié.
Une règle de lecture, aucune pour la modification
Chaque opération a sa propre règle : protéger select ne protège pas update ni delete.
Rôle ou droit lu dans un champ modifiable
Les métadonnées modifiables par l’utilisateur (user_metadata) ne doivent jamais servir à décider d’un droit : un utilisateur peut les changer lui-même.
Vues et stockage oubliés
Une vue peut contourner les règles de la table sous-jacente selon sa configuration, et les fichiers du stockage ont leurs propres règles, séparées de celles des tables.
Clé service_role dans le navigateur
Elle ignore toutes les règles. Si elle est dans le code client, la RLS ne sert plus à rien.
Comment tester avec deux comptes
Créez deux utilisateurs de test, A et B, puis insérez une ligne avec A. Connecté en B, essayez de la lire, de la modifier et de la supprimer. Essayez aussi sans aucune connexion, avec uniquement la clé publique. Les trois opérations doivent échouer ou ne renvoyer aucune ligne.
# Lecture sans connexion : ne doit renvoyer aucune donnée
curl "https://VOTRE-PROJET.supabase.co/rest/v1/factures?select=*" \
-H "apikey: VOTRE_CLE_PUBLIQUE" \
-H "Authorization: Bearer VOTRE_CLE_PUBLIQUE"Votre check-list RLS
- RLS activée sur toutes les tables du schéma public, sans exception.
- Une règle par opération réellement utilisée, avec une condition de propriété.
- Aucun using (true) hors tables volontairement publiques.
- Aucun droit décidé à partir de user_metadata.
- Règles sur les buckets de stockage et vérification des vues.
- Aucune clé service_role dans le navigateur ni dans une variable publique.
Questions fréquentes
La clé « anon » de Supabase est-elle un secret ?
Non : elle est conçue pour être publique et se trouve dans le code du navigateur. C’est précisément pourquoi les règles RLS sont obligatoires : elles sont la seule barrière entre cette clé et vos données.
Que se passe-t-il si j’active RLS sans écrire de règle ?
Tout accès via l’API publique est refusé pour cette table : c’est le bon défaut. Vous ajoutez ensuite les règles minimales nécessaires, une par type d’opération.
La clé service_role contourne-t-elle RLS ?
Oui, entièrement. Elle ne doit être utilisée que sur un serveur de confiance, jamais dans le navigateur ni dans une variable publique.
Contenu général, non contractuel. Un audit sur périmètre signé reste le seul moyen de prouver l’état de sécurité d’une application.
Voir l’audit de sécurité