[{"data":1,"prerenderedAt":1129},["ShallowReactive",2],{"blog-fr-supabase-invalid-jwt":3,"blog-index-fr":603},{"id":4,"title":5,"body":6,"category":561,"cover":562,"coverAlt":563,"description":564,"draft":565,"extension":566,"faq":567,"image":583,"keywords":584,"meta":592,"navigation":593,"ogTitle":5,"path":594,"published":595,"seo":596,"stem":597,"tldr":598,"updated":595,"__hash__":602},"blog_fr\u002Fblog\u002Fsupabase-invalid-jwt.md","Supabase invalid JWT : quelle clé a cessé de marcher ?",{"type":7,"value":8,"toc":548},"minimark",[9,13,24,27,39,44,47,50,53,56,62,66,73,87,167,172,179,200,207,211,221,233,236,262,267,270,282,293,297,300,312,328,332,335,367,371,374,396,399,406,410,413,429,432,440,443,447,453,462,476,486,503,507,536],[10,11,12],"p",{},"Hier votre application marchait. Ce matin chaque requête revient en 401, rien\nn'a changé dans votre code, et la réponse parle d'un JWT, une chose que vous\nn'avez jamais tapée nulle part.",[14,15,20],"pre",{"className":16,"code":18,"language":19},[17],"language-text","{\n  \"code\": \"PGRST301\",\n  \"message\": \"JWT cryptographic operation failed\"\n}\n","text",[21,22,18],"code",{"__ignoreMap":23},"",[10,25,26],{},"Une erreur Supabase invalid JWT est celle qui arrive après que vous avez fait ce\nqu'il fallait. Vous avez changé une clé parce qu'un guide vous l'a conseillé, ou\nvous avez fait passer votre projet aux nouvelles clés, et l'application s'est\ntue.",[10,28,29,30,34,35,38],{},"Et voici ce que guide après guide se trompe : ",[31,32,33],"strong",{},"la clé dont parle ce message\nn'est souvent pas celle que vous venez de changer."," Cherchez l'erreur et on vous\nrenverra vers votre clé ",[21,36,37],{},"anon",". Sur un projet passé aux clés publishable et\nsecret, la clé API n'est pas du tout un jeton signé, donc ce qui a échoué à la\nvérification était autre chose dans la requête.",[40,41,43],"h2",{"id":42},"que-signifie-une-erreur-supabase-invalid-jwt","Que signifie une erreur Supabase invalid JWT ?",[10,45,46],{},"Quelque chose dans votre requête était un jeton signé, et la signature ne\ncorrespondait pas.",[10,48,49],{},"Un mot de passe est un mot que quelqu'un cherche dans une liste. Un JWT, non.\nC'est une lettre fermée par un sceau de cire : la personne à la porte ne vous\ncherche nulle part, elle tient un cachet et vérifie si le sceau de votre lettre a\nété fait avec. Si oui, vous passez, et personne ne lit de liste.",[10,51,52],{},"Une lettre scellée avec le mauvais cachet est refusée alors que chaque mot à\nl'intérieur est correct. Et dès que la porte change de cachet, plus aucune lettre\ndéjà partie ne s'ouvre, sans que personne ait touché aux lettres.",[10,54,55],{},"Votre requête est la lettre. Votre projet Supabase tient le cachet. Un 401 ici\nveut dire que les deux ne concordaient pas.",[57,58],"diagram",{"alt":59,"caption":60,"src":61},"Deux voies amenant chacune une lettre scellée au même cachet, gravé d'une marque à trois branches. En haut, le sceau de la lettre porte la même marque, la lettre passe, la table derrière montre trois lignes éclairées et la réponse est 200. En bas, le sceau porte un point dans un carré, une barre ambre arrête la lettre, la table derrière est un contour pointillé vide et la réponse est 401.","Rien n'est cherché dans une liste. Le sceau du jeton est comparé au cachet que détient votre projet, et une lettre dont le sceau vient d'ailleurs est refusée quel que soit son contenu.","\u002Fblog\u002Fsupabase-invalid-jwt\u002Fhow-the-check-works-1600x660.png",[40,63,65],{"id":64},"le-message-a-changé-dans-postgrest-13-le-code-non","Le message a changé dans PostgREST 13, le code non",[10,67,68,69,72],{},"Faites votre test sur ",[21,70,71],{},"PGRST301",". La phrase qui l'accompagne dépend de la version\nde PostgREST que fait tourner votre projet, et les plus récentes vous en donnent\nune courte liste.",[10,74,75,76,78,79,82,83,86],{},"La référence des erreurs de PostgREST décrit ",[21,77,71],{}," comme un JWT fourni qui\nn'a pas pu être décodé ou qui est invalide, en HTTP 401, aussi bien en version 13\nqu'en version 14. Cette phrase est la description du tableau de documentation.\nCe n'est pas ce qui arrive dans votre champ ",[21,80,81],{},"message",". D'après ",[21,84,85],{},"Error.hs"," sur la\nbranche main de PostgREST, ce champ porte l'une de ces phrases :",[88,89,90,103],"table",{},[91,92,93],"thead",{},[94,95,96,100],"tr",{},[97,98,99],"th",{},"Ce que dit le message",[97,101,102],{},"Ce que cela vous apprend",[104,105,106,117,127,137,147,157],"tbody",{},[94,107,108,114],{},[109,110,111],"td",{},[21,112,113],{},"Empty JWT is sent in Authorization header",[109,115,116],{},"L'en-tête a bien été envoyé et il était vide.",[94,118,119,124],{},[109,120,121],{},[21,122,123],{},"Expected 3 parts in JWT; got 1",[109,125,126],{},"Ce qui est arrivé n'est pas un JWT. Un JWT fait trois blocs séparés par des points.",[94,128,129,134],{},[109,130,131],{},[21,132,133],{},"No suitable key or wrong key type",[109,135,136],{},"Le serveur n'a aucune clé capable de vérifier un jeton de ce type.",[94,138,139,144],{},[109,140,141],{},[21,142,143],{},"Wrong or unsupported encoding algorithm",[109,145,146],{},"Le jeton annonce un algorithme de signature que le serveur n'utilise pas.",[94,148,149,154],{},[109,150,151],{},[21,152,153],{},"JWT cryptographic operation failed",[109,155,156],{},"Le jeton est bien formé et la signature ne correspond pas.",[94,158,159,164],{},[109,160,161],{},[21,162,163],{},"Unsupported token type",[109,165,166],{},"Le jeton a une forme que PostgREST ne lit pas.",[10,168,169,171],{},[21,170,153],{}," est celui qui veut dire clé périmée. Le\njeton a été construit correctement et signé par quelque chose que le projet ne\ndétient plus, ce qui est exactement ce qu'une rotation laisse derrière elle.",[10,173,174,175,178],{},"Les projets plus anciens voient tout autre chose, et c'est de là que vient la\nchaîne que l'on retrouve partout dans les résultats de recherche. Avant la\nversion 13, PostgREST affichait ce que sa bibliothèque JWT avait dit,\nexactement comme elle l'avait dit. D'où ",[21,176,177],{},"JWSError JWSInvalidSignature"," : c'est\nune valeur de bibliothèque affichée telle quelle, pas une phrase écrite pour\nvous. Le changelog de PostgREST pour la 13.0.0 décrit ce changement comme des\nmessages d'erreur diagnostiques à la place d'internes exposés.",[180,181,183],"callout",{"type":182},"warn",[10,184,185,188,189,192,193,195,196,199],{},[31,186,187],{},"Si votre propre code teste le texte du message, testez le code à la place."," Une\ncomparaison de ",[21,190,191],{},"error.message"," avec ",[21,194,177],{}," marche\naujourd'hui et cesse de marcher le jour où votre projet passe à un PostgREST plus\nrécent, sans aucun déploiement de votre part entre les deux. Supabase dit la même\nchose dans sa propre documentation des erreurs : utilisez ",[21,197,198],{},"error.code"," et ne\ncomparez pas les messages d'erreur comme du texte.",[10,201,202,203,206],{},"Un code voisin mérite d'être connu au passage. ",[21,204,205],{},"PGRST303",", également en 401, est\nce que vous obtenez quand la signature a été vérifiée et que le contenu du jeton\na été refusé : expiré, pas encore valide, ou portant la mauvaise audience. Si\nc'est votre code, arrêtez de regarder vos clés et allez regarder l'horloge et la\nsession.",[40,208,210],{"id":209},"quelle-clé-est-en-cause-votre-clé-api-ou-le-jeton-de-votre-utilisateur","Quelle clé est en cause : votre clé API ou le jeton de votre utilisateur ?",[10,212,213,214,216,217,220],{},"Cela dépend de si votre projet utilise encore ",[21,215,37],{}," et ",[21,218,219],{},"service_role",".",[10,222,223,224,216,226,228,229,232],{},"La documentation de Supabase sur les clés API est explicite sur la différence.\nLes anciennes clés ",[21,225,37],{},[21,227,219],{}," sont des JWT de longue durée, et\nc'est pour cela qu'elles commencent par ",[21,230,231],{},"eyJ",". Les clés publishable et secret\nplus récentes sont de courtes chaînes et ne sont pas du tout des JWT.",[10,234,235],{},"Ce seul fait coupe l'erreur en deux :",[237,238,239,250],"ul",{},[240,241,242,249],"li",{},[31,243,244,245,216,247,220],{},"Votre projet utilise encore ",[21,246,37],{},[21,248,219],{}," La clé API de votre\nrequête est elle-même un jeton signé, donc une clé venue d'un autre projet, une\nclé d'avant une rotation ou un collage tronqué échouent à la vérification de\nsignature exactement comme une mauvaise session. Chacun des deux jetons de la\nrequête peut être celui qui a échoué.",[240,251,252,261],{},[31,253,254,255,216,258,220],{},"Votre projet est passé à ",[21,256,257],{},"sb_publishable_",[21,259,260],{},"sb_secret_"," La clé API a\ncessé d'être un jeton, il n'y a donc plus de signature dessus que quoi que ce\nsoit puisse refuser. Reste à vérifier le jeton d'accès de votre utilisateur\nconnecté, que Supabase Auth délivre séparément de la clé API.",[57,263],{"alt":264,"caption":265,"src":266},"Deux rangées, chacune se terminant par un cachet. Dans la rangée du haut, une lettre scellée marquée anon et une seconde lettre scellée à côté d'une personne vont toutes deux vers le cachet. Dans la rangée du bas, une carte simple marquée sb_publishable_ ne porte ni sceau ni trait, et seule la lettre scellée à côté de la personne va vers le cachet.","Sur un ancien projet, deux lettres scellées arrivent et chacune des deux peut être celle qui est refusée. Après le passage aux nouvelles clés, la clé API ne porte plus de sceau, et la session de votre utilisateur connecté est la seule chose à laquelle une signature reste attachée.","\u002Fblog\u002Fsupabase-invalid-jwt\u002Ftwo-things-called-your-key-1600x820.png",[10,268,269],{},"En pratique, la première question n'est donc pas de savoir quelle clé est\nmauvaise. C'est de savoir si quelqu'un était connecté quand la requête a échoué.\nSi une page hors connexion fonctionne et qu'une page connectée ne fonctionne pas,\nvous regardez des sessions. Si tout échoue, y compris une page qui ne demande\nrien de personnel, vous regardez la clé API, et votre projet est un ancien.",[10,271,272,273,276,277,220],{},"Si ce sont des sessions et que votre log Auth affiche aussi\n",[21,274,275],{},"Invalid Refresh Token",", vos utilisateurs sont déconnectés parce que\n",[278,279,281],"a",{"href":280},"\u002Fblog\u002Fsupabase-users-logged-out","la session derrière leur token a pris fin",[10,283,284,285,288,289,220],{},"Si la réponse vient de Supabase Auth et dit ",[21,286,287],{},"invalid claim: missing sub claim",",\nle token a passé la vérification de sa signature et ne nommait personne. C'est\nune clé envoyée là où devrait se trouver le token d'une personne, et\n",[278,290,292],{"href":291},"\u002Fblog\u002Finvalid-claim-missing-sub-claim","ce message a son propre article",[40,294,296],{"id":295},"invalid-jwt-nest-pas-no-api-key-found-in-request","Invalid JWT n'est pas \"No API key found in request\"",[10,298,299],{},"Ce sont deux messages différents avec deux causes différentes, et les\ncorrections n'ont rien en commun.",[10,301,302,303,307,308,311],{},"Un invalid JWT veut dire qu'un jeton est arrivé et que la signature ne\ncorrespondait pas. ",[278,304,306],{"href":305},"\u002Fblog\u002Fno-api-key-found-in-request","\"No API key found in\nrequest\""," veut dire qu'aucun en-tête ",[21,309,310],{},"apikey","\nn'est arrivé, et que la requête a donc été refusée à la passerelle avant que\nvotre base de données soit interrogée.",[10,313,314,315,317,318,321,322,324,325,327],{},"La réponse elle-même tranche. Une clé manquante est refusée par la passerelle\nplacée devant votre projet, le corps porte donc un ",[21,316,81],{}," et un ",[21,319,320],{},"hint"," et\naucun ",[21,323,21],{},". Un invalid JWT est allé assez loin pour être lu par PostgREST, et\nc'est pour cela qu'il revient avec ",[21,326,71],{}," écrit dessus.",[40,329,331],{"id":330},"où-traîne-encore-lancienne-clé-dans-lordre","Où traîne encore l'ancienne clé, dans l'ordre",[10,333,334],{},"Quatre endroits, à vérifier dans cet ordre parce qu'il correspond à peu près à\nla fréquence avec laquelle chacun est la réponse.",[336,337,338,344,355,361],"ol",{},[240,339,340,343],{},[31,341,342],{},"Les réglages de projet de votre outil de création."," Lovable, Bolt, v0 et\nReplit gardent chacun leur jeu de variables d'environnement, et si vous avez\nconstruit avec Cursor ou Claude Code, le même jeu se trouve là où vous\ndéployez. C'est la copie que la plupart des gens mettent à jour, et la seule\nque la plupart des gens mettent à jour.",[240,345,346,349,350,354],{},[31,347,348],{},"Une clé écrite directement dans le code."," Elle part dans le JavaScript que\nvos visiteurs téléchargent, donc la changer dans le tableau de bord ne change\nrien tant que le fichier n'est pas modifié et le site reconstruit. ",[278,351,353],{"href":352},"\u002Fblog\u002Fwhere-to-find-supabase-api-keys","Où se\ntrouve cette page et à quoi sert chaque\nvaleur",", si vous ne l'avez pas ouverte.",[240,356,357,360],{},[31,358,359],{},"Les secrets d'Edge Function."," Une fonction garde son propre jeu, séparé de\ncelui de votre frontend, et continue donc d'utiliser l'ancienne clé une fois\nque tout le reste a bougé. Supabase prévient aussi qu'une fonction dont le\nréglage Verify JWT est activé peut casser lors de la rotation d'une clé de\nsignature.",[240,362,363,366],{},[31,364,365],{},"Un déploiement que personne n'a reconstruit."," La clé a été figée lors du\ndernier build, la copie en ligne continue donc de l'envoyer jusqu'à ce que\nquelque chose déclenche un nouveau build. Votre tableau de bord affiche la\nnouvelle clé pendant tout ce temps, et c'est ce qui rend ce cas difficile à\nvoir : l'endroit où vous allez vérifier est le seul qui soit déjà correct.",[40,368,370],{"id":369},"quelle-clé-votre-application-en-ligne-envoie-vraiment","Quelle clé votre application en ligne envoie vraiment",[10,372,373],{},"Ouvrez le site publié plutôt que l'aperçu, et lisez ce que la page envoie.",[10,375,376,377,379,380,382,383,385,386,390,391,395],{},"Une ancienne clé Supabase est une longue chaîne qui commence par ",[21,378,231],{},". Les plus\nrécentes s'annoncent dans leurs premiers caractères : ",[21,381,257],{}," a sa\nplace dans votre application et ",[21,384,260],{}," jamais. Si vous trouvez la seconde\ndans une page qu'un visiteur peut charger, arrêtez cet article et\n",[278,387,389],{"href":388},"\u002Fblog\u002Frotate-supabase-service-role-key","changez-la"," avant toute autre chose.\nLaquelle des deux vous avez en main, et\n",[278,392,394],{"href":393},"\u002Fblog\u002Fsupabase-new-api-keys","ce qui a changé quand Supabase les a\nrenommées",", sont à régler avant de commencer à\nremplacer des valeurs.",[10,397,398],{},"Pour voir ce que votre projet délivre en ce moment : toutes les clés vivent\ndésormais au même endroit dans le tableau de bord, sous Settings puis API Keys,\nles anciennes comprises.",[10,400,401,402,220],{},"Si vous préférez ne pas lire un bundle minifié, notre scan gratuit lit votre\napplication en ligne comme le ferait un inconnu et signale les clés visibles\ndepuis l'extérieur. Il prend une vingtaine de secondes et ne demande aucun\ncompte : ",[278,403,405],{"href":404},"\u002Fsecurity-scanner","scanner votre application",[40,407,409],{"id":408},"faire-une-rotation-de-clé-de-signature-sans-déconnecter-tout-le-monde","Faire une rotation de clé de signature sans déconnecter tout le monde",[10,411,412],{},"Lequel des deux chemins de rotation vous prenez décide si vos utilisateurs s'en\naperçoivent.",[10,414,415,416,419,420,216,422,424,425,428],{},"La documentation de Supabase sur les clés de signature met les deux côte à côte.\nLa rotation de ",[31,417,418],{},"l'ancien secret JWT"," déconnecte immédiatement les utilisateurs\nactifs, et ",[21,421,37],{},[21,423,219],{}," doivent être changées en même temps. Les\n",[31,426,427],{},"JWT signing keys"," plus récentes marchent autrement : une nouvelle clé démarre\nen standby, la rotation en fait la clé courante, et celle qu'elle remplace\ndevient la précédente. Tant que c'est le cas, les signatures des deux clés\ncontinuent d'être acceptées, et les lettres scellées la semaine dernière\ns'ouvrent encore. Révoquer l'ancienne clé est l'étape distincte qui met fin à\ncela.",[10,430,431],{},"Deux avertissements de cette même documentation sont ceux qui piègent :",[237,433,434,437],{},[240,435,436],{},"Un composant qui vérifie lui-même les jetons contre l'ancien secret JWT, avec\nune bibliothèque comme jose ou jsonwebtoken, casse à la rotation. Il tient\nl'ancien cachet et personne ne lui a dit d'en changer.",[240,438,439],{},"Une Edge Function dont le réglage Verify JWT est activé peut casser pour la\nmême raison.",[10,441,442],{},"Créer des clés publishable et secret ne révoque pas non plus vos anciennes clés.\nElles continuent de fonctionner jusqu'à ce que vous les désactiviez, ce que la\ndocumentation présente comme une étape à part. Une application qui n'a migré que\nla moitié de ses copies continue donc de tourner pendant des semaines, et le jour\noù quelqu'un désactive l'ancienne paire est le jour où l'autre moitié se met à\nrépondre 401.",[40,444,446],{"id":445},"surveiller-une-application-qui-sest-mise-à-répondre-401","Surveiller une application qui s'est mise à répondre 401",[10,448,449,452],{},[31,450,451],{},"Une application qui renvoie 401 à chaque requête est toujours en ligne, sert\ntoujours une page et répond toujours à un contrôle de santé."," Rien ne passe au\nrouge dans votre tableau de bord. Vous l'apprenez quand quelqu'un vous écrit.",[10,454,455],{},[31,456,457,461],{},[278,458,460],{"href":459},"\u002Fwebsite-monitoring","Reeve Monitor"," l'apprend en premier :",[237,463,464,467,470,473],{},[240,465,466],{},"les neuf vérifications toutes les heures, sur jusqu'à trois applications",[240,468,469],{},"un e-mail le jour où un nouveau scan note votre application moins bien que le précédent",[240,471,472],{},"si l'application répond, toutes les 60 secondes",[240,474,475],{},"un rapport mensuel de ce qu'il a vu",[10,477,478],{},[31,479,480,481,485],{},"Une clé que vous avez dû changer dans l'urgence est en général une clé qui\ntraînait là où elle n'aurait pas dû, et d'ici vous ne voyez pas ce qui a été lu\nou modifié avec elle pendant qu'elle était dehors. ",[278,482,484],{"href":483},"\u002Fsupabase-backups","Reeve\nCare"," garde une copie de votre base de données Supabase\nd'avant cet épisode.",[237,487,488,491,494,497,500],{},[240,489,490],{},"une copie chiffrée selon un calendrier, gardée sur le stockage de Reeve dans l'UE, en dehors de votre compte Supabase",[240,492,493],{},"chaque copie vérifiée avant d'être comptée, en comptant les lignes de chaque table",[240,495,496],{},"une restauration en un clic qui sauvegarde l'état actuel avant de le remplacer",[240,498,499],{},"vos fichiers téléversés aussi, dès que vous connectez un accès Storage",[240,501,502],{},"tout ce que fait Monitor",[40,504,506],{"id":505},"quoi-faire-aujourdhui","Quoi faire aujourd'hui",[508,509,510],"key-takeaways",{},[237,511,512,524,527,530,533],{},[240,513,514,515,517,518,520,521,523],{},"Lisez le champ ",[21,516,21],{},", pas la phrase. ",[21,519,71],{}," est une signature qui ne correspondait pas, ",[21,522,205],{}," un jeton dont le contenu a été refusé, par exemple expiré.",[240,525,526],{},"Déterminez quel jeton a échoué avant de changer une clé. Si les pages hors connexion marchent et que les pages connectées ne marchent pas, c'est une session et non votre clé API.",[240,528,529],{},"Vérifiez les quatre endroits où se cache l'ancienne clé : les réglages de l'outil de création, le code lui-même, les secrets d'Edge Function, et un déploiement que personne n'a reconstruit.",[240,531,532],{},"Faites une rotation d'un seul tenant. Chaque copie oubliée est une application qui marche à moitié, et le site en ligne continue d'envoyer l'ancienne clé jusqu'à sa reconstruction.",[240,534,535],{},"Avec les nouvelles clés de signature, c'est la révocation qui met vraiment fin aux anciennes signatures. La rotation seule les laisse acceptées.",[10,537,538,539,542,543,547],{},"Commencez par demander si une page hors connexion se charge encore, car cette\nseule réponse décide quelle moitié de cet article vous concerne. S'il s'avère\nqu'une clé secrète traînait à découvert,\n",[278,540,541],{"href":388},"la changer"," couvre l'ordre dans lequel\nprocéder, et\n",[278,544,546],{"href":545},"\u002Fblog\u002Fwhich-api-keys-are-safe-in-your-frontend","quelles clés ont jamais été sûres à\nlivrer"," explique pourquoi les\ndeux se ressemblent autant.",{"title":23,"searchDepth":549,"depth":549,"links":550},3,[551,553,554,555,556,557,558,559,560],{"id":42,"depth":552,"text":43},2,{"id":64,"depth":552,"text":65},{"id":209,"depth":552,"text":210},{"id":295,"depth":552,"text":296},{"id":330,"depth":552,"text":331},{"id":369,"depth":552,"text":370},{"id":408,"depth":552,"text":409},{"id":445,"depth":552,"text":446},{"id":505,"depth":552,"text":506},"Bases de la sécurité","\u002Fblog\u002Fsupabase-invalid-jwt\u002Fcover-1200x630.png","Une lettre scellée devant un cachet dont la gravure ne correspond plus au sceau, et d'autres lettres derrière une barre ambre.","Une erreur Supabase invalid JWT, c'est PGRST301 : un jeton signé n'a pas passé la vérification. Sur un projet récent, c'est la session, pas la clé API.",false,"md",[568,571,574,577,580],{"q":569,"a":570},"Que signifie PGRST301 ?","PGRST301 est la réponse de PostgREST en HTTP 401 parce qu'un jeton signé présent dans votre requête n'a pas pu être vérifié. PostgREST est le serveur qui transforme vos tables Supabase en l'API HTTP avec laquelle votre application parle. Sa propre référence des erreurs décrit ce code comme un JWT fourni qui n'a pas pu être décodé ou qui est invalide, et depuis la version 13 le champ message porte une phrase plus précise indiquant quelle partie de la vérification a échoué.",{"q":572,"a":573},"Pourquoi ai-je un 401 après avoir changé ma clé Supabase ?","Parce qu'une copie de l'ancienne clé est encore envoyée quelque part. Les endroits habituels sont les réglages de projet de votre outil de création, une clé écrite directement dans le code, un secret d'Edge Function, et un déploiement construit avant votre changement et jamais reconstruit depuis. Un jeton signé par une clé que le serveur n'accepte plus échoue à la vérification, et cela vous arrive comme un 401 sur chaque requête plutôt que comme un message sur la clé.",{"q":575,"a":576},"Quelle différence avec le message No API key found in request ?","Ce sont deux messages différents avec deux causes différentes. No API key found in request signifie que la requête est arrivée sans aucun en-tête apikey et qu'elle a été refusée à la passerelle avant même que votre base de données soit interrogée. Un invalid JWT signifie qu'un jeton était bien là et que sa signature ne correspondait pas. L'un est une lettre sans adresse, l'autre une lettre avec le mauvais sceau.",{"q":578,"a":579},"Dois-je mettre à jour mes Edge Functions aussi ?","Oui, et c'est la copie que l'on oublie le plus souvent, car une Edge Function garde ses propres secrets, séparés de ceux de votre frontend. Supabase prévient aussi qu'une fonction dont le réglage Verify JWT est activé peut casser lors de la rotation d'une clé de signature, et que tout composant qui vérifie lui-même les jetons contre l'ancien secret JWT cassera pour la même raison.",{"q":581,"a":582},"Comment voir quelle clé mon application en ligne envoie vraiment ?","Ouvrez votre site publié, pas l'aperçu, et regardez ce que la page envoie réellement. Une ancienne clé Supabase est une longue chaîne qui commence par eyJ, les plus récentes commencent par sb_publishable_ ou sb_secret_. Notre scan gratuit lit une application en ligne comme le ferait un inconnu et signale les clés visibles depuis l'extérieur, ce qui vous dit aussi si une ancienne est encore envoyée.","\u002Fblog\u002Fsupabase-invalid-jwt\u002Fcard-800x500.png",[585,586,587,588,589,590,591],"supabase invalid jwt","pgrst301","bad_jwt supabase","supabase 401 après rotation de clé","jwsinvalidsignature supabase","ancienne clé supabase ne fonctionne plus","provided jwt could not be decoded",{},true,"\u002Fblog\u002Fsupabase-invalid-jwt","2026-10-16",{"title":5,"description":564},"blog\u002Fsupabase-invalid-jwt",[599,600,601],"Une erreur Supabase invalid JWT arrive sous le code PGRST301 avec un HTTP 401, et elle signifie que la signature du jeton envoyé n'a pas pu être vérifiée. Rien n'a été cherché dans une liste puis refusé.","Les clés publishable et secret sont de courtes chaînes sans signature. Sur un projet qui est passé à ces clés, cette erreur concerne donc votre utilisateur connecté et jamais la clé API.","PostgREST 13 a remplacé une phrase vague par une courte liste de phrases précises. Lisez le message que vous avez vraiment reçu : chacun écarte une cause différente.","KHxrXtOF5BJmFtlL5lytRyP_93UDG1ybzaBeeol8LII",[604,610,616,622,628,634,639,645,651,657,663,670,676,682,688,694,700,706,712,718,724,730,735,741,747,748,754,760,766,772,778,784,790,796,801,807,813,819,825,831,837,843,849,855,861,867,872,878,884,890,896,902,908,914,920,926,932,938,944,950,956,962,968,974,979,985,991,997,1003,1009,1015,1021,1027,1033,1039,1044,1050,1056,1062,1068,1074,1080,1086,1092,1097,1102,1108,1114,1119,1125],{"path":605,"title":606,"description":607,"published":608,"category":561,"image":609,"draft":565},"\u002Fblog\u002Fmax-client-connections-reached","Supabase \"max client connections reached\" expliqué","Supabase \"max client connections reached\" : le pooler n'a plus de place pour un client de plus. Le port de votre chaîne de connexion fixe la limite.","2026-11-09","\u002Fblog\u002Fmax-client-connections-reached\u002Fcard-800x500.png",{"path":611,"title":612,"description":613,"published":614,"category":561,"image":615,"draft":565},"\u002Fblog\u002Funsupported-provider-provider-is-not-enabled","Erreur Supabase : \"Unsupported provider: provider is not enabled\"","\"Unsupported provider: provider is not enabled\" : la connexion Google est désactivée dans votre projet Supabase. Comment l'activer, et redirect_uri_mismatch.","2026-11-08","\u002Fblog\u002Funsupported-provider-provider-is-not-enabled\u002Fcard-800x500.png",{"path":617,"title":618,"description":619,"published":620,"category":561,"image":621,"draft":565},"\u002Fblog\u002Fviolates-foreign-key-constraint","Erreur Supabase \"violates foreign key constraint\" à l'insertion","Supabase \"insert or update on table violates foreign key constraint\" : votre ligne pointe vers une ligne absente. Laquelle, pourquoi, et la solution.","2026-11-07","\u002Fblog\u002Fviolates-foreign-key-constraint\u002Fcard-800x500.png",{"path":623,"title":624,"description":625,"published":626,"category":561,"image":627,"draft":565},"\u002Fblog\u002Fnull-value-violates-not-null-constraint","Erreur Supabase \"null value in column violates not-null constraint\"","Supabase \"null value in column violates not-null constraint\" : une colonne obligatoire est arrivée vide. D'où vient le null, et la solution.","2026-11-06","\u002Fblog\u002Fnull-value-violates-not-null-constraint\u002Fcard-800x500.png",{"path":629,"title":630,"description":631,"published":632,"category":561,"image":633,"draft":565},"\u002Fblog\u002Fauth-session-missing","Supabase \"Auth session missing!\" : où est passée la session","\"Auth session missing!\" : supabase-js n'a trouvé aucune session connectée et n'a même pas interrogé Supabase. Où est passée la session, et la solution.","2026-11-05","\u002Fblog\u002Fauth-session-missing\u002Fcard-800x500.png",{"path":291,"title":635,"description":636,"published":637,"category":561,"image":638,"draft":565},"Supabase \"invalid claim: missing sub claim\" : personne de connecté","\"invalid claim: missing sub claim\" : Supabase Auth a reçu un vrai jeton qui ne nomme personne, la clé du projet à la place d'une session.","2026-11-04","\u002Fblog\u002Finvalid-claim-missing-sub-claim\u002Fcard-800x500.png",{"path":640,"title":641,"description":642,"published":643,"category":561,"image":644,"draft":565},"\u002Fblog\u002Ffailed-to-send-a-request-to-the-edge-function","\"Failed to send a request to the Edge Function\" : la vraie cause","\"Failed to send a request to the Edge Function\" : le navigateur n'a reçu aucune réponse lisible. Sa console dit pourquoi, et si votre fonction a tourné.","2026-11-03","\u002Fblog\u002Ffailed-to-send-a-request-to-the-edge-function\u002Fcard-800x500.png",{"path":646,"title":647,"description":648,"published":649,"category":561,"image":650,"draft":565},"\u002Fblog\u002Fsupabase-auth-redirects-to-localhost","Pourquoi les liens e-mail de Supabase redirigent vers localhost:3000","Si Supabase redirige vers localhost:3000, la Site URL n'a jamais été changée ou votre adresse manque dans Redirect URLs. La solution, et le joker à éviter.","2026-11-02","\u002Fblog\u002Fsupabase-auth-redirects-to-localhost\u002Fcard-800x500.png",{"path":652,"title":653,"description":654,"published":655,"category":561,"image":656,"draft":565},"\u002Fblog\u002Femail-link-is-invalid-or-has-expired","Supabase \"Email link is invalid or has expired\" sur un lien neuf","Sur un lien envoyé il y a une minute, \"Email link is invalid or has expired\" de Supabase signifie souvent qu'un filtre de messagerie l'a utilisé avant.","2026-11-01","\u002Fblog\u002Femail-link-is-invalid-or-has-expired\u002Fcard-800x500.png",{"path":658,"title":659,"description":660,"published":661,"category":561,"image":662,"draft":565},"\u002Fblog\u002Fcanceling-statement-due-to-statement-timeout","Supabase \"canceling statement due to statement timeout\" expliqué","Supabase \"canceling statement due to statement timeout\" : une requête a dépassé la limite de son rôle, 3 secondes pour un visiteur. Vérifiez la règle RLS.","2026-10-31","\u002Fblog\u002Fcanceling-statement-due-to-statement-timeout\u002Fcard-800x500.png",{"path":664,"title":665,"description":666,"published":667,"category":668,"image":669,"draft":565},"\u002Fblog\u002Fdatabase-error-deleting-user","\"Database error deleting user\" sur Supabase, et ce qui part avec","\"Database error deleting user\" sur Supabase : votre base a refusé la suppression. La cause est dans vos logs, et la solution décide de ce qui part avec.","2026-10-30","Backups","\u002Fblog\u002Fdatabase-error-deleting-user\u002Fcard-800x500.png",{"path":671,"title":672,"description":673,"published":674,"category":561,"image":675,"draft":565},"\u002Fblog\u002Fstripe-webhook-no-signatures-found","\"No signatures found matching the expected signature\" sur Supabase","Un webhook Stripe dans une Edge Function Supabase affiche \"No signatures found matching the expected signature\" ? Deux causes. Gardez la vérification.","2026-10-29","\u002Fblog\u002Fstripe-webhook-no-signatures-found\u002Fcard-800x500.png",{"path":677,"title":678,"description":679,"published":680,"category":561,"image":681,"draft":565},"\u002Fblog\u002Fsupabase-invalid-login","\"Invalid login credentials\" dans Supabase : les trois causes","Supabase répond \"Invalid login credentials\" à un mauvais mot de passe, un e-mail inconnu et un compte Google. Comment savoir lequel.","2026-10-28","\u002Fblog\u002Fsupabase-invalid-login\u002Fcard-800x500.png",{"path":683,"title":684,"description":685,"published":686,"category":561,"image":687,"draft":565},"\u002Fblog\u002Fedge-function-returned-a-non-2xx-status-code","\"Edge Function returned a non-2xx status code\" : la vraie erreur","\"Edge Function returned a non-2xx status code\" signifie que votre fonction Supabase a répondu par une erreur. Voici où lire la vraie.","2026-10-27","\u002Fblog\u002Fedge-function-returned-a-non-2xx-status-code\u002Fcard-800x500.png",{"path":689,"title":690,"description":691,"published":692,"category":561,"image":693,"draft":565},"\u002Fblog\u002Fcertificate-not-trusted","Certificat non approuvé : trois causes autres que l’expiration","Certificat non approuvé alors que la date est bonne ? Il nomme une autre adresse, il s’est signé lui-même ou il manque un maillon à sa chaîne.","2026-10-26","\u002Fblog\u002Fcertificate-not-trusted\u002Fcard-800x500.png",{"path":695,"title":696,"description":697,"published":698,"category":561,"image":699,"draft":565},"\u002Fblog\u002Finvalid-input-syntax-for-type-uuid","Supabase \"invalid input syntax for type uuid\" : lisez les guillemets","Supabase \"invalid input syntax for type uuid\" : votre app a envoyé autre chose qu'un id. Lisez les guillemets, retenez la requête, gardez la colonne.","2026-10-25","\u002Fblog\u002Finvalid-input-syntax-for-type-uuid\u002Fcard-800x500.png",{"path":701,"title":702,"description":703,"published":704,"category":561,"image":705,"draft":565},"\u002Fblog\u002Fduplicate-key-value-violates-unique-constraint","Supabase \"duplicate key value violates unique constraint\" expliqué","Supabase \"duplicate key value violates unique constraint\" : la valeur est déjà prise. Trouver la colonne, choisir un correctif, garder la valeur hors écran.","2026-10-24","\u002Fblog\u002Fduplicate-key-value-violates-unique-constraint\u002Fcard-800x500.png",{"path":707,"title":708,"description":709,"published":710,"category":561,"image":711,"draft":565},"\u002Fblog\u002Fsupabase-relation-does-not-exist","Supabase \"relation does not exist\" alors que la table existe","Supabase \"relation does not exist\" ou PGRST205 : aucune table ne porte ce nom dans ce schéma. Quatre vérifications, et ce qu'ouvre un schéma exposé.","2026-10-23","\u002Fblog\u002Fsupabase-relation-does-not-exist\u002Fcard-800x500.png",{"path":713,"title":714,"description":715,"published":716,"category":561,"image":717,"draft":565},"\u002Fblog\u002Fsupabase-function-not-found","Supabase PGRST202: \"Could not find the function in the schema cache\"","Supabase \"Could not find the function in the schema cache\" cite les noms d'arguments envoyés par votre application. Comparez-les à la fonction.","2026-10-22","\u002Fblog\u002Fsupabase-function-not-found\u002Fcard-800x500.png",{"path":719,"title":720,"description":721,"published":722,"category":561,"image":723,"draft":565},"\u002Fblog\u002Fsupabase-schema-cache-column-error","Supabase PGRST204: \"Could not find the column in the schema cache\"","Supabase \"Could not find the column in the schema cache\" vient le plus souvent du nom. Quatre vérifications, et la ligne qui recharge le cache.","2026-10-21","\u002Fblog\u002Fsupabase-schema-cache-column-error\u002Fcard-800x500.png",{"path":725,"title":726,"description":727,"published":728,"category":561,"image":729,"draft":565},"\u002Fblog\u002Fsupabase-email-rate-limit-exceeded","Supabase \"Email Rate Limit Exceeded\" : deux limites, un code","Supabase \"Email Rate Limit Exceeded\" plafonne chaque e-mail de votre projet : 2 par heure avec l'expéditeur intégré. Ce qui compte, et comment le relever.","2026-10-20","\u002Fblog\u002Fsupabase-email-rate-limit-exceeded\u002Fcard-800x500.png",{"path":280,"title":731,"description":732,"published":733,"category":561,"image":734,"draft":565},"Supabase \"Invalid Refresh Token: Refresh Token Not Found\" : 3 causes","Supabase \"Invalid Refresh Token: Refresh Token Not Found\" déconnecte vos utilisateurs. Trois causes, et comment le log Auth les distingue.","2026-10-19","\u002Fblog\u002Fsupabase-users-logged-out\u002Fcard-800x500.png",{"path":736,"title":737,"description":738,"published":739,"category":561,"image":740,"draft":565},"\u002Fblog\u002Fpermission-denied-for-schema-public","Supabase \"permission denied for schema public\" : trois causes","Supabase \"permission denied for schema public\" signale un grant manquant sur le schéma. Ce qui l'a retiré, et la ligne qui le remet.","2026-10-18","\u002Fblog\u002Fpermission-denied-for-schema-public\u002Fcard-800x500.png",{"path":742,"title":743,"description":744,"published":745,"category":561,"image":746,"draft":565},"\u002Fblog\u002Fsupabase-bucket-not-found","Supabase \"Bucket not found\" : les trois choses que cela veut dire","Supabase \"Bucket not found\", c'est une de trois choses : un lien public vers un bucket privé, un nom pas tout à fait exact, ou le mauvais projet.","2026-10-17","\u002Fblog\u002Fsupabase-bucket-not-found\u002Fcard-800x500.png",{"path":594,"title":5,"description":564,"published":595,"category":561,"image":583,"draft":565},{"path":749,"title":750,"description":751,"published":752,"category":561,"image":753,"draft":565},"\u002Fblog\u002Fsupabase-single-row-error","Supabase \"multiple (or no) rows returned\" veut dire zéro ligne","Supabase renvoie PGRST116, \"JSON object requested, multiple (or no) rows returned\", quand la requête n'a rien trouvé. Une ligne cachée semble absente.","2026-10-15","\u002Fblog\u002Fsupabase-single-row-error\u002Fcard-800x500.png",{"path":755,"title":756,"description":757,"published":758,"category":561,"image":759,"draft":565},"\u002Fblog\u002Fdatabase-error-saving-new-user","\"Database error saving new user\" sur Supabase : où regarder","\"Database error saving new user\" veut dire que quelque chose rattaché à votre inscription Supabase a échoué. La vraie erreur est dans vos logs.","2026-10-14","\u002Fblog\u002Fdatabase-error-saving-new-user\u002Fcard-800x500.png",{"path":761,"title":762,"description":763,"published":764,"category":561,"image":765,"draft":565},"\u002Fblog\u002Fwhat-is-supabase","Qu'est-ce que Supabase ? La base que votre builder a choisie","Qu'est-ce que Supabase : la base de données, la connexion et le stockage de fichiers de votre app. Les règles sur qui lit vos lignes sont à vous.","2026-10-13","\u002Fblog\u002Fwhat-is-supabase\u002Fcard-800x500.png",{"path":767,"title":768,"description":769,"published":770,"category":561,"image":771,"draft":565},"\u002Fblog\u002Faws-access-key-exposed-in-frontend","Une clé AWS exposée dans le frontend n'est pas une clé OpenAI","Une clé d'accès AWS exposée dans votre frontend lit et écrit votre stockage. La solution est en général une presigned URL, pas une nouvelle clé.","2026-10-12","\u002Fblog\u002Faws-access-key-exposed-in-frontend\u002Fcard-800x500.png",{"path":773,"title":774,"description":775,"published":776,"category":561,"image":777,"draft":565},"\u002Fblog\u002Fstorage-upload-violates-row-level-security","\"Row-level security policy for table objects\" à l'upload","\"New row violates row-level security policy for table objects\" signifie que votre upload n'a pas de règle insert. Rendre le bucket public n'en ajoute aucune.","2026-10-11","\u002Fblog\u002Fstorage-upload-violates-row-level-security\u002Fcard-800x500.png",{"path":779,"title":780,"description":781,"published":782,"category":561,"image":783,"draft":565},"\u002Fblog\u002Fbase44-security-scan","Scan de sécurité Base44 : ce que lui seul peut voir","Le scan de sécurité Base44 vérifie sept types de problèmes depuis l’intérieur. Voici la moitié que lui seul lit, et celle qu’il ne regarde jamais.","2026-10-10","\u002Fblog\u002Fbase44-security-scan\u002Fcard-800x500.png",{"path":785,"title":786,"description":787,"published":788,"category":561,"image":789,"draft":565},"\u002Fblog\u002Fapi-key-leaked-what-to-do","Votre clé API a fuité. L'ordre dans lequel agir","Une clé API a fuité et vous ne savez pas par quoi commencer. Toutes les clés de votre frontend n'en sont pas une, et l'ordre compte plus que la vitesse.","2026-10-09","\u002Fblog\u002Fapi-key-leaked-what-to-do\u002Fcard-800x500.png",{"path":791,"title":792,"description":793,"published":794,"category":561,"image":795,"draft":565},"\u002Fblog\u002Finfinite-recursion-in-policy-for-relation","\"Infinite recursion detected in policy\" sans désactiver RLS","\"Infinite recursion detected in policy for relation\" signifie que votre policy a interrogé la table qu'elle protège. Voici comment rompre le cercle.","2026-10-08","\u002Fblog\u002Finfinite-recursion-in-policy-for-relation\u002Fcard-800x500.png",{"path":305,"title":797,"description":798,"published":799,"category":561,"image":800,"draft":565},"\"No API key found in request\" sur Supabase, et le mauvais correctif","\"No API key found in request\" veut dire que votre requête est arrivée sans clé. La plupart des réponses pointent vers les règles de votre base.","2026-10-07","\u002Fblog\u002Fno-api-key-found-in-request\u002Fcard-800x500.png",{"path":802,"title":803,"description":804,"published":805,"category":561,"image":806,"draft":565},"\u002Fblog\u002Fis-base44-safe","Base44 est-il sûr ? Ce que 5 442 applications ont montré","Base44 est-il sûr ? Neuf vérifications sur 5 442 applications Base44 en ligne. Presque toutes ont eu un B, pour des raisons que personne n’a choisies.","2026-10-06","\u002Fblog\u002Fis-base44-safe\u002Fcard-800x500.png",{"path":808,"title":809,"description":810,"published":811,"category":561,"image":812,"draft":565},"\u002Fblog\u002Fmove-a-secret-to-an-edge-function","Cacher une clé API : la déplacer dans une Edge Function Supabase","Cacher une clé API veut dire la sortir du navigateur, et une Edge Function Supabase est le plus petit endroit où la mettre. Deux étapes comptent davantage.","2026-10-05","\u002Fblog\u002Fmove-a-secret-to-an-edge-function\u002Fcard-800x500.png",{"path":814,"title":815,"description":816,"published":817,"category":561,"image":818,"draft":565},"\u002Fblog\u002Fenv-file-exposed-on-your-server","Votre fichier .env est-il exposé ? Les douze chemins à vérifier","Votre fichier .env est-il exposé sur votre propre serveur web ? Douze adresses vous le disent, et une réponse signifie que tout son contenu est public.","2026-10-04","\u002Fblog\u002Fenv-file-exposed-on-your-server\u002Fcard-800x500.png",{"path":820,"title":821,"description":822,"published":823,"category":561,"image":824,"draft":565},"\u002Fblog\u002Fis-v0-safe","Sécurité de v0 : les 1 790 applications scannées ont toutes eu A","La sécurité de v0 mesurée sur 1 790 applications en ligne : toutes ont eu A. Seules 17 citaient une base de données, et c’est surtout cela que ce A mesure.","2026-10-03","\u002Fblog\u002Fis-v0-safe\u002Fcard-800x500.png",{"path":826,"title":827,"description":828,"published":829,"category":561,"image":830,"draft":565},"\u002Fblog\u002Fis-bolt-safe","Bolt est-il sûr ? Ce que 1 123 applications Bolt ont montré","Bolt est-il sûr ? Neuf vérifications sur 1 123 applications Bolt en ligne. L’hébergement était propre. Les trouvailles : des clés et des tables ouvertes.","2026-10-02","\u002Fblog\u002Fis-bolt-safe\u002Fcard-800x500.png",{"path":832,"title":833,"description":834,"published":835,"category":561,"image":836,"draft":565},"\u002Fblog\u002Fis-supabase-down-or-your-app","Supabase en panne, ou est-ce votre app ? Comment le savoir","Supabase est-il en panne, ou est-ce votre app ? Un projet en pause, une base pleine et un bug chez vous se ressemblent. Quatre vérifications les séparent.","2026-10-01","\u002Fblog\u002Fis-supabase-down-or-your-app\u002Fcard-800x500.png",{"path":838,"title":839,"description":840,"published":841,"category":561,"image":842,"draft":565},"\u002Fblog\u002Fdoes-supabase-encrypt-my-data","Supabase chiffre-t-il mes données ? Oui. Ce que cela arrête","Supabase chiffre-t-il les données ? Oui : AES-256 au repos, TLS en transit, SOC 2 et ISO 27001. Ce que couvre chacun, et la fuite qu'aucun n'arrête.","2026-09-30","\u002Fblog\u002Fdoes-supabase-encrypt-my-data\u002Fcard-800x500.png",{"path":844,"title":845,"description":846,"published":847,"category":561,"image":848,"draft":565},"\u002Fblog\u002Fsupabase-free-plan-limits","Limites du plan gratuit Supabase : ce qui se passe à chacune","Les limites du plan gratuit Supabase : 500 Mo de base, 5 Go d'egress, aucune sauvegarde. Ce qui se passe à chaque seuil, et ce que change Pro à $25.","2026-09-29","\u002Fblog\u002Fsupabase-free-plan-limits\u002Fcard-800x500.png",{"path":850,"title":851,"description":852,"published":853,"category":668,"image":854,"draft":565},"\u002Fblog\u002Ftest-your-supabase-backup","Testez votre sauvegarde Supabase avant d'en avoir besoin","Comment tester votre sauvegarde Supabase : la restaurer dans un projet d'exercice, compter les lignes, se connecter, chercher la ligne qui manque.","2026-09-28","\u002Fblog\u002Ftest-your-supabase-backup\u002Fcard-800x500.png",{"path":856,"title":857,"description":858,"published":859,"category":668,"image":860,"draft":565},"\u002Fblog\u002Fsupabase-backup-github-action","Sauvegarde Supabase gratuite avec une GitHub Action, et le piège","Une sauvegarde Supabase par GitHub Action est gratuite et convient à beaucoup d'apps. Le workflow, la bonne connection string et l'egress de chaque run.","2026-09-27","\u002Fblog\u002Fsupabase-backup-github-action\u002Fcard-800x500.png",{"path":862,"title":863,"description":864,"published":865,"category":668,"image":866,"draft":565},"\u002Fblog\u002Fdownload-your-supabase-backup","Pourquoi vous ne pouvez pas télécharger votre sauvegarde Supabase","Impossible de télécharger votre sauvegarde Supabase sur un projet récent : la copie quotidienne est physique. Comment le vérifier et garder la vôtre.","2026-09-26","\u002Fblog\u002Fdownload-your-supabase-backup\u002Fcard-800x500.png",{"path":868,"title":869,"description":870,"published":865,"category":561,"image":871,"draft":565},"\u002Fblog\u002Fsupabase-permission-denied-for-table","Supabase \"permission denied for table\" : le grant manquant","Dès le 30 octobre, une nouvelle table Supabase répond \"permission denied for table\" tant que l'accès n'est pas accordé. Le grant de l'e-mail est la moitié.","\u002Fblog\u002Fsupabase-permission-denied-for-table\u002Fcard-800x500.png",{"path":873,"title":874,"description":875,"published":876,"category":561,"image":877,"draft":565},"\u002Fblog\u002Fopen-api-endpoint-exposed","Un endpoint d'API ouvert est-il un problème de sécurité ?","Votre scan a signalé un endpoint d'API ouvert. Que cela compte dépend de ce qui est revenu, et la plupart de ceux trouvés étaient à la plateforme.","2026-09-25","\u002Fblog\u002Fopen-api-endpoint-exposed\u002Fcard-800x500.png",{"path":879,"title":880,"description":881,"published":882,"category":561,"image":883,"draft":565},"\u002Fblog\u002Flovable-security-scan","Scan de sécurité Lovable : ce qu’il ne peut pas prouver","Scan de sécurité Lovable : ce que vérifient le Quick scan et le Deep scan, quand chacun part, et la seule chose qu’un scan de l’intérieur ne prouve pas.","2026-09-24","\u002Fblog\u002Flovable-security-scan\u002Fcard-800x500.png",{"path":885,"title":886,"description":887,"published":888,"category":668,"image":889,"draft":565},"\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","\u002Fblog\u002Fsupabase-backup-auth-users\u002Fcard-800x500.png",{"path":891,"title":892,"description":893,"published":894,"category":561,"image":895,"draft":565},"\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":897,"title":898,"description":899,"published":900,"category":561,"image":901,"draft":565},"\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":903,"title":904,"description":905,"published":906,"category":561,"image":907,"draft":565},"\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":909,"title":910,"description":911,"published":912,"category":561,"image":913,"draft":565},"\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":915,"title":916,"description":917,"published":918,"category":561,"image":919,"draft":565},"\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":921,"title":922,"description":923,"published":924,"category":561,"image":925,"draft":565},"\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":927,"title":928,"description":929,"published":930,"category":561,"image":931,"draft":565},"\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":933,"title":934,"description":935,"published":936,"category":561,"image":937,"draft":565},"\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":939,"title":940,"description":941,"published":942,"category":668,"image":943,"draft":565},"\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":945,"title":946,"description":947,"published":948,"category":668,"image":949,"draft":565},"\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":951,"title":952,"description":953,"published":954,"category":668,"image":955,"draft":565},"\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":957,"title":958,"description":959,"published":960,"category":561,"image":961,"draft":565},"\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":963,"title":964,"description":965,"published":966,"category":561,"image":967,"draft":565},"\u002Fblog\u002Fenable-rls-on-every-supabase-table","Activer Row Level Security sur chaque table Supabase, et le prouver","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.","2026-09-10","\u002Fblog\u002Fenable-rls-on-every-supabase-table\u002Fcard-800x500.png",{"path":969,"title":970,"description":971,"published":972,"category":561,"image":973,"draft":565},"\u002Fblog\u002Fsupabase-rls-disabled-in-public","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":388,"title":975,"description":976,"published":977,"category":561,"image":978,"draft":565},"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":980,"title":981,"description":982,"published":983,"category":561,"image":984,"draft":565},"\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. Huit outils comparés, avec les prix.","2026-09-07","\u002Fblog\u002Fvibe-coding-security-scanners-compared\u002Fcard-800x500.png",{"path":986,"title":987,"description":988,"published":989,"category":561,"image":990,"draft":565},"\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":992,"title":993,"description":994,"published":995,"category":561,"image":996,"draft":565},"\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":998,"title":999,"description":1000,"published":1001,"category":561,"image":1002,"draft":565},"\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":1004,"title":1005,"description":1006,"published":1007,"category":561,"image":1008,"draft":565},"\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":1010,"title":1011,"description":1012,"published":1013,"category":561,"image":1014,"draft":565},"\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":1016,"title":1017,"description":1018,"published":1019,"category":668,"image":1020,"draft":565},"\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":1022,"title":1023,"description":1024,"published":1025,"category":561,"image":1026,"draft":565},"\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":1028,"title":1029,"description":1030,"published":1031,"category":668,"image":1032,"draft":565},"\u002Fblog\u002Fback-up-supabase-free-tier","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":1034,"title":1035,"description":1036,"published":1037,"category":561,"image":1038,"draft":565},"\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":352,"title":1040,"description":1041,"published":1042,"category":561,"image":1043,"draft":565},"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":1045,"title":1046,"description":1047,"published":1048,"category":561,"image":1049,"draft":565},"\u002Fblog\u002Fnew-row-violates-row-level-security-policy","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":1051,"title":1052,"description":1053,"published":1054,"category":561,"image":1055,"draft":565},"\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":1057,"title":1058,"description":1059,"published":1060,"category":668,"image":1061,"draft":565},"\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":1063,"title":1064,"description":1065,"published":1066,"category":668,"image":1067,"draft":565},"\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":1069,"title":1070,"description":1071,"published":1072,"category":561,"image":1073,"draft":565},"\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":1075,"title":1076,"description":1077,"published":1078,"category":561,"image":1079,"draft":565},"\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":1081,"title":1082,"description":1083,"published":1084,"category":668,"image":1085,"draft":565},"\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":1087,"title":1088,"description":1089,"published":1090,"category":561,"image":1091,"draft":565},"\u002Fblog\u002Fcan-anyone-read-your-supabase-database","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":1093,"title":1094,"description":1095,"published":1090,"category":561,"image":1096,"draft":565},"\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":393,"title":1098,"description":1099,"published":1100,"category":561,"image":1101,"draft":565},"Supabase publishable key : la même chose que l'anon key ?","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":1103,"title":1104,"description":1105,"published":1106,"category":668,"image":1107,"draft":565},"\u002Fblog\u002Fdoes-supabase-back-up-my-database","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":1109,"title":1110,"description":1111,"published":1112,"category":561,"image":1113,"draft":565},"\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":1115,"title":1116,"description":1117,"published":1112,"category":668,"image":1118,"draft":565},"\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":1120,"title":1121,"description":1122,"published":1123,"category":668,"image":1124,"draft":565},"\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":545,"title":1126,"description":1127,"published":1123,"category":561,"image":1128,"draft":565},"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",1794213642010]