[{"data":1,"prerenderedAt":800},["ShallowReactive",2],{"blog-fr-enable-rls-on-every-supabase-table":3,"blog-index-fr":561},{"id":4,"title":5,"body":6,"category":517,"cover":518,"coverAlt":519,"description":520,"draft":521,"extension":522,"faq":523,"image":539,"keywords":540,"meta":549,"navigation":550,"ogTitle":551,"path":552,"published":553,"seo":554,"stem":555,"tldr":556,"updated":553,"__hash__":560},"blog_fr\u002Fblog\u002Fenable-rls-on-every-supabase-table.md","Activer Row Level Security sur chaque table Supabase, et le prouver",{"type":7,"value":8,"toc":505},"minimark",[9,13,21,26,29,32,39,45,48,52,55,58,69,80,86,89,95,98,114,118,121,127,133,159,165,171,174,180,186,193,275,287,291,294,297,302,305,308,314,318,321,324,327,333,342,345,349,352,358,365,370,391,404,411,415,418,421,433,436,439,451,455,492],[10,11,12],"p",{},"On vous a dit d'activer Row Level Security, ou votre constructeur d'IA l'a\nmentionné en passant pendant qu'il réparait autre chose. Votre projet Supabase\ncontient entre quatre et quarante tables, et vous ne savez pas lesquelles sont\ncouvertes.",[10,14,15,16,20],{},"L'instruction que vous trouvez partout est une ligne de SQL par table, et\njusque-là elle est juste. Ce devant quoi presque tous les guides s'arrêtent,\nc'est l'étape d'après. ",[17,18,19],"strong",{},"Une politique qui existe n'est pas une politique qui\nmarche",", et rien dans votre tableau de bord ne vous montrera la différence.\nActiver Row Level Security dans Supabase, c'est donc trois chantiers et pas un :\nmettre le réglage sur toutes les tables, écrire les deux ou trois politiques qui\nremontent votre app, puis poser à votre propre base la question qu'un inconnu lui\nposerait.",[22,23,25],"h2",{"id":24},"à-quoi-sert-vraiment-row-level-security","À quoi sert vraiment Row Level Security ?",[10,27,28],{},"Il fait consulter vos règles à Postgres avant qu'il ne livre une ligne. Le\nréglage désactivé, il n'y a aucune règle à consulter, donc la réponse à toute\nrequête est : tout.",[10,30,31],{},"Imaginez un bibliothécaire qui va chercher ce que vous demandez. Row Level\nSecurity est la consigne de lire une note à votre sujet avant de remplir le\nchariot. La note, c'est votre politique, et elle peut dire que cette personne\npeut emporter les livres qu'elle a écrits, ou que n'importe qui peut emporter\nn'importe quoi. Avec la consigne en place et aucune note encore écrite, le\nbibliothécaire revient avec un chariot vide et n'explique rien.",[10,33,34,35,38],{},"C'est cette dernière partie qui fait trébucher, et elle décide de ce à quoi\nressemblera un test plus tard. ",[17,36,37],{},"Row Level Security filtre des lignes. Il ne\nrefuse pas des requêtes."," Une table que vous n'avez pas le droit de lire répond\navec une liste vide et un code de succès, pas avec une erreur ni un écran de\nconnexion. On ne dit jamais à votre app qu'elle a été refusée. Elle ne reçoit\nrien, et elle affiche un écran blanc.",[40,41],"diagram",{"alt":42,"caption":43,"src":44},"La même requête dessinée trois fois. Avec l'interrupteur de sécurité éteint, quatre lignes allumées reviennent. Avec l'interrupteur allumé et aucune politique, un emplacement pointillé vide revient. Avec l'interrupteur allumé et une politique de propriété, une seule ligne allumée revient. Les trois retours portent la marque 200.","Une requête, trois réglages, et le même code de succès à chaque fois. Row Level Security change ce qui revient, jamais si la requête a abouti.","\u002Fblog\u002Fenable-rls-on-every-supabase-table\u002Fsame-request-three-answers-1600x780.png",[10,46,47],{},"Mettre le réglage sur un projet où aucune politique n'est encore écrite ne\nverrouille donc pas vos données aux inconnus. Cela verrouille tout le monde,\nvotre propre app comprise, jusqu'à ce que vous disiez qui a le droit de voir\nquoi.",[22,49,51],{"id":50},"comment-activer-rls-sur-toutes-les-tables-supabase-dun-coup","Comment activer RLS sur toutes les tables Supabase d'un coup ?",[10,53,54],{},"Une boucle, exécutée une fois dans l'éditeur SQL. Elle parcourt toutes les tables\nde votre schéma public et met le réglage partout où il est désactivé.",[10,56,57],{},"Commencez par voir où vous en êtes. Ceci liste vos tables et dit si chacune l'a\nen ce moment :",[59,60,65],"pre",{"className":61,"code":63,"language":64},[62],"language-text","select tablename, rowsecurity\nfrom pg_tables\nwhere schemaname = 'public'\norder by tablename;\n","text",[66,67,63],"code",{"__ignoreMap":68},"",[10,70,71,72,75,76,79],{},"Chaque ligne où ",[66,73,74],{},"rowsecurity"," indique ",[66,77,78],{},"false"," est une table qui livre son contenu\nà quiconque détient la clé publiable qui part avec votre app. Si la liste est\ncourte, faites-les une par une et regardez ce qui casse :",[59,81,84],{"className":82,"code":83,"language":64},[62],"alter table public.orders enable row level security;\n",[66,85,83],{"__ignoreMap":68},[10,87,88],{},"Si elle n'est pas courte, ceci s'occupe de tout :",[59,90,93],{"className":91,"code":92,"language":64},[62],"do $$\ndeclare t record;\nbegin\n  for t in\n    select tablename from pg_tables where schemaname = 'public'\n  loop\n    execute format(\n      'alter table public.%I enable row level security', t.tablename\n    );\n  end loop;\nend $$;\n",[66,94,92],{"__ignoreMap":68},[10,96,97],{},"Exécutez ça et votre app devient blanche. Supabase le dit clairement dans sa\npropre documentation : les données deviennent inaccessibles via l'API avec une\nclé publiable tant que des politiques ne sont pas définies. C'est le réglage qui\nfait son travail, et c'est pourquoi la section suivante est celle à garder\nouverte avant d'appuyer sur exécuter.",[99,100,102],"callout",{"type":101},"warn",[10,103,104,107,108,113],{},[17,105,106],{},"Les tables qu'a faites votre constructeur sont celles qui étaient ouvertes.","\nUne table créée en cliquant dans le Table Editor de Supabase arrive avec Row\nLevel Security activé. Une table créée en exécutant du SQL, non, et exécuter du\nSQL est la façon dont Lovable, Bolt, Cursor et v0 créent des tables pour vous.\nLes tables que vous n'avez jamais vues naître sont exactement celles pour\nlesquelles cette boucle existe, et\n",[109,110,112],"a",{"href":111},"\u002Fblog\u002Fsupabase-rls-disabled-in-public","ce que l'alerte \"RLS disabled in public\" attrape et n'attrape pas","\nexplique pourquoi votre tableau de bord a pu rester muet à leur sujet.",[22,115,117],{"id":116},"les-trois-politiques-dont-vous-avez-vraiment-besoin","Les trois politiques dont vous avez vraiment besoin",[10,119,120],{},"Presque toutes les tables d'une app comme la vôtre ont l'une des trois formes :\ndes lignes qui appartiennent à une personne, des lignes que tout le monde peut\nlire, et des lignes que votre app écrit pour un visiteur. Voici chacune, prête à\ncoller et à renommer.",[10,122,123,126],{},[17,124,125],{},"Des lignes qui appartiennent à une personne."," Commandes, messages, éléments\nenregistrés, tout ce qui a un propriétaire.",[59,128,131],{"className":129,"code":130,"language":64},[62],"create policy \"read own orders\"\non public.orders for select\nto authenticated\nusing ( (select auth.uid()) = user_id );\n",[66,132,130],{"__ignoreMap":68},[10,134,135,138,139,142,143,146,147,150,151,154,155,158],{},[66,136,137],{},"auth.uid()"," est l'identifiant de la personne connectée sur cette requête.\n",[66,140,141],{},"user_id"," est la colonne de votre table qui enregistre le propriétaire, alors\nvérifiez le nom avant de lancer : les constructeurs écrivent aussi ",[66,144,145],{},"owner_id",",\n",[66,148,149],{},"profile_id"," et ",[66,152,153],{},"created_by",". La ligne ",[66,156,157],{},"to authenticated"," signifie que la\npolitique n'est même pas envisagée pour un visiteur déconnecté, et c'est ce qui\ngarde la table fermée au public.",[10,160,161,164],{},[17,162,163],{},"Des lignes que tout le monde peut lire."," Un catalogue produits, des articles\npubliés, une carte de lieux.",[59,166,169],{"className":167,"code":168,"language":64},[62],"create policy \"anyone may read products\"\non public.products for select\nto anon, authenticated\nusing ( true );\n",[66,170,168],{"__ignoreMap":68},[10,172,173],{},"Écrivez celle-là délibérément ou pas du tout, parce que c'est aussi la politique\nvers laquelle se tourne un constructeur d'IA dès que vous lui demandez de\nréparer un écran vide. La question à trancher avant : cette table pourrait-elle\nêtre une page de votre site, telle quelle, sans rien en retirer ? Un non veut\ndire qu'elle réclame plutôt la politique de propriété du dessus.",[10,175,176,179],{},[17,177,178],{},"Des lignes que votre app écrit."," Lire et écrire sont des droits distincts\ndans Postgres, donc une table dans laquelle votre app enregistre a besoin d'une\nseconde politique, et celle-ci contrôle la ligne à l'entrée et non à la sortie.",[59,181,184],{"className":182,"code":183,"language":64},[62],"create policy \"insert own orders\"\non public.orders for insert\nto authenticated\nwith check ( (select auth.uid()) = user_id );\n",[66,185,183],{"__ignoreMap":68},[10,187,188,189,192],{},"Quelle clause va où, c'est la partie qui piège, et la ligne ",[66,190,191],{},"update"," porte une\nexigence qui n'a rien d'évident :",[194,195,196,212],"table",{},[197,198,199],"thead",{},[200,201,202,206,209],"tr",{},[203,204,205],"th",{},"Opération",[203,207,208],{},"Clause",[203,210,211],{},"Exige aussi",[213,214,215,230,244,262],"tbody",{},[200,216,217,223,228],{},[218,219,220],"td",{},[66,221,222],{},"select",[218,224,225],{},[66,226,227],{},"using",[218,229],{},[200,231,232,237,242],{},[218,233,234],{},[66,235,236],{},"insert",[218,238,239],{},[66,240,241],{},"with check",[218,243],{},[200,245,246,250,256],{},[218,247,248],{},[66,249,191],{},[218,251,252,150,254],{},[66,253,227],{},[66,255,241],{},[218,257,258,259,261],{},"une politique ",[66,260,222],{}," sur la même table",[200,263,264,269,273],{},[218,265,266],{},[66,267,268],{},"delete",[218,270,271],{},[66,272,227],{},[218,274],{},[10,276,277,278,281,282,286],{},"La documentation de Supabase est explicite sur la dernière : sans politique de\nselect correspondante, un update ne fonctionne pas comme prévu. Et si le message\n",[66,279,280],{},"new row violates row-level security policy"," est ce qui vous a mis en recherche\nau départ, l'écart entre ces deux clauses est\n",[109,283,285],{"href":284},"\u002Fblog\u002Fnew-row-violates-row-level-security-policy","toute cette erreur",".",[22,288,290],{"id":289},"pourquoi-tous-les-exemples-écrivent-select-authuid-et-pas-authuid","Pourquoi tous les exemples écrivent (select auth.uid()) et pas auth.uid()",[10,292,293],{},"Parce que les parenthèses font calculer la valeur à Postgres une fois pour toute\nla requête au lieu d'une fois par ligne examinée.",[10,295,296],{},"La version enveloppée devient ce que Postgres appelle un initPlan : exécuté une\nseule fois, puis réutilisé pour le reste de l'instruction. Sans les parenthèses,\nla fonction est rappelée à la ligne un, à la ligne deux, à la ligne trois, et\nainsi de suite dans une table qui peut en contenir cent mille. Le Performance\nAdvisor de Supabase signale la version sans parenthèses sous une règle nommée\nAuth RLS Initialization Plan, et c'est l'une des entrées qu'on y trouve le plus\nsouvent.",[40,298],{"alt":299,"caption":300,"src":301},"Deux panneaux au-dessus des mêmes huit lignes de table. Dans le panneau de gauche, une marque de fonction se tient à côté de chaque ligne avec son propre trait, huit au total. Dans le panneau de droite, une seule marque de fonction en haut s'ouvre en éventail vers les huit lignes à la fois.","Les parenthèses font toute la différence. À gauche la fonction s'exécute une fois par ligne ; à droite elle s'exécute une fois et la réponse est réutilisée.","\u002Fblog\u002Fenable-rls-on-every-supabase-table\u002Fonce-per-query-1600x620.png",[10,303,304],{},"Une réserve, et elle vient de Supabase : cela marche parce que la réponse ne\nchange pas d'une ligne à l'autre. Une fonction dont le résultat dépend vraiment\nde la ligne qu'elle a devant elle ne peut pas être sortie de la boucle, donc\ncelle-là, laissez-la sans parenthèses.",[10,306,307],{},"Tant que vous y êtes, ajoutez un index sur la colonne que vos politiques\nfiltrent. La politique devient une condition à chaque lecture de cette table,\ndonc sur une table qui contient beaucoup de lignes, une colonne sans index se\nvoit dans vos temps de réponse :",[59,309,312],{"className":310,"code":311,"language":64},[62],"create index orders_user_id_idx on public.orders (user_id);\n",[66,313,311],{"__ignoreMap":68},[22,315,317],{"id":316},"tester-une-politique-sans-fabriquer-un-faux-compte","Tester une politique sans fabriquer un faux compte",[10,319,320],{},"L'éditeur SQL de Supabase peut exécuter une requête comme si un visiteur précis\nl'avait envoyée, ce qui couvre entièrement le cas anonyme.",[10,322,323],{},"L'éditeur porte un contrôle pour le rôle sous lequel une requête doit tourner.\nRéglez-le sur le rôle anonyme, puis lancez un select ordinaire sur la table que\nvous venez de modifier. Ce qui revient est ce que reçoit un inconnu déconnecté.\nPour un visiteur connecté, prenez l'identifiant d'un utilisateur que vous avez\ndéjà au lieu d'en créer un ; n'importe quelle ligne de votre propre table suffit\npour tester.",[10,325,326],{},"Si vous préférez taper que cliquer, la même chose en SQL :",[59,328,331],{"className":329,"code":330,"language":64},[62],"begin;\nset local role anon;\nselect * from public.orders;\nrollback;\n",[66,332,330],{"__ignoreMap":68},[10,334,335,150,338,341],{},[66,336,337],{},"begin",[66,339,340],{},"rollback"," sont là pour que le changement de rôle dure le temps de ce\nbloc et pas davantage, ce qui compte si vous enchaînez plusieurs tables d'affilée.",[10,343,344],{},"Ce que cela vous dit, c'est ce que font vos politiques à l'intérieur de la base.\nCe que cela ne peut pas vous dire, c'est ce que votre projet livre à internet,\nparce que la requête que font vraiment vos visiteurs ne part pas de l'éditeur\nSQL. Elle part d'un navigateur, porte une clé publiable, et arrive par l'adresse\npublique de votre projet.",[22,346,348],{"id":347},"comment-tester-le-rls-supabase-depuis-lextérieur-de-mon-app","Comment tester le RLS Supabase depuis l'extérieur de mon app ?",[10,350,351],{},"Envoyez la requête qu'enverrait un inconnu. Il vous faut deux valeurs et les\ndeux sont déjà dans le code que votre site sert à chaque visiteur : l'URL de\nvotre projet et votre clé publiable.",[59,353,356],{"className":354,"code":355,"language":64},[62],"curl \"https:\u002F\u002FYOUR-PROJECT.supabase.co\u002Frest\u002Fv1\u002Forders?select=*&limit=1\" \\\n  -H \"apikey: YOUR_PUBLISHABLE_KEY\" \\\n  -H \"Authorization: Bearer YOUR_PUBLISHABLE_KEY\"\n",[66,357,355],{"__ignoreMap":68},[10,359,360,361,364],{},"Remplacez le nom de la table une par une et lisez ce qui revient. Une liste\nvide, ",[66,362,363],{},"[]",", veut dire que la politique a tenu pour un visiteur déconnecté. Une\nligne veut dire que quiconque détient une clé partant avec votre app peut lire\ncette table. Une erreur qui mentionne la clé elle-même veut dire que vous avez\ncopié la mauvaise valeur, et cela vaut la peine de l'écarter avant de conclure\nquoi que ce soit.",[40,366],{"alt":367,"caption":368,"src":369},"Une frontière en pointillés autour d'une table de base de données. À l'intérieur, une loupe se tient près de la table avec une courte flèche. À l'extérieur, une personne envoie une flèche qui porte une clé par une brèche dans la frontière, avec le chemin barre rest barre v1 écrit à côté de la brèche, et atteint la même table.","Le test de l'éditeur ne sort jamais du bâtiment. La requête venue de l'extérieur arrive par la même adresse publique que celle qu'utilisent vos visiteurs, avec la même clé que votre app expédie.","\u002Fblog\u002Fenable-rls-on-every-supabase-table\u002Ftwo-tests-one-table-1600x640.png",[10,371,372,373,376,377,380,381,385,386,390],{},"Sur un projet Supabase récent, cette clé commence par ",[66,374,375],{},"sb_publishable_",", et sur\nun plus ancien c'est la clé ",[66,378,379],{},"anon",". L'une comme l'autre s'utilise ainsi sans\nrisque et se trouve sans risque dans votre app, c'est tout leur intérêt ;\n",[109,382,384],{"href":383},"\u002Fblog\u002Fwhich-api-keys-are-safe-in-your-frontend","quelles clés d'API ont leur place dans un frontend","\ntraite de la paire qui n'y a pas la sienne, et\n",[109,387,389],{"href":388},"\u002Fblog\u002Fwhere-to-find-supabase-api-keys","où les trouver dans le tableau de bord","\ndétaille les quatre valeurs de cette page de réglages.",[10,392,393,394,398,399,403],{},"C'est le test qui colle à la réalité, et le passer à grande échelle est la raison\npour laquelle nous savons à quel point l'écart est répandu. Entre le 12 et le\n14 août 2026, nous avons passé neuf vérifications externes sur 30 998 apps en\nproduction publiées depuis Lovable, Base44, Replit, v0 et Bolt. Sur les 3 680\napps adossées à Supabase où la vérification a pu aller au bout, 2 096 ont répondu\nà une requête anonyme avec des lignes d'au moins une table. Cela fait 57 %, et\nc'est une part des apps qui nous ont donné une réponse nette, pas de tout ce que\nnous avons scanné. Le\n",[109,395,397],{"href":396},"\u002Fresearch\u002Fvibe-coded-app-security-2026","jeu de données complet est publié",", et\n",[109,400,402],{"href":401},"\u002Fblog\u002Fcan-anyone-read-your-supabase-database","de quoi ces 57 % sont une part","\ndétaille le décompte.",[10,405,406,407,286],{},"Le faire à la main convient pour quatre tables et devient pénible pour quarante.\nNotre scan gratuit envoie cette requête pour vous, découvre quelles tables\nexistent sans que vous les nommiez, et vous dit lesquelles ont répondu, à côté de\nhuit autres vérifications qu'il fait depuis l'extérieur. Il lit votre site en\nproduction comme n'importe quel visiteur peut le faire, prend environ 20 secondes\net ne demande aucun compte : ",[109,408,410],{"href":409},"\u002Fsecurity-scanner","scanner votre app",[22,412,414],{"id":413},"avant-de-réécrire-des-politiques-sur-une-table-en-production","Avant de réécrire des politiques sur une table en production",[10,416,417],{},"Prenez d'abord une copie de votre base. Vous êtes sur le point de changer les\ndroits sur toutes les tables que vous avez, avec les mêmes outils qui ont produit\nle problème.",[10,419,420],{},"Deux risques distincts méritent d'être séparés, parce qu'un seul concerne le\ntravail d'aujourd'hui. Si une table était lisible et modifiable par n'importe\nqui, la resserrer maintenant ne change rien à ce qui s'est déjà passé, et cette\nversion-là apparaît en général comme un message de support à propos de données\nqui ont changé toutes seules. L'autre risque, c'est la migration elle-même. Une\npolitique supprimée puis recréée légèrement de travers est un mardi ordinaire, et\nle chemin du retour est une copie de l'état d'il y a une heure.",[10,422,423,424,428,429,286],{},"Sur un plan payant Supabase, la copie d'hier soir attend dans la console. Sur le\nplan gratuit, il n'y a rien du tout où retomber, parce que\n",[109,425,427],{"href":426},"\u002Fblog\u002Fdoes-supabase-back-up-my-database","Supabase ne prend aucune sauvegarde automatique sur le plan gratuit",".\nSi c'est votre cas,\n",[109,430,432],{"href":431},"\u002Fblog\u002Fback-up-supabase-free-tier","prenez-en une avant de commencer",[10,434,435],{},"Reeve Care est la version de tout cela dont vous n'avez pas à vous souvenir.\nVotre base Supabase est copiée selon un calendrier, gardée hors de votre compte\nSupabase, chiffrée, et relue pour confirmer qu'elle se restaure avant que la date\naffichée sur votre tableau de bord ne bouge. Les fichiers envoyés par vos\nutilisateurs voyagent avec elle dès que vous connectez une clé Storage, et cette\nclé est demandée à part parce que Supabase n'émet aucune clé en lecture seule\npour les fichiers : celle qui copie vos envois peut aussi écrire, celle qui copie\nvotre base, non. La connecter est facultatif et votre base est sauvegardée dans\nles deux cas. Les sauvegardes ne concernent que Supabase, donc si vos données\nvivent ailleurs nous le disons plutôt que de vous vendre un abonnement qui\nsurveille une boîte vide.",[10,437,438],{},"La restauration est la partie qui compte un jour comme celui-ci. Care copie\nl'état actuel de votre base avant de rejouer la version que vous avez choisie,\ndonc appuyer sur le bouton a lui-même une annulation.",[10,440,441,442,446,447,286],{},"L'autre moitié, c'est la vérification que vous venez de faire à la main. Une\npolitique qui se relâche lors d'une migration plus tardive n'est pas une chose\nque l'on trouve en regardant, alors Care relance la même requête anonyme selon un\ncalendrier et vous prévient quand une table se met à répondre alors qu'elle était\nmuette la semaine dernière. La surveillance de disponibilité et un rapport\nmensuel figurent dans le même abonnement. Rien de tout cela n'écrit vos\npolitiques à votre place, et aucune sauvegarde ne referme une table ouverte. Ce\nqui change, c'est ce que vous coûte une migration qui tourne mal.\n",[109,443,445],{"href":444},"\u002Fsupabase-backups","Ce que Reeve sauvegarde sur Supabase, à quelle fréquence, et ce que fait une restauration","\nparcourt tout le cycle, et les formules sont sur la\n",[109,448,450],{"href":449},"\u002Fpricing","page tarifs",[22,452,454],{"id":453},"lordre-dans-lequel-travailler","L'ordre dans lequel travailler",[456,457,458],"key-takeaways",{},[459,460,461,469,472,479,489],"ul",{},[462,463,464,465,468],"li",{},"Listez vos tables avec ",[66,466,467],{},"select tablename, rowsecurity from pg_tables where schemaname = 'public'"," et voyez combien sont ouvertes avant de changer quoi que ce soit.",[462,470,471],{},"Prenez une sauvegarde, puis activez Row Level Security sur toutes les tables du schéma public. Attendez-vous à ce que votre app devienne blanche ; c'est le réglage qui travaille.",[462,473,474,475,478],{},"Donnez à chaque table l'une des trois politiques. La propriété est le cas normal ; ",[66,476,477],{},"USING (true)"," est une décision que vous prenez table par table, pas un moyen de récupérer les écrans.",[462,480,481,482,485,486,488],{},"Écrivez ",[66,483,484],{},"(select auth.uid())"," et pas ",[66,487,137],{},", et indexez la colonne que vos politiques filtrent.",[462,490,491],{},"Testez chaque table depuis l'extérieur, sans connexion. Une liste vide, c'est réussi. Une ligne, c'est une table que n'importe qui peut lire, quoi qu'en dise votre tableau de bord.",[10,493,494,495,499,500,504],{},"Commencez par la table qui vous gênerait le plus en page publique, et descendez\nà partir de là. La\n",[109,496,498],{"href":497},"\u002Fchecklist","checklist de sécurité en 10 minutes"," couvre cela avec le reste de ce\nqu'il vaut la peine de confirmer sur une app fraîchement lancée, et le\n",[109,501,503],{"href":502},"\u002Fis-your-supabase-app-safe","guide de sécurité Supabase"," passe en revue ce qui a\ntendance à rester ouvert par ailleurs.",{"title":68,"searchDepth":506,"depth":506,"links":507},3,[508,510,511,512,513,514,515,516],{"id":24,"depth":509,"text":25},2,{"id":50,"depth":509,"text":51},{"id":116,"depth":509,"text":117},{"id":289,"depth":509,"text":290},{"id":316,"depth":509,"text":317},{"id":347,"depth":509,"text":348},{"id":413,"depth":509,"text":414},{"id":453,"depth":509,"text":454},"Bases de la sécurité","\u002Fblog\u002Fenable-rls-on-every-supabase-table\u002Fcover-1200x630.png","Une liste de tables de base de données dans un panneau, chacune avec un interrupteur de sécurité à côté, et la plupart encore éteints.","Activer Row Level Security dans Supabase sans politique ferme la table entièrement. Une politique sans le réglage ne fait rien. Voici le SQL, et le test.",false,"md",[524,527,530,533,536],{"q":525,"a":526},"Que se passe-t-il si j'active RLS sans écrire de politique ?","La table cesse de répondre, y compris à votre propre app. Le réglage activé, Postgres consulte vos politiques avant de livrer une ligne, et sans politique il n'y a rien qui puisse dire oui, donc les requêtes reviennent vides. Supabase le documente directement : les données deviennent inaccessibles via l'API avec une clé publiable tant que des politiques ne sont pas définies. Rien n'est supprimé et rien n'est cassé. Écrivez une politique pour les lignes que votre app doit montrer et les écrans reviennent.",{"q":528,"a":529},"Row Level Security ralentit-il mes requêtes ?","Cela peut arriver, et les deux corrections sont petites. Écrivez `(select auth.uid())` dans la condition de la politique, avec les parenthèses, ce qui laisse Postgres calculer la valeur une fois pour toute la requête puis la réutiliser sur chaque ligne. Supabase signale la version sans parenthèses dans son propre Performance Advisor, sous une règle nommée Auth RLS Initialization Plan. Ajoutez ensuite un index sur la colonne que la politique filtre, en général `user_id`. Sur une table de quelques milliers de lignes, vous ne verrez probablement pas la différence. Sur une grande, les deux comptent.",{"q":531,"a":532},"Ai-je besoin de RLS si ma table ne contient aucune donnée personnelle ?","Vous voulez quand même le réglage activé, et la politique peut être la permissive. Une table dont Row Level Security est désactivé est lisible par quiconque détient la clé publiable qui part avec votre app, ce qui convient pour un catalogue produits et beaucoup moins pour tout ce que vous ne publieriez pas sous forme de page. L'activer puis écrire une politique de lecture en `USING (true)` vous donne le même accès public, mais délibérément, et la table se lit comme décidée plutôt que comme oubliée la prochaine fois que quelqu'un parcourt la liste.",{"q":534,"a":535},"Pourquoi mon abonnement realtime a-t-il cessé de fonctionner après l'activation de RLS ?","Parce que Realtime consulte les mêmes politiques avant d'envoyer un changement à un abonné. Une table dont Row Level Security est activé et sans politique de select pour ce visiteur ne livre aucune ligne à une requête et aucun changement à un abonnement, exactement pour la même raison. Ajoutez la politique de select dont cet abonné a besoin et le flux repart. Si vous utilisez Realtime broadcast ou presence plutôt que les changements de base, ceux-là sont autorisés séparément, par des politiques écrites sur la table `realtime.messages`.",{"q":537,"a":538},"Comment tester une politique sans créer un faux utilisateur ?","De deux façons, et aucune ne demande un nouveau compte. L'éditeur SQL de Supabase peut exécuter une requête comme si un rôle précis l'avait envoyée, ce qui couvre entièrement le cas anonyme : ce qui revient est ce que reçoit un inconnu. Pour le cas connecté, il vous faut un identifiant d'utilisateur qui serve de doublure, et n'importe quelle ligne déjà présente dans votre table fait l'affaire. La seconde façon est une requête depuis l'extérieur portant votre clé publiable, qui teste tout le chemin et pas seulement la politique.","\u002Fblog\u002Fenable-rls-on-every-supabase-table\u002Fcard-800x500.png",[541,542,543,544,545,546,547,548],"activer row level security supabase","supabase activer rls","row level security policies supabase","exemple de politique rls supabase","supabase rls select auth.uid","tester rls supabase","supabase rls best practices","auth.uid() policy",{},true,"Activer Row Level Security sur chaque table Supabase","\u002Fblog\u002Fenable-rls-on-every-supabase-table","2026-09-10",{"title":5,"description":520},"blog\u002Fenable-rls-on-every-supabase-table",[557,558,559],"Activer Row Level Security dans Supabase sans politique ferme une table entièrement, et écrire une politique sans activer le réglage ne fait rien du tout. Chaque table a besoin des deux.","Trois formes de politique couvrent presque tout ce que fabrique un constructeur d'IA : les lignes qui appartiennent à une personne, les lignes que tout le monde peut lire, et les lignes que votre app écrit pour un visiteur.","Vérifiez ensuite depuis l'extérieur de votre app, sans connexion, parce que c'est la requête que fait un inconnu, et la seule qui vous dise ce que font vos politiques plutôt que ce qu'elles annoncent.","Kok38lvaAV0zzA3R588wz-88gmNR6tFFsVVGr2lMasQ",[562,569,575,581,587,593,599,605,611,617,623,629,635,641,642,647,653,659,665,671,677,683,689,695,701,706,712,717,722,728,734,740,746,752,758,763,768,774,779,785,790,796],{"path":563,"title":564,"description":565,"published":566,"category":567,"image":568,"draft":521},"\u002Fblog\u002Fsupabase-backup-auth-users","Pourquoi votre dump Supabase ne contient aucun utilisateur","Lancez supabase db dump tout seul et vous obtenez la forme de votre base et aucune de ses lignes, sans le schéma auth où vivent vos utilisateurs.","2026-09-23","Backups","\u002Fblog\u002Fsupabase-backup-auth-users\u002Fcard-800x500.png",{"path":570,"title":571,"description":572,"published":573,"category":517,"image":574,"draft":521},"\u002Fblog\u002Fdomain-and-certificate-expiry","Domaine expiré, site hors ligne : ce qui se passe ensuite","Votre domaine a expiré et votre site est hors ligne. Le compte à rebours qui démarre, pourquoi le certificat est le moindre souci, et comment vérifier les deux.","2026-09-22","\u002Fblog\u002Fdomain-and-certificate-expiry\u002Fcard-800x500.png",{"path":576,"title":577,"description":578,"published":579,"category":517,"image":580,"draft":521},"\u002Fblog\u002Fis-lovable-safe","Lovable est-il sûr ? Ce que 18 554 applications Lovable ont montré","Lovable est-il sûr ? 18 554 applications, neuf vérifications. La plateforme était la plus propre des cinq. Les trouvailles étaient dans les applications.","2026-09-21","\u002Fblog\u002Fis-lovable-safe\u002Fcard-800x500.png",{"path":582,"title":583,"description":584,"published":585,"category":517,"image":586,"draft":521},"\u002Fblog\u002Fvibe-coded-app-security-checklist","La checklist de sécurité du vibe coding, en neuf vérifications","Une checklist de sécurité du vibe coding en neuf points, chacun vérifiable de l’extérieur sur votre appli en ligne, et chacun avec un test d’une ligne.","2026-09-20","\u002Fblog\u002Fvibe-coded-app-security-checklist\u002Fcard-800x500.png",{"path":588,"title":589,"description":590,"published":591,"category":517,"image":592,"draft":521},"\u002Fblog\u002Fstripe-secret-key-in-frontend","Une clé secrète Stripe dans votre frontend peut déplacer de l’argent","Une clé secrète Stripe exposée dans votre frontend peut rembourser, débiter et lire chaque fiche client que vous détenez. Votre clé pk_live_ y a sa place.","2026-09-19","\u002Fblog\u002Fstripe-secret-key-in-frontend\u002Fcard-800x500.png",{"path":594,"title":595,"description":596,"published":597,"category":517,"image":598,"draft":521},"\u002Fblog\u002Fvite-and-next-public-env-vars","Variables d’environnement Vite exposées : le préfixe dit publier","Variables d’environnement Vite exposées : votre appli a fait ce que le préfixe demandait. VITE_ et NEXT_PUBLIC_ veulent dire publier, et l’IA ignorait le prix.","2026-09-18","\u002Fblog\u002Fvite-and-next-public-env-vars\u002Fcard-800x500.png",{"path":600,"title":601,"description":602,"published":603,"category":517,"image":604,"draft":521},"\u002Fblog\u002Fbase44-source-maps","Sécurité Base44 : ce qu’un scan signale, et ce qui dépend de vous","Sécurité Base44 sur 5 438 applis : trois signalements sur presque chacune sont ceux de la plateforme, la source map est le badge Base44, votre part est courte.","2026-09-17","\u002Fblog\u002Fbase44-source-maps\u002Fcard-800x500.png",{"path":606,"title":607,"description":608,"published":609,"category":517,"image":610,"draft":521},"\u002Fblog\u002Fis-cursor-ai-safe","Cursor AI est-il sûr ? L’éditeur, le code et l’appli publiée","Cursor AI est-il sûr ? Trois questions dans une recherche : ce que Cursor garde, ce que son code rate, et si l’appli que vous avez publiée est ouverte.","2026-09-16","\u002Fblog\u002Fis-cursor-ai-safe\u002Fcard-800x500.png",{"path":612,"title":613,"description":614,"published":615,"category":517,"image":616,"draft":521},"\u002Fblog\u002Fis-replit-safe","Replit est-il sûr ? Ce que 3 042 applications Replit nous ont montré","Replit est-il sûr ? 3 042 applications Replit en ligne, neuf vérifications externes. Les trouvailles étaient dans l’application publiée, pas chez l’hébergeur.","2026-09-15","\u002Fblog\u002Fis-replit-safe\u002Fcard-800x500.png",{"path":618,"title":619,"description":620,"published":621,"category":567,"image":622,"draft":521},"\u002Fblog\u002Fsupabase-storage-backup","Supabase storage backup : votre copie de base n'a aucun fichier","Un Supabase storage backup est une tâche à part. Les sauvegardes de la base gardent la liste de vos fichiers et aucun des fichiers, donc chaque upload casse.","2026-09-14","\u002Fblog\u002Fsupabase-storage-backup\u002Fcard-800x500.png",{"path":624,"title":625,"description":626,"published":627,"category":567,"image":628,"draft":521},"\u002Fblog\u002Fsupabase-point-in-time-recovery","Point-in-time recovery Supabase : prix et limites","Le point-in-time recovery de Supabase rembobine votre base à la seconde près sur la dernière semaine. $100 par mois en plus de Pro, et rien que la base.","2026-09-13","\u002Fblog\u002Fsupabase-point-in-time-recovery\u002Fcard-800x500.png",{"path":630,"title":631,"description":632,"published":633,"category":567,"image":634,"draft":521},"\u002Fblog\u002Fsupabase-project-paused-recover","Projet Supabase en pause ? Vos données sont toujours là","Supabase a mis votre projet en pause après une semaine sans activité. Rien n'est supprimé, Restaurer est à côté du nom, et vous avez un an pour cliquer.","2026-09-12","\u002Fblog\u002Fsupabase-project-paused-recover\u002Fcard-800x500.png",{"path":636,"title":637,"description":638,"published":639,"category":517,"image":640,"draft":521},"\u002Fblog\u002Fsafest-ai-app-builder","Quel builder d'app IA est le plus sûr ? 30 998 apps testées","Quel builder d'app IA est le plus sûr ? Nous avons scanné 30 998 apps actives de Lovable, Base44, Replit, v0 et Bolt. Ce n'est pas le builder qui décide.","2026-09-11","\u002Fblog\u002Fsafest-ai-app-builder\u002Fcard-800x500.png",{"path":552,"title":5,"description":520,"published":553,"category":517,"image":539,"draft":521},{"path":111,"title":643,"description":644,"published":645,"category":517,"image":646,"draft":521},"Supabase \"RLS disabled in public\" : ce que l'alerte rate","Supabase signale \"RLS disabled in public\" comme une erreur. Elle ne dit rien de la politique de lecture qui laisse votre table tout aussi ouverte.","2026-09-09","\u002Fblog\u002Fsupabase-rls-disabled-in-public\u002Fcard-800x500.png",{"path":648,"title":649,"description":650,"published":651,"category":517,"image":652,"draft":521},"\u002Fblog\u002Frotate-supabase-service-role-key","Faire tourner une clé service_role Supabase qui a fuité","Supabase dit de colmater la fuite d'abord. D'autres guides disent de faire tourner la clé tout de suite. Tout dépend d'où votre clé service_role a fuité.","2026-09-08","\u002Fblog\u002Frotate-supabase-service-role-key\u002Fcard-800x500.png",{"path":654,"title":655,"description":656,"published":657,"category":517,"image":658,"draft":521},"\u002Fblog\u002Fvibe-coding-security-scanners-compared","Scanners de sécurité vibe coding comparés, le nôtre compris","Le meilleur scanner de sécurité vibe coding tient à trois questions qu'aucune liste de fonctions ne traite. Dix outils comparés, avec les prix.","2026-09-07","\u002Fblog\u002Fvibe-coding-security-scanners-compared\u002Fcard-800x500.png",{"path":660,"title":661,"description":662,"published":663,"category":517,"image":664,"draft":521},"\u002Fblog\u002Fsupabase-security-checker","Supabase security checker : les cinq vérifications à faire soi-même","Un Supabase security checker lit votre app publiée plutôt que les réglages de votre projet. Voici les cinq vérifications, et comment faire chacune vous-même.","2026-09-06","\u002Fblog\u002Fsupabase-security-checker\u002Fcard-800x500.png",{"path":666,"title":667,"description":668,"published":669,"category":517,"image":670,"draft":521},"\u002Fblog\u002Fvibe-coding-security-scanner","Scanner de sécurité vibe coding : ce qu’un scan d’URL rate","Un scanner de sécurité vibe coding lit votre app en ligne depuis l’extérieur. Ce qu’il couvre, les quatre choses qu’il ne voit pas, et comment lire le résultat.","2026-09-05","\u002Fblog\u002Fvibe-coding-security-scanner\u002Fcard-800x500.png",{"path":672,"title":673,"description":674,"published":675,"category":517,"image":676,"draft":521},"\u002Fblog\u002Fmissing-security-headers","En-têtes de sécurité manquants : quand cela compte","Les en-têtes de sécurité manquants sont notre constat le plus fréquent. Contre quoi ils protègent, et quand ils comptent le moins dans votre rapport.","2026-09-04","\u002Fblog\u002Fmissing-security-headers\u002Fcard-800x500.png",{"path":678,"title":679,"description":680,"published":681,"category":517,"image":682,"draft":521},"\u002Fblog\u002Fopenai-api-key-exposed-in-frontend","Votre clé API OpenAI est exposée dans votre frontend. Changez-la.","Une clé API OpenAI exposée dans votre frontend ne peut être liée à aucun domaine. Changez-la aujourd'hui, passez par votre serveur et plafonnez la dépense.","2026-09-03","\u002Fblog\u002Fopenai-api-key-exposed-in-frontend\u002Fcard-800x500.png",{"path":684,"title":685,"description":686,"published":687,"category":517,"image":688,"draft":521},"\u002Fblog\u002Fwhat-secrets-leak-from-vibe-coded-apps","Clé API exposée dans le frontend : ce que 30 998 applis livrent","Une clé API exposée dans votre frontend est le plus souvent une clé Google Maps. Nous avons scanné 30 998 applis vibe-codées et compté ce qui fuit vraiment.","2026-09-02","\u002Fblog\u002Fwhat-secrets-leak-from-vibe-coded-apps\u002Fcard-800x500.png",{"path":690,"title":691,"description":692,"published":693,"category":567,"image":694,"draft":521},"\u002Fblog\u002Fsupabase-backup-tools-compared","Outils de sauvegarde Supabase comparés, le nôtre compris","Quatre familles d'outil de sauvegarde Supabase, ce que chacun copie vraiment, et quand une GitHub Action gratuite bat le fait de payer, nous compris.","2026-09-01","\u002Fblog\u002Fsupabase-backup-tools-compared\u002Fcard-800x500.png",{"path":696,"title":697,"description":698,"published":699,"category":517,"image":700,"draft":521},"\u002Fblog\u002Freplit-secrets-explained","Utiliser les secrets sur Replit, et ce qui est publié quand même","Utiliser les secrets sur Replit : en ajouter un, le relire, corriger les deux causes du undefined. Et les clés que l'outil Secrets ne peut pas protéger.","2026-08-31","\u002Fblog\u002Freplit-secrets-explained\u002Fcard-800x500.png",{"path":431,"title":702,"description":703,"published":704,"category":567,"image":705,"draft":521},"Sauvegardes du plan gratuit Supabase : en faire une sans terminal","Le plan gratuit de Supabase ne fait aucune sauvegarde : la copie vient de vous. Comment la faire depuis le tableau de bord, et ce que le CSV oublie.","2026-08-30","\u002Fblog\u002Fback-up-supabase-free-tier\u002Fcard-800x500.png",{"path":707,"title":708,"description":709,"published":710,"category":517,"image":711,"draft":521},"\u002Fblog\u002Fis-supabase-secure","Supabase est-il sûr ? Oui. Votre projet est une autre question","Supabase est-il sûr ? La plateforme est auditée, chiffrée et testée en intrusion. Sa documentation dit où cela s'arrête et où vos réglages commencent.","2026-08-29","\u002Fblog\u002Fis-supabase-secure\u002Fcard-800x500.png",{"path":388,"title":713,"description":714,"published":715,"category":517,"image":716,"draft":521},"Où trouver vos clés API Supabase : anon, service_role et URL","L'URL du projet, la clé anon et la clé service_role tiennent sur une page du tableau de bord. Voici où elle est, et laquelle des quatre va dans votre app.","2026-08-28","\u002Fblog\u002Fwhere-to-find-supabase-api-keys\u002Fcard-800x500.png",{"path":284,"title":718,"description":719,"published":720,"category":517,"image":721,"draft":521},"New row violates row-level security policy sur Supabase : et après ?","\"New row violates row-level security policy\" signifie que Supabase a refusé une écriture. Le correctif rapide rouvre la table à tout le monde.","2026-08-27","\u002Fblog\u002Fnew-row-violates-row-level-security-policy\u002Fcard-800x500.png",{"path":723,"title":724,"description":725,"published":726,"category":517,"image":727,"draft":521},"\u002Fblog\u002Fcors-wildcard-security-risk","Un joker CORS est-il un risque de sécurité ? Rarement.","Un joker CORS est-il un risque de sécurité ? C'est souvent le réglage par défaut de votre builder, et il ne livre rien que votre serveur ne donnait déjà.","2026-08-26","\u002Fblog\u002Fcors-wildcard-security-risk\u002Fcard-800x500.png",{"path":729,"title":730,"description":731,"published":732,"category":567,"image":733,"draft":521},"\u002Fblog\u002Fsupabase-branching-is-not-a-backup","Le branching Supabase n'est pas une sauvegarde de vos données.","Pourquoi le branching Supabase n'est pas une sauvegarde : une branche démarre sans vos données, et un merge ne déplace que le schéma. À quoi il sert vraiment.","2026-08-25","\u002Fblog\u002Fsupabase-branching-is-not-a-backup\u002Fcard-800x500.png",{"path":735,"title":736,"description":737,"published":738,"category":567,"image":739,"draft":521},"\u002Fblog\u002Fhow-to-restore-a-supabase-backup","Restaurer une sauvegarde Supabase, et ce qui casse après","Restaurer une sauvegarde Supabase depuis le tableau de bord ou un fichier de dump, ce que la restauration remplace et pourquoi votre app peut rester cassée.","2026-08-24","\u002Fblog\u002Fhow-to-restore-a-supabase-backup\u002Fcard-800x500.png",{"path":741,"title":742,"description":743,"published":744,"category":517,"image":745,"draft":521},"\u002Fblog\u002Fsupabase-storage-bucket-public","Votre bucket Supabase Storage est public. Est-ce un problème ?","Un bucket Supabase Storage public signifie que celui qui a l'URL d'un fichier peut l'ouvrir. Il ne signifie pas que quelqu'un peut lister ce qu'il contient.","2026-08-23","\u002Fblog\u002Fsupabase-storage-bucket-public\u002Fcard-800x500.png",{"path":747,"title":748,"description":749,"published":750,"category":517,"image":751,"draft":521},"\u002Fblog\u002Fgoogle-api-key-exposed-in-frontend","Une clé API Google dans votre frontend, est-ce un problème ?","Une clé API Google exposée dans votre frontend est la clé que notre scanner trouve le plus souvent, et en général tout va bien. Un réglage gratuit tranche.","2026-08-22","\u002Fblog\u002Fgoogle-api-key-exposed-in-frontend\u002Fcard-800x500.png",{"path":753,"title":754,"description":755,"published":756,"category":567,"image":757,"draft":521},"\u002Fblog\u002Fai-agent-deleted-my-database","Un agent IA a supprimé mes données Supabase. Que puis-je récupérer ?","Un agent IA a supprimé des données de votre base. Ce que vous pouvez récupérer était déjà décidé avant, et les prochaines minutes décident du reste.","2026-08-21","\u002Fblog\u002Fai-agent-deleted-my-database\u002Fcard-800x500.png",{"path":401,"title":759,"description":760,"published":761,"category":517,"image":762,"draft":521},"Qui peut lire votre base Supabase ? Nous avons testé 3 680 apps","N'importe qui peut-il lire votre base de données Supabase sans se connecter ? Nous avons scanné 30 998 apps en ligne créées avec des builders IA.","2026-08-18","\u002Fblog\u002Fcan-anyone-read-your-supabase-database\u002Fcard-800x500.png",{"path":764,"title":765,"description":766,"published":761,"category":517,"image":767,"draft":521},"\u002Fblog\u002Fsource-maps-exposed-in-production","Source maps exposées : votre app publie son code original","Une source map exposée laisse n'importe qui lire le code original de votre app, commentaires compris. Le test de 30 secondes, et ce qui compte vraiment.","\u002Fblog\u002Fsource-maps-exposed-in-production\u002Fcard-800x500.png",{"path":769,"title":770,"description":771,"published":772,"category":517,"image":773,"draft":521},"\u002Fblog\u002Fsupabase-new-api-keys","Les nouvelles clés API Supabase : laquelle va dans votre app ?","Supabase a remplacé anon et service_role par des clés publiables et secrètes. Laquelle a sa place dans votre app, et laquelle jamais ?","2026-08-12","\u002Fblog\u002Fsupabase-new-api-keys\u002Fcard-800x500.png",{"path":426,"title":775,"description":776,"published":777,"category":567,"image":778,"draft":521},"Supabase sauvegarde-t-il ma base de données ? Cela dépend du plan.","Supabase sauvegarde-t-il votre base de données ? Chaque jour sur les plans payants, jamais sur le gratuit. Comment savoir ce que vous avez vraiment.","2026-08-11","\u002Fblog\u002Fdoes-supabase-back-up-my-database\u002Fcard-800x500.png",{"path":780,"title":781,"description":782,"published":783,"category":517,"image":784,"draft":521},"\u002Fblog\u002Fsupabase-rls-on-but-table-still-public","Supabase Row Level Security est activé. La table reste publique.","Activer Supabase Row Level Security ne protège pas une table. Ce sont vos politiques, et celle qui a réparé votre app laisse peut-être entrer tout le monde.","2026-08-10","\u002Fblog\u002Fsupabase-rls-on-but-table-still-public\u002Fcard-800x500.png",{"path":786,"title":787,"description":788,"published":783,"category":567,"image":789,"draft":521},"\u002Fblog\u002Fversion-history-is-not-a-backup","L'historique des versions n'est pas une sauvegarde de vos données.","Lovable et Bolt tiennent un historique des versions de votre code. Votre base de données est un service à part, et revenir en arrière ne la ramène pas.","\u002Fblog\u002Fversion-history-is-not-a-backup\u002Fcard-800x500.png",{"path":791,"title":792,"description":793,"published":794,"category":567,"image":795,"draft":521},"\u002Fblog\u002Fthree-ways-to-back-up-a-supabase-database","Trois façons de sauvegarder une base Supabase, et ce qui manque","Le tableau de bord, pg_dump et un service géré. Ce que chacun enregistre, ce qu'il laisse de côté sans le dire, et lequel survit à la perte du compte.","2026-08-09","\u002Fblog\u002Fthree-ways-to-back-up-a-supabase-database\u002Fcard-800x500.png",{"path":383,"title":797,"description":798,"published":794,"category":517,"image":799,"draft":521},"Quelles clés API sont sûres côté navigateur, et lesquelles non","Votre clé anon Supabase est faite pour être publique. Votre clé service_role non, et elle ignore toutes les règles que vous posez. Comment les distinguer.","\u002Fblog\u002Fwhich-api-keys-are-safe-in-your-frontend\u002Fcard-800x500.png",1790150953893]