Aller au contenu

Supabase anon key vs service role key : ce que chacune ouvre

Voir en MarkdownOuvrir dans ClaudeOuvrir dans ChatGPTOuvrir dans Perplexity

La question est aussi copiée. Si le chat reste vide, collez-la.

En bref

La anon key, désormais appelée publishable key, est faite pour être publique : elle correspond au rôle anon ou authenticated, et vos politiques RLS décident de ce qu’elle voit. La service role key, désormais secret key, correspond à service_role, qui contourne entièrement la RLS. Sur ma table de test locale, avec la RLS activée et sans politique, la clé publique a obtenu 0 ligne et la secret key les 3. Mettez la publishable key dans le navigateur, gardez la secret key sur un serveur, et renouvelez-la si elle a jamais été livrée.

Je suis Denys, ingénieur full-stack et IA. Une secret key divulguée est la première chose que je cherche quand je reprends une application Supabase, car avec elle toutes les autres protections ne sont que décoration. Cet article explique ce que chaque clé ouvre, avec les requêtes que j’ai exécutées pour le vérifier.

Qu’est-ce que la anon key de Supabase ?

La anon key identifie votre application, pas votre utilisateur. Toute requête d’un navigateur ou d’une application mobile la porte, elle doit donc être publique : n’importe qui peut la lire dans le code source de la page. Une requête avec cette seule clé s’exécute avec le rôle Postgres anon. Quand un utilisateur se connecte via Supabase Auth, la même clé voyage avec le jeton de l’utilisateur et la requête s’exécute en tant que authenticated. Vos politiques RLS sont écrites pour ces deux rôles.

Supabase renomme les clés. Le guide des API keys appelle les nouvelles publishable (sb_publishable_…) et secret (sb_secret_…), et abandonne les anciennes clés anon et service_role, basées sur JWT, d’ici fin 2026. Les rôles derrière elles restent les mêmes.

Clé Ancien nom Rôle Postgres La RLS s’applique ? Où la mettre
Publishable sb_publishable_… anon key anon, ou authenticated avec un jeton utilisateur Oui Navigateur, application mobile, tout ce que vous livrez
Secret sb_secret_… service_role key service_role Non, le rôle a BYPASSRLS Serveur, Edge Function, tâche cron uniquement

Peut-on exposer la anon key de Supabase sans risque ?

Oui, si chaque table, vue et fonction qu’elle atteint est protégée. La clé elle-même n’accorde rien de spécial ; les droits et les politiques de votre schéma décident de tout. Je l’ai vérifié sur un stack Supabase local (CLI 2.109.1, Postgres 17.6) avec une table de trois fausses commandes :

Le rôle Postgres que devient chaque clé. Et si vos politiques RLS voient la requête. Publishable key, déconnecté: Publishable key → rôle anon → politiques RLS appliquées; Publishable key, connecté: Publishable key + jeton utilisateur → rôle authenticated → politiques RLS appliquées; Secret key: Secret key → rôle service_role → RLS contournée.
Figure 1. D'après le guide des API keys de Supabase, vérifié sur un stack local, 23 octobre 2026.
État de la table Publishable key Secret key
RLS désactivée Les 3 lignes, et une insertion a renvoyé 201 Created Les 3 lignes
RLS activée, aucune politique [] Les 3 lignes
RLS activée, politique using (true) Les 3 lignes Les 3 lignes
Aucun droit pour anon 42501 permission denied, avec un indice qui nomme le GRANT manquant Les 3 lignes

La publishable key est donc aussi sûre que votre table la plus faible. Une table sans RLS, ou avec une politique qui autorise toutes les lignes, est lisible par quiconque ouvre DevTools. C’est la faille derrière la CVE-2025-48757, où 170 des 1 645 applications vitrines de Lovable servaient des données à la clé publique.

Qu’est-ce que la service role key, et pourquoi est-elle dangereuse ?

La secret key est le passe-partout. Elle s’exécute avec service_role, qui a l’attribut BYPASSRLS : aucune politique que vous écrivez ne s’applique jamais à elle. Dans la dernière colonne du tableau ci-dessus, elle a lu les trois lignes dans tous les états. Le guide de Supabase indique où elle a sa place : serveurs qui font leurs propres contrôles d’autorisation, Edge Functions, tâches de fond et outils d’administration. Deux détails du guide comptent en pratique :

  • La nouvelle secret key refuse les requêtes du navigateur : Supabase examine le User-Agent et renvoie 401. L’ancien JWT service_role n’a pas ce contrôle, une ancienne clé divulguée fonctionne donc de n’importe où. Mon stack local, qui n’a pas ce contrôle de passerelle, a répondu à un script avec la secret key en renvoyant les 3 lignes.
  • Une secret key ne contourne la RLS que si la requête ne porte aucun jeton utilisateur. Avec le jeton d’un utilisateur connecté, la requête s’exécute sous les politiques de cet utilisateur.

Une Edge Function qui utilise la secret key doit vérifier elle-même qui appelle et filtrer elle-même par propriétaire ou par entreprise, car plus rien en dessous ne le fera.

Où trouver les clés ?

Dans le Dashboard, ouvrez la boîte de dialogue Connect de votre projet pour l’URL et la publishable key, ou Settings → API Keys pour toutes les clés, anciennes comprises. En local, supabase start et supabase status affichent une publishable key et une secret key. Gardez-les dans des variables d’environnement : dans Next.js, seule la publishable key peut porter le préfixe NEXT_PUBLIC_, car le bundler livre au navigateur tout ce qui porte ce préfixe.

Que faire si la service role key a fuité ?

Considérez-la comme compromise : chaque ligne de chaque table était lisible et modifiable par celui qui l’a trouvée.

  1. Créez une nouvelle secret key, basculez vos serveurs dessus, puis supprimez celle qui a fuité. Si c’était une ancienne service_role key, la sortie est la migration vers les nouvelles clés : créez une publishable key et une secret key, basculez l’application, puis désactivez les anciennes clés dans Settings → API Keys, où elles restent sinon valides.
  2. Cherchez sb_secret_ et service_role dans le JavaScript compilé et dans l’historique Git. Le scan d’Escape sur 5 600 applications vibe-codées a trouvé plus de 400 secrets exposés, la plupart dans des bundles frontend.
  3. Passez en revue ce qui a changé pendant qu’elle était dehors : nouveaux utilisateurs, changements de rôle, lignes supprimées.

L’audit de sécurité Supabase gratuit ne lit pas votre frontend, mais il lit le côté base de données du même problème : rôles qui contournent la RLS, tables sans RLS, politiques qui autorisent toutes les lignes et colonnes qui semblent sensibles et sont lisibles par les visiteurs anonymes. Pour vérifier ce que votre clé publique atteint en pratique, les étapes sont dans risques de sécurité du vibe coding, et la liste complète que j’applique à une application est dans ma checklist de sécurité d’une application Lovable.

Vous ne savez pas quelle clé votre application livre ?

Je jette volontiers un œil et je compare nos observations. Sans démarchage.

Me contacter

© 2026 Denys Zaichenko. Article original : https://madsalt.tech/fr/blog/supabase-anon-key-vs-service-role-key/