<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="fr">
    <title>~&#x2F;bertrandclavelier</title>
    <link rel="self" type="application/atom+xml" href="https://atelier.clavelier.me/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://atelier.clavelier.me"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2026-07-26T00:00:00+00:00</updated>
    <id>https://atelier.clavelier.me/atom.xml</id>
    <entry xml:lang="fr">
        <title>Mail : la lettre qui voyage ouverte</title>
        <published>2026-07-26T00:00:00+00:00</published>
        <updated>2026-07-26T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Bertrand CLAVELIER
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://atelier.clavelier.me/articles/mail-la-lettre-qui-voyage-ouverte/"/>
        <id>https://atelier.clavelier.me/articles/mail-la-lettre-qui-voyage-ouverte/</id>
        
        <content type="html" xml:base="https://atelier.clavelier.me/articles/mail-la-lettre-qui-voyage-ouverte/">&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;atelier.clavelier.me&#x2F;articles&#x2F;mail-la-lettre-qui-voyage-ouverte&#x2F;mail-en-clair.png&quot; alt=&quot;Un mail ouvert dans un éditeur de texte : en-têtes, expéditeur, destinataire, objet, puis le corps du message, tout en clair.&quot; &#x2F;&gt;
&lt;em&gt;Un message ordinaire, tel qu’il voyage et tel que chaque serveur du trajet le voit : en clair, en-têtes compris. Contenu fabriqué pour la démonstration, adresse de l’expéditeur masquée.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;La souveraineté numérique est partout dans le discours. Chaque site affiche sa politique de confidentialité, chaque contrat sa clause de protection des données, chaque entreprise sa charte sur l’usage de l’IA. Pendant ce temps, notre canal écrit le plus universel, le mail (personnel comme professionnel), circule en quasi-totalité sous une forme lisible : lisible par chaque serveur qu’il traverse, lisible par ceux qui hébergent le courrier de la planète.&lt;&#x2F;p&gt;
&lt;p&gt;Nous avons donc un sérieux problème avec nos mails.&lt;&#x2F;p&gt;
&lt;p&gt;Il ne date pas d’hier, il ne vient pas de l’IA, et je n’invente rien en le nommant : la solution technique existe, l’idée a cinquante ans (1976), l’outil libre et gratuit trente-cinq (1991), et presque personne ne s’en sert. Cet article enfonce donc une porte ouverte. Je vais l’enfoncer avec des faits publics et deux expériences que j’ai réellement menées sur mon propre serveur, reproductibles chez vous.&lt;&#x2F;p&gt;
&lt;p&gt;D’abord, la mesure du sujet. Plus de 360 milliards de mails circulent chaque jour dans le monde (Radicati Group). Un utilisateur de Microsoft 365 en reçoit 117 par jour en moyenne. Tout y passe : contrats, factures, échanges clients, décisions écrites, et chaque « mot de passe oublié » de chaque outil de l’entreprise. Ce courrier vit de plus en plus au même endroit : dans le Fortune 500, près de deux entreprises sur trois hébergent leur messagerie chez Microsoft (64,5 % en 2026, d’après les enregistrements DNS de leurs domaines). Ajoutez Google, et l’essentiel du courrier des grandes entreprises se joue entre deux fournisseurs américains.&lt;&#x2F;p&gt;
&lt;p&gt;Ensuite, deux chiffres qui résument le problème.&lt;&#x2F;p&gt;
&lt;p&gt;En transit, presque tous les mails sont chiffrés : 98 à 99 % circulent chiffrés entre les serveurs (rapport de transparence de Google ; il mesure le trafic vu par Gmail, pas le mail mondial, mais c’est le meilleur ordre de grandeur public disponible). De bout en bout, presque aucun : sur 81 millions de mails échangés en 27 ans dans une université allemande, 0,06 % étaient chiffrés (étude IEEE, 2022 ; une population universitaire, donc a priori mieux équipée que la moyenne).&lt;&#x2F;p&gt;
&lt;p&gt;L’image juste : le camion postal est blindé, mais la lettre voyage ouverte. Sur la route, elle est à l’abri ; dans chaque centre de tri, elle est ouverte et lisible.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;le-trajet-d-un-mail&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#le-trajet-d-un-mail&quot; aria-label=&quot;Anchor link for: le-trajet-d-un-mail&quot;&gt;Le trajet d’un mail&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Pour comprendre ces deux chiffres, il faut suivre le trajet. Un mail part de votre client mail (le logiciel avec lequel vous l’écrivez : Outlook, Apple Mail, le webmail dans le navigateur, etc.), monte sur le serveur de votre fournisseur, puis voyage de serveur en serveur jusqu’à celui du destinataire, qui le remet à son client mail. Le trajet le plus court compte deux serveurs, mais il est souvent plus long : relais d’envoi, passerelle antispam placée devant la messagerie de l’entreprise, redirection d’adresse. Chaque intermédiaire est une machine de plus entre les mains d’un acteur de plus.&lt;&#x2F;p&gt;
&lt;p&gt;Autre différence avec la lettre papier, et elle change beaucoup de choses : rien ne se déplace, tout se copie. À chaque étape, le serveur transmet une copie du message, et rien ne l’oblige à effacer la sienne. À l’arrivée, le mail ne descend pas dans votre appareil : dans l’usage courant (IMAP, webmail), il reste sur le serveur, c’est là que vit la boîte, parfois pendant des années ; votre client s’y connecte pour en afficher, à son tour, une copie. Même la suppression est relative : effacer un message le retire de votre boîte, pas nécessairement des systèmes du fournisseur. Google, par exemple, indique dans sa politique de conservation qu’une donnée supprimée met environ deux mois à disparaître de ses systèmes actifs, et jusqu’à six mois de ses sauvegardes. Rien de caché là-dedans, c’est l’architecture même du mail : des copies, qui durent.&lt;&#x2F;p&gt;
&lt;p&gt;Entre chaque machine, le tuyau est chiffré (TLS) : c’est le camion blindé, ce sont les 98 à 99 %. Mais le chiffrement s’arrête à la porte de chaque serveur : le serveur déchiffre le message, le traite (antispam, tri, indexation), puis le rechiffre vers l’étape suivante. Le mail est donc en clair sur chaque machine qu’il traverse. Le centre de tri lit tout : le contenu, les pièces jointes, et l’enveloppe (qui écrit à qui, quand, à quelle fréquence). Pour une entreprise, cette enveloppe, c’est par exemple la liste des clients et les négociations en cours.&lt;&#x2F;p&gt;
&lt;p&gt;Ce qui empêche votre hébergeur d’exploiter cette lecture n’est pas une barrière technique : c’est un contrat. Un contrat est un engagement, pas une impossibilité. Et il se signe, le plus souvent, avec un géant américain soumis à ses propres lois : le CLOUD Act permet aux autorités américaines d’exiger l’accès aux données, où qu’elles soient hébergées.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;chiffre-un-mot-trois-realites&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#chiffre-un-mot-trois-realites&quot; aria-label=&quot;Anchor link for: chiffre-un-mot-trois-realites&quot;&gt;« Chiffré » : un mot, trois réalités&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Quand un service vante ses « échanges chiffrés », il faut demander de quel chiffrement il s’agit.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Chiffré en transit&lt;&#x2F;strong&gt; : le tuyau entre les machines. Personne ne lit sur la route, mais chaque serveur traversé lit. C’est le chiffrement des 98 à 99 %, et c’est presque toujours de lui que parlent les arguments commerciaux.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Chiffré au repos&lt;&#x2F;strong&gt; : le disque du serveur. Dans sa version sérieuse, chaque mail entrant est chiffré avec la clé publique du compte avant d’être écrit sur le disque : une fois stocké, il est illisible pour tout le monde, hébergeur compris ; seule la clé privée du titulaire l’ouvre. Le hic est ailleurs : le mail est arrivé en clair, le serveur l’a vu passer avant de le chiffrer. Quant à la version pratiquée par les grands fournisseurs, elle est plus faible : Gmail chiffre votre courrier au repos avec ses propres clés. Google peut lire.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Chiffré de bout en bout&lt;&#x2F;strong&gt; : ce n’est plus le tuyau ni le disque qui est chiffré, c’est le message lui-même, du logiciel de l’expéditeur jusqu’à celui du destinataire. Toutes les machines intermédiaires, hébergeur compris, transportent une lettre scellée qu’elles ne peuvent pas ouvrir. C’est le seul chiffrement qui ne repose sur la confiance de personne. Et c’est lui qui plafonne à 0,06 % dans l’étude citée au-dessus.&lt;&#x2F;p&gt;
&lt;p&gt;Trois « chiffré », deux questions qui départagent tout. D’abord : qui chiffre ? Celui qui chiffre a le message en clair entre les mains, et tous ceux qui le précèdent aussi ; plus le chiffrement part tôt, moins il y a de regards possibles. Ensuite : qui détient les clés ? Celui-là pourra toujours rouvrir.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;deux-experiences-reproductibles&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#deux-experiences-reproductibles&quot; aria-label=&quot;Anchor link for: deux-experiences-reproductibles&quot;&gt;Deux expériences, reproductibles&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;La solution s’appelle le chiffrement asymétrique. L’idée date de 1976, l’outil grand public de 1991 (PGP, dont l’auteur fut un temps visé par une enquête pour « export de munitions » : la cryptographie forte relevait alors du même régime que les armes de guerre). Une paire de clés, deux usages : le cadenas (chiffrer : n’importe qui peut fermer un message avec ma clé publique, seule ma clé privée l’ouvre) et le sceau (signer : je scelle avec ma clé privée, n’importe qui vérifie avec ma clé publique que c’est bien moi et que rien n’a été altéré). Je l’ai mis à l’épreuve deux fois.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Première expérience : le chiffrement au repos, sur mon serveur.&lt;&#x2F;strong&gt; J’héberge une boîte mail sur mon propre serveur (Stalwart, open source). J’y ai déposé ma clé publique : chaque mail entrant est désormais chiffré avant d’être écrit sur le disque. Résultat vérifié : moi, l’administrateur de la machine, je ne peux plus lire le contenu de cette boîte. J’ai relevé le même message avec deux logiciels : Apple Mail, qui n’a pas la clé, n’affiche qu’une pièce jointe illisible (un long bloc de caractères pour un mot de six lettres) ; Thunderbird, qui détient ma clé privée, le déchiffre et l’affiche. La limite, déjà nommée : le mail est arrivé en clair jusqu’au serveur. C’est une protection du stockage, pas une garantie de confidentialité.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;atelier.clavelier.me&#x2F;articles&#x2F;mail-la-lettre-qui-voyage-ouverte&#x2F;chiffre-au-repos.png&quot; alt=&quot;Le message chiffré ouvert dans un éditeur de texte : un bloc PGP de trente-neuf lignes, de « BEGIN PGP MESSAGE » à « END PGP MESSAGE ».&quot; &#x2F;&gt;
&lt;em&gt;Le contenu du message « azerty », tel qu’il est stocké sur le disque de mon serveur : illisible, même pour l’administrateur.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Deuxième expérience : le bout en bout, à travers Google.&lt;&#x2F;strong&gt; J’ai envoyé, depuis un compte Gmail configuré dans Thunderbird (OpenPGP y est intégré), un mail chiffré et signé vers ma boîte. La preuve tient dans le dossier « Envoyés » de Gmail : pas d’objet, et pour tout contenu un bloc chiffré en pièce jointe. Google vient d’expédier, depuis ses propres serveurs, un courrier qu’il ne peut pas lire. À l’arrivée, seul le logiciel détenant la clé privée affiche le message, et il vérifie au passage la signature : auteur garanti, contenu intact.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;atelier.clavelier.me&#x2F;articles&#x2F;mail-la-lettre-qui-voyage-ouverte&#x2F;bout-en-bout-gmail.png&quot; alt=&quot;Le dossier « Envoyés » de Gmail : un message sans objet, dont tout le contenu tient dans deux pièces jointes, dont un fichier encrypted.asc.&quot; &#x2F;&gt;
&lt;em&gt;Mon dossier « Envoyés », vu de Gmail : pas d’objet, une pièce jointe chiffrée (un bloc du même type que sur la capture précédente). C’est tout ce que les serveurs du trajet verront du contenu.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Ce sceau mérite qu’on s’y arrête, parce que l’enjeu le plus concret pour une entreprise est là : la fraude au virement et à la fausse facture repose sur l’usurpation d’expéditeur, et la signature la casse. (DKIM, que votre service informatique connaît, authentifie le canal : le serveur du domaine. La signature PGP authentifie l’auteur : la personne qui détient la clé.) Rien n’empêcherait une banque ou une administration, usurpées chaque jour, de signer leurs mails. Presque aucune ne le fait.&lt;&#x2F;p&gt;
&lt;p&gt;Un point que les décideurs sous-estiment : &lt;strong&gt;les pièces jointes font partie du message&lt;&#x2F;strong&gt;. En clair par défaut, elles sont lisibles par l’hébergeur au même titre que le corps du mail. Chiffrées de bout en bout, elles deviennent illisibles pour tout intermédiaire, exactement comme le texte : le format utilisé dans mes expériences (PGP&#x2F;MIME) chiffre corps et pièces jointes d’un seul bloc. Une facture, un contrat, un dossier client en PDF joint peuvent donc voyager aussi protégés que le message qui les porte.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;les-limites-sans-les-edulcorer&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#les-limites-sans-les-edulcorer&quot; aria-label=&quot;Anchor link for: les-limites-sans-les-edulcorer&quot;&gt;Les limites, sans les édulcorer&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;La force du chiffrement ne dispense pas d’en dire les bornes.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;L’enveloppe reste visible.&lt;&#x2F;strong&gt; Qui écrit à qui, et quand : l’hébergeur le voit toujours, il en a besoin pour livrer. L’objet est un cas intermédiaire : en clair dans le protocole, protégé par certains logiciels (Thunderbird le déplace dans la partie chiffrée).&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Le chiffrement au repos n’est pas du bout en bout.&lt;&#x2F;strong&gt; Il protège le stockage, pas le trajet : deux menaces différentes, deux réponses différentes.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;La gestion des clés est le vrai mur.&lt;&#x2F;strong&gt; Pour chiffrer vers quelqu’un, il faut sa clé publique avant l’envoi ; personne ne la gère à votre place. Et une clé privée perdue, c’est une boîte définitivement illisible. L’étude citée plus haut mesure l’effet de ce mur : 2,8 % de mails signés (signer n’exige rien du destinataire) contre 0,06 % de chiffrés (chiffrer exige qu’il soit équipé). Là où le mur tombe, l’usage est presque cinquante fois plus haut.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Tous les mails ne portent pas le même enjeu.&lt;&#x2F;strong&gt; Un vœu d’anniversaire n’est pas un dossier client. Ce que cela doit changer, c’est le choix de la solution, pas le principe : j’y reviens en conclusion.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;pourquoi-presque-personne-alors&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#pourquoi-presque-personne-alors&quot; aria-label=&quot;Anchor link for: pourquoi-presque-personne-alors&quot;&gt;Pourquoi presque personne, alors ?&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Parce que ceux qui pouvaient rendre le chiffrement invisible ne l’ont pas fait. La preuve que c’était possible existe : Signal et WhatsApp chiffrent de bout en bout des milliards de messages par jour, pour des millions de personnes qui n’ont jamais vu une clé. L’adoption n’est pas venue de l’éducation des utilisateurs, elle est venue le jour où comprendre n’était plus nécessaire. La même recette existe pour le mail : chez Proton, par exemple, chaque adresse reçoit sa paire de clés à la création, et tout échange entre comptes Proton part chiffré de bout en bout et signé, sans un geste, avec le même standard ouvert que mes expériences (OpenPGP).&lt;&#x2F;p&gt;
&lt;p&gt;Ne l’attendez pas de Gmail ni d’Outlook : leurs services reposent sur la lecture du courrier (recherche, tri, antispam, fonctions IA). Un mail illisible est un mail non exploitable. Et quand Google s’y est mis (Gmail propose un chiffrement de bout en bout depuis 2025), le résultat est parlant : réservé à une offre entreprise payante, technologie propriétaire plutôt que le standard ouvert, et le destinataire externe lit le message dans une interface Google. Je n’y mets pas d’intention, je constate l’effet : là où un standard ouvert existait, le choix s’est porté sur une solution qui retient le client.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#conclusion&quot; aria-label=&quot;Anchor link for: conclusion&quot;&gt;Conclusion&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;On s’inquiète beaucoup, et à juste titre, de ce que l’IA peut lire de nos données. Mais l’ordre des priorités est étrange : si la quasi-totalité de notre correspondance peut déjà être lue et analysée en masse par une poignée d’acteurs, le problème est là, en amont de l’IA. C’est celui-là qu’une entreprise devrait mesurer d’abord.&lt;&#x2F;p&gt;
&lt;p&gt;Ma position tient en une phrase : aucun de nos messages (même s’il n’est pas un secret d’État) ne devrait être lisible par d’autres que son destinataire. On ferme bien sa porte à clé sans avoir un coffre-fort derrière : c’est une hygiène, pas un aveu. Que tous les mails n’aient pas la même importance ne justifie pas d’en laisser l’immense majorité ouverte ; ce qui doit varier selon les besoins, c’est la solution, pas le principe.&lt;&#x2F;p&gt;
&lt;p&gt;Des solutions, il y en a pour chaque profil. Tout le monde n’a pas à héberger son serveur mail : je l’ai fait, c’est instructif, mais j’en ai aussi éprouvé le prix : l’exploitation au quotidien, et la réputation à construire (un serveur neuf, même configuré proprement, part présumé coupable chez les grands fournisseurs). Selon l’exigence et les moyens : un hébergeur dont le modèle économique n’est pas la lecture du courrier, comme Proton, où le chiffrement s’obtient en ne faisant rien ; ou, comme premier pas, la signature, qui n’équipe qu’un seul bout et casse la fraude la plus courante.&lt;&#x2F;p&gt;
&lt;p&gt;Et ce réflexe dépasse le mail. La même question vaut pour les SMS, pour les messageries d’équipe, et pour le cloud où vivent désormais nos documents, drives et espaces partagés compris : pourquoi tout cela voyage-t-il ouvert, alors que les solutions existent ? Les expériences de cet article le montrent : la solution est à portée de main depuis des décennies. Elle est même devenue confortable. Il reste à décider de s’en servir.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="fr">
        <title>Un backend Supabase de A à Z, piloté par API</title>
        <published>2026-06-14T00:00:00+00:00</published>
        <updated>2026-06-14T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Bertrand CLAVELIER
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://atelier.clavelier.me/articles/backend-supabase-pilote-par-api/"/>
        <id>https://atelier.clavelier.me/articles/backend-supabase-pilote-par-api/</id>
        
        <content type="html" xml:base="https://atelier.clavelier.me/articles/backend-supabase-pilote-par-api/">&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;atelier.clavelier.me&#x2F;articles&#x2F;backend-supabase-pilote-par-api&#x2F;schema-cellier.jpg&quot; alt=&quot;Le schéma du Cellier dans Supabase : les tables commandes, profils, lignes_commande, cuvees et domaines, et les liens qui les relient.&quot; &#x2F;&gt;
