Politiques RLS
Politiques Row Level Security par table, stratégies de test et patterns courants.
Qu'est-ce que le RLS
Row Level Security (RLS) est une fonctionnalité PostgreSQL qui restreint les lignes auxquelles un utilisateur peut accéder. Lorsqu'il est activé sur une table, chaque requête est filtrée par des politiques -- même si vous faites un SELECT *, vous n'obtenez que les lignes que vous êtes autorisé à voir.
Dans ScaleRocket, le RLS est la couche d'autorisation principale. La clé anon de Supabase (utilisée par les clients) se connecte avec le rôle anon, qui est restreint par le RLS. La clé service role contourne entièrement le RLS.
Politiques par table
profiles
-- Users can read their own profile
CREATE POLICY "profiles_select_own"
ON profiles FOR SELECT
USING (auth.uid() = id);
-- Users can update their own profile
CREATE POLICY "profiles_update_own"
ON profiles FOR UPDATE
USING (auth.uid() = id)
WITH CHECK (auth.uid() = id);
-- Profile creation handled by trigger (no INSERT policy needed for users)subscriptions
-- Users can read their own subscription
CREATE POLICY "subscriptions_select_own"
ON subscriptions FOR SELECT
USING (auth.uid() = user_id);
-- No INSERT/UPDATE/DELETE for users
-- Managed exclusively by Edge Functions via service rolecredits
-- Users can read their own credit balance
CREATE POLICY "credits_select_own"
ON credits FOR SELECT
USING (auth.uid() = user_id);
-- No INSERT/UPDATE/DELETE for users
-- Managed by Edge Functions and database functions (SECURITY DEFINER)posts (blog)
-- Anyone can read published posts (public blog)
CREATE POLICY "posts_select_published"
ON posts FOR SELECT
USING (published = true);
-- No INSERT/UPDATE/DELETE for regular users
-- Admin panel uses service roleTester les politiques
Via le dashboard Supabase
- Allez dans SQL Editor dans votre dashboard Supabase.
- Exécutez des requêtes en tant qu'utilisateur spécifique :
-- Set the role and user ID for testing
SET request.jwt.claims = '{"sub": "user-uuid-here"}';
SET role = 'authenticated';
-- This should return only the user's own profile
SELECT * FROM profiles;
-- This should return only the user's subscription
SELECT * FROM subscriptions;Via le SDK client
// This query is automatically filtered by RLS
const { data, error } = await supabase
.from("profiles")
.select("*");
// data will only contain the current user's profileVérifier que les politiques bloquent les accès non autorisés
-- As an authenticated user, try to read another user's data
SET request.jwt.claims = '{"sub": "user-a-uuid"}';
SET role = 'authenticated';
SELECT * FROM profiles WHERE id = 'user-b-uuid';
-- Should return 0 rows
UPDATE profiles SET full_name = 'hacked' WHERE id = 'user-b-uuid';
-- Should affect 0 rowsPatterns courants
L'utilisateur possède la ligne
Le pattern le plus courant -- les utilisateurs ne peuvent accéder qu'aux lignes où leur user_id correspond :
CREATE POLICY "user_owns_row"
ON my_table FOR ALL
USING (auth.uid() = user_id)
WITH CHECK (auth.uid() = user_id);Lecture publique, écriture authentifiée
Utile pour le contenu partagé :
-- Anyone can read
CREATE POLICY "public_read"
ON my_table FOR SELECT
USING (true);
-- Only authenticated users can insert their own rows
CREATE POLICY "authenticated_insert"
ON my_table FOR INSERT
WITH CHECK (auth.uid() = user_id);Lecture seule pour les utilisateurs, le service role gère les modifications
Pour les données que les utilisateurs peuvent consulter mais que seul le serveur peut modifier (abonnements, crédits) :
-- Users can read their own
CREATE POLICY "select_own"
ON my_table FOR SELECT
USING (auth.uid() = user_id);
-- No INSERT/UPDATE/DELETE policies
-- Edge Functions use service role to bypass RLSAccès équipe/organisation
Si vous ajoutez des équipes ou des organisations :
CREATE POLICY "team_members_read"
ON team_data FOR SELECT
USING (
EXISTS (
SELECT 1 FROM team_members
WHERE team_members.team_id = team_data.team_id
AND team_members.user_id = auth.uid()
)
);Notes importantes
- Le RLS refuse par défaut. Si aucune politique ne correspond, la requête retourne zéro ligne (SELECT) ou échoue (INSERT/UPDATE/DELETE).
- Activez le RLS sur chaque table. Une table avec le RLS désactivé est accessible à quiconque possède la clé anon.
WITH CHECKest pour les écritures.USINGfiltre quelles lignes peuvent être lues/modifiées.WITH CHECKvalide les nouvelles données lors des INSERT/UPDATE.- Le service role contourne le RLS. C'est intentionnel -- les Edge Functions ont besoin d'un accès non restreint pour gérer les abonnements et les crédits.
- Testez après chaque migration. Vérifiez toujours que les nouvelles tables ont le RLS activé et des politiques appropriées.
-- Quick check: which tables have RLS disabled?
SELECT tablename
FROM pg_tables
WHERE schemaname = 'public'
AND tablename NOT IN (
SELECT tablename FROM pg_tables t
JOIN pg_class c ON c.relname = t.tablename
WHERE c.relrowsecurity = true
);Fini ? Marquez cette page comme terminée.