Chiffrement de bout en bout, avec les clés sur tes propres appareils
Happier garde une session de code synchronisée entre l’ordinateur où elle tourne et chaque appareil depuis lequel tu la suis, et un serveur relay se tient au milieu. Cette page, c’est l’architecture cachée derrière cette phrase : quelle clé est créée où, ce que le relay détient réellement, ce qu’il peut malgré tout voir, et ce qui change sur un serveur configuré pour désactiver le chiffrement.
Comment un message est chiffré entre ton téléphone et ton ordinateur
Un message que tu envoies depuis ton téléphone, représenté aux trois points par lesquels il passe. Tout ce que l’agent répond suit le même chemin en sens inverse, scellé sur ton ordinateur avant de partir.
- Ton téléphone
- Scellé ici. Le message est chiffré sur l’appareil où tu l’as tapé, sous une clé qui appartient à cette session et à rien d’autre — 32 octets aléatoires tirés à la création de la session, AES-256-GCM, un nonce neuf par message. La clé de session est ensuite scellée avec la clé propre à ton compte via un échange X25519 éphémère, et c’est la copie scellée qui est remise au relay.
- Le relay
- Transporté scellé. Ce que le serveur écrit, c’est une ligne de la forme { t: "encrypted", c: "…" } — du base64, plus une enveloppe de clé scellée dont il n’a aucune clé secrète. Il peut router cette ligne, la compter, la conserver et la restituer. Il n’a rien pour l’ouvrir, et aucun endpoint ne le lui demande.
- Ton ordinateur
- Ouvert ici. Le CLI ouvre la clé de session scellée avec la clé de compte qui lui a été donnée quand tu as connecté le terminal, déchiffre, et transmet le texte en clair à Claude Code, Codex, OpenCode ou à l’agent qui tourne. La réponse fait le même trajet en sens inverse, scellée avant de partir.
Ce que stocke le serveur relay
Le chiffrement est une affirmation sur le contenu, et une affirmation sur le contenu n’est qu’une demi-réponse. Voici l’autre moitié, au même niveau de détail : les colonnes qu’un serveur exploitant ce relay peut lire sans clé.
- Du texte chiffré, et une enveloppe de clé scellée
- Une ligne par message, contenant du base64 et rien d’autre, plus la clé de données encapsulée de la session. L’encapsulation se fait sur un appareil ; aucune route serveur n’en produit.
- Identifiants et forme
- Les identifiants de compte, d’appareil et de session, un tag aléatoire par session, des numéros de séquence, des horodatages et des tailles. C’est la partie que le chiffrement ne couvre sur aucun système qui synchronise, et il vaut mieux le dire franchement : le relay sait combien tu as envoyé et quand.
- De quel côté vient chaque message
- Chaque message porte un rôle — utilisateur, agent, événement ou inconnu — fourni par le client à côté du texte chiffré. C’est une colonne, pour qu’une transcription puisse être paginée et comptée sans être ouverte. Sur une ligne chiffrée, le serveur ne peut pas le déduire ; il ne peut que stocker ce que le client a déclaré.
- Une projection d’activité volontairement minuscule
- Si une session est non lue, combien de demandes de permission attendent, combien de questions l’agent a posées, s’il est en train de réfléchir, comment le dernier tour s’est terminé. Chacune de ces informations est un état dérivé — un compteur, un drapeau ou un horodatage que le client écrit à mesure qu’une session avance — jamais un mot de ce qui a été dit. Cela existe pour qu’un téléphone resté fermé une heure affiche le bon badge dès que tu l’ouvres, et compter est le maximum que le serveur reçoive pour ça.
- Ce que tu as tapé, et ce que l’agent a répondu
- La transcription, c’est le texte chiffré. Il n’y a pas de seconde copie, pas d’index côté serveur dessus, et aucune étape de résumé qui en aurait besoin.
- Où la session tourne
- Le chemin du projet, ton nom d’hôte, ton répertoire personnel et la version du CLI sont des métadonnées de session, et les métadonnées sont chiffrées avec la même clé de session avant que la session ne soit créée. Ce sont des champs à l’intérieur d’un blob scellé, pas des colonnes sur lesquelles le serveur peut trier.
- Tes identifiants de provider
- Un compte connecté — l’identifiant Claude ou ChatGPT sous lequel tourne une session — est scellé sur l’appareil avant d’être envoyé, sous une clé dérivée pour ce seul usage à partir du secret de ton compte. Le relay stocke une enveloppe et la restitue à tes propres appareils.
- Ton dépôt
- Ton dépôt n’est jamais synchronisé ni mis en miroir. L’agent lit et écrit les fichiers sur l’ordinateur où il tourne, et cet ordinateur reste la seule copie complète. Quand tu demandes un fichier, un dossier ou un diff, il emprunte le même chemin scellé que tout le reste — parce que tu l’as demandé, pas parce que Happier en garde une copie.
Tes clés de chiffrement sont créées sur ton propre appareil
Il y a un secret à la racine de ton compte, et il est créé sur un appareil — pas délivré par un serveur. Tout le reste en est dérivé par un arbre de clés : une racine HMAC-SHA-512, puis une étape HMAC par élément de chemin étiqueté. La paire de clés qui ouvre les clés de session scellées sort de cet arbre sous le label "content", et il en va de même pour une clé distincte par type de blob stocké, de sorte qu’aucune clé ne fait deux métiers.
C’est pour ça qu’un navigateur tout neuf peut se connecter à ton compte sans rien te montrer de la semaine dernière. Se connecter prouve qui tu es auprès du relay. Lire une ancienne session demande la clé, et la clé n’est pas sur le relay pour être envoyée. Restaurer l’appareil, c’est l’étape qui la déplace — depuis un appareil qui l’a déjà, ou depuis la clé secrète que tu as conservée.
Cela signifie aussi que le cas de perte est réel et mérite d’être énoncé une fois : si tous les appareils connectés ont disparu et que la clé secrète a disparu avec eux, les sessions chiffrées ne peuvent être récupérées ni par nous ni par personne. Un relay capable de les restituer serait un relay capable de les lire.
Lier un nouvel appareil, et comment tes clés lui parviennent
Ajouter un appareil, c’est le moment où le matériel cryptographique se déplace : c’est donc le moment qui mérite d’être compris. Scanner le QR code lève une demande, et c’est tout ce que ça fait : l’approbation a lieu sur un appareil déjà connecté, et quand les deux écrans affichent un court code de confirmation, tu es censé les comparer avant d’approuver.
Ce que fait réellement l’approbation, c’est sceller la clé de contenu avec la clé publique de l’appareil demandeur, dans une enveloppe portant une clé d’émetteur éphémère et un nonce neuf. Cette enveloppe traverse le relay comme tout le reste. Connecter un terminal ajoute une liaison de plus par-dessus : la charge utile est authentifiée contre un secret d’appairage qui a voyagé dans le QR code, pas à travers le serveur, de sorte qu’un relay qui échangerait la charge utile ne pourrait pas produire un tag correspondant.
Politique de stockage : le chiffrement de bout en bout est le réglage par défaut
Tout ce qui précède décrit le réglage par défaut, et ce défaut n’est pas une suggestion que le client pourrait faire changer d’avis au serveur. Un relay neuf est réglé pour exiger un stockage chiffré de bout en bout : une écriture en clair est refusée avec une erreur de politique plutôt qu’acceptée en silence. Les clients lisent la politique depuis l’endpoint de features du serveur avant de créer une session, donc le mode d’une session est convenu avant son premier message.
Un opérateur de serveur dispose de deux autres réglages. L’un peut laisser un compte choisir, si bien que des sessions chiffrées et en clair coexistent sur le même relay — il faut à la fois la politique optionnelle et l’autorisation de désactivation, et cette autorisation est désactivée tant que l’opérateur ne l’active pas. L’autre exige le texte clair, pour les organisations qui gèrent le chiffrement au niveau infrastructure et ont besoin que le serveur puisse lire et traiter le contenu des sessions. Ce dernier est un vrai compromis et il vaut la peine de le dire sans l’adoucir : sur une session en clair, le serveur peut lire la transcription. C’est tout l’objet du réglage.
Le mode est fixé par session à la création, donc une session n’est jamais à moitié dans chacun, et changer le mode d’un compte change ce qui arrive aux nouvelles sessions plutôt que de revenir sur les anciennes. Rien n’est déchiffré rétroactivement, et rien n’est chiffré rétroactivement non plus.
Les variables qui règlent ces trois points, les options de chiffrement au repos en dessous et les contrôles d’identité autour constituent la moitié opérateur du sujet, et vivent sur la page d’auto-hébergement pour les équipes.
Les notifications push sont envoyées par ton propre ordinateur
La notification push est la seule chose qui sort du modèle, parce qu’elle doit arriver sur un téléphone où rien n’est ouvert. La réponse de Happier, c’est que c’est ton propre ordinateur qui les envoie. Le serveur stocke tes tokens push ; le CLI sur ton propre ordinateur les relit et envoie lui-même la notification, ce qui garde le relay hors d’un chemin où il faudrait sinon lui dire le contenu.
Ce que porte la charge utile est volontairement maigre : le type d’outil ou de requête, et un court indice quand il aide — un fichier comme src/file.ts, un nom de commande, un décompte du type « 3 questions ». L’entrée brute des outils n’y est pas mise. De quoi décider s’il faut attraper le téléphone, sur un écran que n’importe qui derrière toi peut lire.
Relay auto-hébergé : les métadonnées restent elles aussi sur ton matériel
Tout cela tient sur un relay que tu ne fais pas tourner. La raison d’en faire tourner un à toi, c’est la ligne ci-dessus sur les identifiants et la forme : le chiffrement ne cache pas qui parle à qui, ni à quelle fréquence, et sur ton propre relay ce registre est à toi aussi. Une commande place le relay sur du matériel qui t’appartient, et le chemin devient ton appareil, ton relay, ton ordinateur, sans rien dedans que tu n’aies déployé.
Lis le code de chiffrement toi-même
Il n’y a aucune certification sur cette page parce qu’il n’y en a aucune à rapporter, et une page de sécurité qui fait signe vers une conformité qu’elle n’a pas est pire qu’une page qui n’en parle pas. Ce qu’il y a à la place, c’est le code à partir duquel chaque phrase ci-dessus a été écrite, sous licence MIT et lisible avant que tu ne l’exécutes : les primitives dans packages/protocol/src/crypto, le chiffrement de session dans apps/cli/src/api/encryption.ts, la politique de stockage que le serveur applique dans son endpoint de features, et le schéma qui montre exactement quelles colonnes sont en clair.
C’est aussi la réponse honnête à la façon dont tu devrais traiter cette page : comme une carte indiquant où regarder, pas comme une promesse à prendre sur parole. Lis les quatre fichiers, ou fais tourner le relay toi-même et lis ce qu’il annonce à ses clients.
La référence du modèle de chiffrement couvre le même terrain sous forme de procédure — ce qu’une restauration te demande, ce que chaque mode de stockage implique pour un compte, et vers quel flux se tourner quand un appareil ne peut pas encore lire une session.