&lt;em&gt;Le schéma du Cellier : cinq tables et leurs liens. Le seul aperçu de l’intérieur de la valise de toute la série.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;J’ai construit un backend complet avec Supabase — schéma, règles métier, authentification, paiement — sans frontend ni infrastructure à administrer. Je l’explore en profondeur, brique par brique, et je suis loin d’avoir fait le tour : ces posts sont mon carnet d’apprentissage, documenté au fil de l’eau.&lt;&#x2F;p&gt;
&lt;p&gt;Le terrain de jeu : &lt;strong&gt;Le Cellier&lt;&#x2F;strong&gt;, une cave à vin en ligne fictive mais crédible — elle pourrait tourner pour de vrai. 130 domaines, plus de 14 000 cuvées, des comptes clients, des commandes, un paiement Stripe.&lt;&#x2F;p&gt;
&lt;p&gt;Cet article clôt une série publiée sur deux semaines autour de Supabase. J’y reprends, jour après jour, le récit complet d’une expérience que j’ai partagée au fil des posts — chaque étape avec sa démo en vidéo.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;jour-1-la-valise-numerique&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#jour-1-la-valise-numerique&quot; aria-label=&quot;Anchor link for: jour-1-la-valise-numerique&quot;&gt;Jour 1 — La valise numérique&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;J’ai commencé par poser le cadre, avant la moindre ligne de code. Construire vite, aujourd’hui, on sait faire : une interface, un workflow, une automatisation se montent en quelques heures et se remplacent sans douleur. Mais il y a des briques qu’on ne change pas tous les six mois — celles qui portent les données et les règles métier. Celles-là doivent tenir dans le temps.&lt;&#x2F;p&gt;
&lt;p&gt;D’où l’image qui m’a servi de boussole : une valise numérique. Autour d’elle, les outils changent et se multiplient ; à l’intérieur, le contenu évolue, mais dans un écosystème cohérent qui le garde lisible. Pour un projet, cette valise transporte non seulement des données, mais aussi les règles qui les gouvernent. Les enjeux montent d’un cran — sécurité, confidentialité — et l’exigence avec.&lt;&#x2F;p&gt;
&lt;p&gt;Et traverser le temps ne tient pas qu’à la robustesse : ça demande de la souveraineté. Des formats ouverts, exportables, des briques qu’on peut reprendre ailleurs le jour où l’outil qui les rassemble disparaît. Sinon, la valise est verrouillée chez quelqu’un d’autre.&lt;&#x2F;p&gt;
&lt;p&gt;C’est là qu’arrive Supabase — et ce qui m’a décidé, ce n’est pas l’outil en lui-même, mais les briques open source qu’il assemble, toutes reconnues dans leur domaine : PostgreSQL pour les données (référence mondiale depuis trente ans), PostgREST pour exposer la base en API REST, Auth pour l’authentification, Storage compatible S3 pour les fichiers — et d’autres encore. Supabase n’est pas la valise : c’est l’assemblage qui la forme. Le jour où je change d’assemblage, les briques restent. Mes données, mon schéma, mes règles aussi.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;atelier.clavelier.me&#x2F;articles&#x2F;backend-supabase-pilote-par-api&#x2F;jour01-projet.png&quot; alt=&quot;Le tableau de bord du projet Supabase : base de données, PostgREST, Auth, Realtime, Storage et Edge Functions, tous en état sain, sur une instance hébergée à Paris.&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;jour-2-premiere-requete-le-catalogue-repond&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#jour-2-premiere-requete-le-catalogue-repond&quot; aria-label=&quot;Anchor link for: jour-2-premiere-requete-le-catalogue-repond&quot;&gt;Jour 2 — Première requête : le catalogue répond&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Le Cellier s’expose en API REST, un standard que presque tous les outils savent parler : un terminal, du code, n’importe quel créateur d’interface. Moi, je dialogue avec depuis Bruno — un client local et open source — donc tout reste sur ma machine.&lt;&#x2F;p&gt;
&lt;p&gt;Pour entrer, deux choses : l’adresse du projet et une clé publique. Cette clé n’est pas un mot de passe ; elle franchit juste la première porte — « je suis bien un client de ce projet ». Ce que je pourrai lire ou écrire ensuite, c’est la RLS — les règles d’accès ligne par ligne — qui le décide. La démo le montre : sans clé, refus ; avec, le catalogue répond — 14 160 cuvées et 130 domaines. Et pour les compter, une petite fonction dédiée plutôt que d’ouvrir toute l’API au comptage : n’exposer que ce dont on a besoin, rien de plus — dès le premier geste.&lt;&#x2F;p&gt;

