Au-delà de la RLS, Supabase permet de gérer des systèmes de rôles sophistiqués (admin, moderateur, user, etc.) en combinant PostgreSQL, les JWT tokens et les policies. Voici comment construire un système de permissions robuste.
Pour le contexte global, consulte notre guide complet Supabase. Pour les bases de la sécurité, lis Supabase RLS : Row Level Security. Pour les tokens JWT, voir Supabase Auth. Pour les migrations de ta table permissions, voir Supabase Migrations.
Les Rôles PostgreSQL dans Supabase
Supabase crée 4 rôles PostgreSQL par défaut :
| Rôle | Description | Usage |
|---|---|---|
anon |
Utilisateurs non connectés | API publique |
authenticated |
Utilisateurs connectés | API sécurisée |
service_role |
Accès complet (bypass RLS) | Backend serveur uniquement |
postgres |
Superuser PostgreSQL | Migrations, administration |
Implémenter un Système de Rôles Applicatifs
Étape 1 : Ajouter un champ rôle au profil
-- Créer un type ENUM pour les rôles
CREATE TYPE user_role AS ENUM ('user', 'moderator', 'admin');
-- Ajouter à la table profiles
ALTER TABLE profiles ADD COLUMN role user_role DEFAULT 'user';
-- Index pour les performances
CREATE INDEX idx_profiles_role ON profiles(role);
Étape 2 : Fonctions helper pour les policies
CREATE OR REPLACE FUNCTION is_admin()
RETURNS BOOLEAN AS $$
SELECT EXISTS (
SELECT 1 FROM profiles
WHERE id = auth.uid() AND role = 'admin'
);
$$ LANGUAGE sql STABLE SECURITY DEFINER;
CREATE OR REPLACE FUNCTION is_moderator_or_above()
RETURNS BOOLEAN AS $$
SELECT EXISTS (
SELECT 1 FROM profiles
WHERE id = auth.uid()
AND role IN ('moderator', 'admin')
);
$$ LANGUAGE sql STABLE SECURITY DEFINER;
Étape 3 : Policies basées sur les rôles
ALTER TABLE comments ENABLE ROW LEVEL SECURITY;
CREATE POLICY "comments_public_read"
ON comments FOR SELECT USING (true);
CREATE POLICY "authenticated_create_comments"
ON comments FOR INSERT
TO authenticated
WITH CHECK (auth.uid() = user_id);
CREATE POLICY "users_or_mods_delete_comments"
ON comments FOR DELETE
TO authenticated
USING (auth.uid() = user_id OR is_moderator_or_above());
Rôles via JWT Claims Personnalisés
CREATE OR REPLACE FUNCTION public.custom_access_token_hook(event JSONB)
RETURNS JSONB AS $$
DECLARE
claims JSONB;
user_role_value user_role;
BEGIN
SELECT role INTO user_role_value
FROM profiles
WHERE id = (event->>'user_id')::UUID;
claims := event->'claims';
claims := jsonb_set(claims, '{user_role}', to_jsonb(user_role_value::TEXT));
RETURN jsonb_set(event, '{claims}', claims);
END;
$$ LANGUAGE plpgsql STABLE SECURITY DEFINER;
Permissions Granulaires avec des Tables de Permissions
CREATE TABLE permissions (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
name TEXT UNIQUE NOT NULL,
description TEXT
);
CREATE TABLE role_permissions (
role user_role NOT NULL,
permission_id UUID REFERENCES permissions(id),
PRIMARY KEY (role, permission_id)
);
Afficher le Rôle côté Frontend
export function useRole() {
const user = useUser()
const [role, setRole] = useState(null)
useEffect(() => {
if (!user) return
supabase
.from('profiles')
.select('role')
.eq('id', user.id)
.single()
.then(({ data }) => setRole(data?.role ?? 'user'))
}, [user])
return {
role,
isAdmin: role === 'admin',
isModerator: role === 'moderator' || role === 'admin',
}
}
👉 Articles du guide Supabase
Cet article fait partie du Guide Complet Supabase 2026. Retrouvez les autres articles :
- ✅ Supabase : Le Guide Complet 2026
- ✅ Supabase vs Firebase : Comparatif Complet 2026
- ✅ Installer Supabase en Local avec Docker
- ✅ Supabase Pricing : Quel Plan Choisir en 2026
- ✅ Architecture Supabase : Postgres, GoTrue, Realtime et Storage
- ✅ Créer et Structurer sa Base de Données Supabase
- ✅ Supabase RLS : Sécuriser ses Données avec Row Level Security
- ✅ Supabase SQL : Triggers, Fonctions et Procédures Stockées
- ✅ Supabase Migrations : Gérer l’Évolution de son Schéma
- ✅ Supabase Auth : Email, OAuth et Magic Links
- 📅 JWT Supabase — à paraître le 18/06
- 📅 Supabase + Next.js — à paraître le 20/06
- 📅 Supabase + React — à paraître le 22/06
- 📅 API REST Supabase — à paraître le 24/06
- 📅 Edge Functions — à paraître le 26/06
- 📅 Realtime Supabase — à paraître le 28/06
- 📅 Storage Supabase — à paraître le 30/06
- 📅 Vector & pgvector — à paraître le 02/07
- 📅 Supabase MCP — à paraître le 04/07
- 📅 Déploiement en production — à paraître le 06/07
- 📅 CLI Supabase — à paraître le 08/07