&lt;video controls preload=&quot;metadata&quot; src=&quot;jour02.mp4&quot;&gt;&lt;&#x2F;video&gt;
&lt;h2 id=&quot;jour-3-chercher-filtrer-paginer-tout-dans-l-url&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#jour-3-chercher-filtrer-paginer-tout-dans-l-url&quot; aria-label=&quot;Anchor link for: jour-3-chercher-filtrer-paginer-tout-dans-l-url&quot;&gt;Jour 3 — Chercher, filtrer, paginer : tout dans l’URL&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Aucune fonction écrite, aucune vue préparée : tout se joue dans la construction de l’URL. D’abord paginer — je demande les cuvées 100 par 100 et la base me renvoie le total ; avec ces deux nombres, tourner les pages se fait tout seul. Ensuite affiner : un cru entre 30 et 80 €, dans un millésime récent, du moins cher au plus cher. J’écris la demande morceau par morceau dans l’URL, et la base renvoie exactement ça. Ici, « cru » n’est pas un filtre prévu d’avance : c’est juste un mot que je cherche dans le nom de la cuvée et que je glisse dans l’adresse, comme dans une barre de recherche.&lt;&#x2F;p&gt;
&lt;p&gt;Enfin relier : je veux le domaine de chaque cuvée — son producteur, sa région. C’est une jointure ; j’ajoute un mot, « domaine », et chaque vin arrive avec le sien, sans avoir à préciser comment. La base sait déjà qui est lié à qui. Chercher, trier, borner, relier : tout est là, de série — sur plus de 14 000 lignes, en une fraction de seconde.&lt;&#x2F;p&gt;

&lt;video controls preload=&quot;metadata&quot; src=&quot;jour03.mp4&quot;&gt;&lt;&#x2F;video&gt;
&lt;h2 id=&quot;jour-4-inscription-et-double-authentification&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#jour-4-inscription-et-double-authentification&quot; aria-label=&quot;Anchor link for: jour-4-inscription-et-double-authentification&quot;&gt;Jour 4 — Inscription et double authentification&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;L’inscription est étonnamment simple : un email, un mot de passe, et en retour un jeton — une sorte de bracelet d’entrée qui dit « c’est bien moi ». Plus tard, se réidentifier sera le même geste. Mais un mot de passe, même solide, reste un seul rempart. Alors je suis allé plus loin : la double authentification, le fameux code à six chiffres — et toute sa mécanique tient dans l’API.&lt;&#x2F;p&gt;
&lt;p&gt;Trois appels suffisent. L’enrôlement, où la base prépare le second facteur (elle me renvoie le secret, que je colle dans mon application d’authentification). Le défi, où je la préviens que je vais prouver mon identité. La vérification, où je tape les six chiffres affichés sur mon téléphone. En retour, un jeton de niveau supérieur (aal2) : c’est lui qui pourra ouvrir l’accès aux données protégées. Le tout en une minute, en direct dans Bruno, sans montage. Note sécurité : jetons et secret s’affichent en clair à l’écran — ce qu’on ne fait jamais en vrai — mais c’est un compte de test sans aucun privilège, et ces jetons sont de courte durée.&lt;&#x2F;p&gt;

&lt;video controls preload=&quot;metadata&quot; src=&quot;jour04.mp4&quot;&gt;&lt;&#x2F;video&gt;
&lt;h2 id=&quot;jour-5-plusieurs-niveaux-d-acces&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#jour-5-plusieurs-niveaux-d-acces&quot; aria-label=&quot;Anchor link for: jour-5-plusieurs-niveaux-d-acces&quot;&gt;Jour 5 — Plusieurs niveaux d’accès&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Une seule table, &lt;code&gt;profils&lt;&#x2F;code&gt;, un même utilisateur, trois comportements. Sans jeton, la lecture de mon profil ne renvoie rien. Avec mon jeton d’entrée (aal1), il apparaît, prénom et nom encore à remplir. Mais quand je tente de le modifier : refus. Mon jeton prouve qui je suis, la règle veut davantage pour écrire — un second facteur que je n’ai pas encore prouvé dans cette session. (Côté sécurité, ce refus, je pourrais le rendre muet face à quelqu’un qui sonde ; ici je l’affiche parce que je montre.)&lt;&#x2F;p&gt;
&lt;p&gt;Alors je passe au second facteur — défi, vérification, six chiffres — et la base me rend un jeton aal2, celui qui autorise l’écriture. Je rejoue ma modification : acceptée. Une règle qui change de comportement selon le niveau d’authentification, le tout dans la base, sans aucun middleware. Exiger ça pour un prénom, c’est exagéré, j’en conviens ; ce qui compte, c’est le mécanisme.&lt;&#x2F;p&gt;

&lt;video controls preload=&quot;metadata&quot; src=&quot;jour05.mp4&quot;&gt;&lt;&#x2F;video&gt;
&lt;h2 id=&quot;jour-6-stockage-de-fichiers&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#jour-6-stockage-de-fichiers&quot; aria-label=&quot;Anchor link for: jour-6-stockage-de-fichiers&quot;&gt;Jour 6 — Stockage de fichiers&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Le Storage de Supabase, compatible S3, se pilote depuis l’API comme le reste. Sans jeton, déposer un fichier est refusé d’emblée. Je me connecte : avec mon jeton, l’envoi passe. Sophie dépose deux fichiers, Pierre — un autre compte — en dépose un. Trois fichiers dans le bucket.&lt;&#x2F;p&gt;
&lt;p&gt;Vient le moment que je trouve fort : je demande la liste de &lt;strong&gt;tous&lt;&#x2F;strong&gt; les fichiers. Avec le jeton de Sophie, deux ; avec celui de Pierre, un seul ; sans jeton, rien. La même requête, mot pour mot — aucun filtre, je ne demande pas « mes » fichiers, mais tous. C’est la RLS qui décide ce qui existe ou non pour chacun : le jeton change, la réalité avec lui. Un détail que je n’ai pas soigné dans la démo mais qui compte en vrai : ranger chaque fichier dans un dossier au nom de son propriétaire, pour que deux « photo.jpg » ne se télescopent jamais.&lt;&#x2F;p&gt;

&lt;video controls preload=&quot;metadata&quot; src=&quot;jour06.mp4&quot;&gt;&lt;&#x2F;video&gt;
&lt;h2 id=&quot;jour-7-le-role-qui-voyage-dans-le-jeton&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#jour-7-le-role-qui-voyage-dans-le-jeton&quot; aria-label=&quot;Anchor link for: jour-7-le-role-qui-voyage-dans-le-jeton&quot;&gt;Jour 7 — Le rôle qui voyage dans le jeton&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Les rôles. Dans Le Cellier, trois types d’utilisateurs : client, sommelier, administrateur. J’ai traité le sujet de deux façons.&lt;&#x2F;p&gt;
&lt;p&gt;La première, classique : un enum dans la table &lt;code&gt;profils&lt;&#x2F;code&gt; — client ou sommelier — protégé par un GRANT. Seul l’admin peut promouvoir, impossible de se proclamer sommelier.&lt;&#x2F;p&gt;
&lt;p&gt;La seconde m’a bien plus marqué : le rôle d’administrateur vit dans le jeton lui-même. Ce jeton est signé par Supabase, et une signature, n’importe qui peut la vérifier avec la clé publique. Dans la démo, deux utilisateurs se connectent — un client de la cave, un administrateur — et j’envoie leur jeton à un webhook : le premier est refusé, le second accepté. Ce qui reçoit, c’est un scénario n8n, une application totalement séparée du Cellier : elle récupère la clé publique du projet, vérifie le jeton, lit s’il porte le rôle admin, et tranche — sans jamais interroger la base.&lt;&#x2F;p&gt;
&lt;p&gt;Et c’est là tout l’intérêt : une application qui n’a rien à voir avec Le Cellier sait authentifier mes utilisateurs et lire leur rôle, juste en vérifiant une signature. L’authentification Supabase peut donc servir d’identité à d’autres applications que celle pour laquelle elle a été pensée — un rôle qui voyage comme une preuve signée, lisible partout. Ce qu’un simple enum en base ne permet pas.&lt;&#x2F;p&gt;

&lt;video controls preload=&quot;metadata&quot; src=&quot;jour07.mp4&quot;&gt;&lt;&#x2F;video&gt;
&lt;h2 id=&quot;jour-8-passer-commande&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#jour-8-passer-commande&quot; aria-label=&quot;Anchor link for: jour-8-passer-commande&quot;&gt;Jour 8 — Passer commande&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Le morceau le plus dense de la série. Passer commande, ce n’est pas ajouter une ligne dans une table : c’est un enchaînement de règles métier qui vivent toutes dans PostgreSQL. D’abord, être connecté — sans utilisateur authentifié, aucune commande. On crée une commande vide, dont le client doit être l’utilisateur connecté : pas de commande au nom d’un autre.&lt;&#x2F;p&gt;
&lt;p&gt;Une fonction &lt;code&gt;acheter&lt;&#x2F;code&gt; est ensuite la seule porte d’écriture des lignes de commande — impossible d’en glisser une à la main. Elle vérifie l’appartenance, le statut ouvert, le stock disponible. Elle décrémente le stock dans la foulée : pas de survente. Le prix est figé par la base, jamais reçu du client. Tout tient en trois paramètres : la commande, la cuvée, le nombre de bouteilles.&lt;&#x2F;p&gt;
&lt;p&gt;Petit bonus métier : un trigger offre automatiquement une bouteille dès que la commande passe 100 €. Personne ne l’a demandée — elle apparaît seule dans l’état de la commande, qu’on lit via une seconde fonction. Quant au total, il n’est jamais stocké mais recalculé à la volée : une copie figée finirait par diverger des lignes.&lt;&#x2F;p&gt;

&lt;video controls preload=&quot;metadata&quot; src=&quot;jour08.mp4&quot;&gt;&lt;&#x2F;video&gt;
&lt;h2 id=&quot;jour-9-paiement-stripe-securise&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#jour-9-paiement-stripe-securise&quot; aria-label=&quot;Anchor link for: jour-9-paiement-stripe-securise&quot;&gt;Jour 9 — Paiement Stripe sécurisé&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;La commande d’hier est restée en attente. Il est temps de payer. Au programme : un vrai paiement Stripe, depuis Bruno.&lt;&#x2F;p&gt;
&lt;p&gt;Un appel API déclenche le paiement. Côté serveur, une Edge Function — du code hébergé par Supabase — recalcule le montant (jamais envoyé par le client : impossible de payer 1 € une commande à 100 €) et demande à Stripe une page de paiement Checkout, dont elle me renvoie l’URL. J’ouvre la page, je paie avec une carte de test. Stripe me redirige vers une confirmation « Paiement réussi »… servie elle aussi par Supabase. Je rejoue la requête d’état : la commande est passée à « payée », sans que personne n’y ait touché à la main.&lt;&#x2F;p&gt;
&lt;p&gt;En coulisses, ce n’est pas ce retour qui valide — il est falsifiable. C’est Stripe qui notifie Supabase via un webhook, avec un message signé. La fonction vérifie la signature avant de toucher à la commande. Pas de signature valide, pas de statut « payée ». La clé secrète Stripe n’a jamais quitté Supabase.&lt;&#x2F;p&gt;

&lt;video controls preload=&quot;metadata&quot; src=&quot;jour09.mp4&quot;&gt;&lt;&#x2F;video&gt;
&lt;h2 id=&quot;jour-10-conclusion&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#jour-10-conclusion&quot; aria-label=&quot;Anchor link for: jour-10-conclusion&quot;&gt;Jour 10 — Conclusion&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Dix posts, brique après brique. Inscription, double authentification, niveaux d’accès, recherche paginée, fichiers isolés par propriétaire, commandes avec garde-fous métier, rôles vérifiables hors Supabase, paiement Stripe complet. Le tout piloté par API, sans front, sans infrastructure à administrer, et sans qu’aucune clé sensible ne circule où elle ne devrait pas.&lt;&#x2F;p&gt;
&lt;p&gt;Je me suis dit plusieurs fois « ça, ça va être compliqué ». La double authentification, le webhook signé Stripe, le rôle portable vérifié par un outil externe. À chaque fois, ça tenait en quelques requêtes. La seule limite rencontrée : pas de page HTML rendue sur le domaine par défaut — ma confirmation s’est affichée en texte brut. Une protection anti-abus, compréhensible.&lt;&#x2F;p&gt;
&lt;p&gt;Et pour la première et seule fois de la série, un aperçu de l’intérieur de la valise : le schéma des tables reliées — en couverture — et, ici, la table des commandes : la première ligne est celle de la démo, passée à « payée » au post 9. Les données, le schéma, les règles métier : tout est exportable, comme promis au premier jour. La série s’arrête ici, la cave reste pleine.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;atelier.clavelier.me&#x2F;articles&#x2F;backend-supabase-pilote-par-api&#x2F;jour10-commandes.jpg&quot; alt=&quot;La table des commandes dans l’éditeur Supabase : 101 lignes, la première au statut « payee ».&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;en-complement-le-jeton-jwt&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#en-complement-le-jeton-jwt&quot; aria-label=&quot;Anchor link for: en-complement-le-jeton-jwt&quot;&gt;En complément — Le jeton JWT&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;On a beaucoup parlé de JWT dans cette série. À l’écran, ça ressemble à une longue chaîne de caractères — on imagine un truc bien chiffré. Pas du tout.&lt;&#x2F;p&gt;
&lt;p&gt;J’ai glissé une donnée bidon dans le jeton de l’admin — &lt;code&gt;mon_secret&lt;&#x2F;code&gt; — et je l’ai collé dans &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;jwt.io&quot;&gt;jwt.io&lt;&#x2F;a&gt;. Le site affiche tout en clair : protocole de signature, adresse du projet, identité, rôle, et le « secret » ironique. Un JWT, c’est du base64 &lt;strong&gt;signé&lt;&#x2F;strong&gt;, pas chiffré. La signature prouve l’authenticité, mais le contenu est lisible par tout le monde. On n’y met donc jamais de secret.&lt;&#x2F;p&gt;
&lt;p&gt;Une nuance sur cette signature, parce qu’elle se comprend souvent de travers : pour la valider, jwt.io va chercher la clé publique à l’adresse inscrite dans le jeton. Ça prouve que le jeton est cohérent avec l’adresse qu’il affiche, pas qu’il vient du bon projet — c’est le jeton lui-même qui désigne où aller vérifier. En vrai, on contrôle toujours avec la clé qu’on détient déjà de son côté.&lt;&#x2F;p&gt;

&lt;video controls preload=&quot;metadata&quot; src=&quot;bonus-jwt.mp4&quot;&gt;&lt;&#x2F;video&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Une belle expérience, très formatrice : un backend qui pourrait être bien réel, monté brique par brique. Je n’ai fait qu’effleurer la surface des possibilités — il me reste énormément à explorer. Supabase m’a étonné par le peu de limites que j’y ai rencontrées, et c’est précisément ce qui m’impressionne autant que ça me plaît. À suivre, dans d’autres aventures.&lt;&#x2F;p&gt;
</content>
        
    </entry>
</feed>
