Crittografia end-to-end, con le chiavi sui tuoi dispositivi
Happier tiene sincronizzata una sessione di coding tra il computer su cui gira e ogni dispositivo da cui la guardi, e in mezzo c’è un server relay. Questa pagina è l’architettura sotto quella frase: quale chiave viene creata dove, cosa contiene davvero il relay, cosa può comunque vedere, e cosa cambia su un server configurato per disattivare la crittografia.
Come viene crittografato un messaggio tra il tuo telefono e il tuo computer
Un messaggio che invii dal telefono, disegnato nei tre punti che attraversa. Tutto ciò che l’agente risponde percorre la stessa strada nella direzione opposta, sigillato sul tuo computer prima di partire.
- Il tuo telefono
- Sigillato qui. Il messaggio viene crittografato sul dispositivo su cui lo hai digitato, con una chiave che appartiene a quella sessione e a nient’altro — 32 byte casuali estratti alla creazione della sessione, AES-256-GCM, un nonce nuovo per ogni messaggio. La chiave di sessione viene poi sigillata con la chiave del tuo account tramite uno scambio X25519 effimero, ed è la copia sigillata quella che viene consegnata al relay.
- Il relay
- Trasportato sigillato. Quello che il server scrive è una riga della forma { t: "encrypted", c: "…" } — base64, più una busta di chiave sigillata per cui non ha alcuna chiave segreta. Può instradare quella riga, contarla, conservarla e restituirla. Non ha nulla con cui aprirla, e nessun endpoint glielo chiede.
- Il tuo computer
- Aperto qui. La CLI apre la chiave di sessione sigillata con la chiave dell’account che le è stata data quando hai collegato il terminale, decritta e passa il testo in chiaro a Claude Code, Codex, OpenCode o a qualunque agente sia in esecuzione. La risposta fa lo stesso viaggio al contrario, sigillata prima di partire.
Cosa memorizza il server relay
La crittografia è un’affermazione sul contenuto, e un’affermazione sul contenuto è solo metà risposta. Ecco l’altra metà, con lo stesso livello di dettaglio: le colonne che un operatore di questo relay può leggere senza una chiave.
- Testo cifrato, e una busta di chiave sigillata
- Una riga per messaggio, che contiene base64 e nient’altro, più la chiave dati incapsulata della sessione. L’incapsulamento avviene su un dispositivo; nessuna rotta del server ne produce uno.
- Identificatori e forma
- Id di account, dispositivi e sessioni, un tag casuale per sessione, numeri di sequenza, timestamp e dimensioni. Questa è la parte che la crittografia non copre su nessun sistema che si sincronizza, e vale la pena dirlo chiaramente: il relay sa quanto hai inviato e quando.
- Da quale parte è arrivato ogni messaggio
- Ogni messaggio porta un ruolo — utente, agente, evento o sconosciuto — fornito dal client insieme al testo cifrato. È una colonna, così una trascrizione può essere paginata e conteggiata senza essere aperta. Su una riga crittografata il server non può ricavarlo; può solo memorizzare quello che il client ha dichiarato.
- Una proiezione di attività deliberatamente ridotta
- Se una sessione è da leggere, quante richieste di permesso sono in attesa, quante domande ha posto l’agente, se sta pensando, come è finito l’ultimo turno. Ognuna di queste è uno stato derivato — un contatore, un flag o un timestamp che il client scrive mentre una sessione avanza — mai una parola di ciò che è stato detto. Esiste perché un telefono rimasto chiuso per un’ora mostri un badge corretto nel momento in cui lo apri, e contare è il massimo che il server riceve per farlo.
- Quello che hai scritto, e quello che l’agente ha risposto
- La trascrizione è il testo cifrato. Non c’è una seconda copia, nessun indice lato server su di essa, e nessun passaggio di riassunto che ne avrebbe bisogno.
- Dove è in esecuzione la sessione
- Il percorso del progetto, il tuo hostname, la tua home directory e la versione della CLI sono metadati di sessione, e i metadati vengono crittografati con la stessa chiave di sessione prima che la sessione venga creata. Sono campi dentro un blob sigillato, non colonne su cui il server possa ordinare.
- Le tue credenziali del provider
- Un account collegato — la credenziale Claude o ChatGPT con cui gira una sessione — viene sigillato sul dispositivo prima di essere caricato, con una chiave derivata per quello scopo soltanto dal segreto del tuo account. Il relay memorizza una busta e la restituisce ai tuoi dispositivi.
- Il tuo repository
- Il tuo repository non viene mai sincronizzato né rispecchiato. L’agente legge e scrive file sul computer su cui gira, e quel computer resta l’unica copia completa. Quando chiedi un file, una cartella o un diff, questi percorrono lo stesso percorso sigillato di tutto il resto — perché li hai chiesti tu, non perché Happier ne tenga una copia.
Le tue chiavi di crittografia vengono create sul tuo dispositivo
C’è un solo segreto alla radice del tuo account, e viene creato su un dispositivo — non emesso da un server. Tutto il resto ne deriva tramite un albero di chiavi: una radice HMAC-SHA-512, poi un passo HMAC per ogni elemento di percorso etichettato. La coppia di chiavi che apre le chiavi di sessione sigillate esce da quell’albero sotto l’etichetta "content", e così pure una chiave separata per ogni altro tipo di blob memorizzato, così nessuna chiave fa due lavori.
È per questo che un browser nuovo di zecca può accedere al tuo account e non mostrarti comunque nulla della settimana scorsa. Accedere dimostra al relay chi sei. Leggere una vecchia sessione richiede la chiave, e la chiave non è sul relay da inviare. Ripristinare il dispositivo è il passo che la sposta — da un dispositivo che la ha già, o dalla chiave segreta che hai conservato.
Significa anche che il caso di perdita è reale e vale la pena dirlo una volta: se tutti i dispositivi connessi sono spariti e con essi la chiave segreta, le sessioni crittografate non possono essere recuperate né da noi né da nessun altro. Un relay che potesse restituirle sarebbe un relay che potrebbe leggerle.
Collegare un nuovo dispositivo, e come le tue chiavi ci arrivano
Aggiungere un dispositivo è il momento in cui si sposta il materiale delle chiavi, quindi è il momento che vale la pena capire. Scansionare il codice QR solleva una richiesta, e non fa altro: l’approvazione avviene su un dispositivo già connesso, e quando entrambi gli schermi mostrano un breve codice di conferma sei tenuto a confrontarli prima di approvare.
Quello che l’approvazione fa davvero è sigillare la chiave dei contenuti con la chiave pubblica del dispositivo che l’ha chiesta, in una busta che porta una chiave mittente effimera e un nonce nuovo. Quella busta attraversa il relay come tutto il resto. Collegare un terminale aggiunge un ulteriore vincolo: il payload è autenticato rispetto a un segreto di abbinamento che ha viaggiato nel codice QR, non attraverso il server, così un relay che sostituisse il payload non riuscirebbe a produrre un tag corrispondente.
Policy di archiviazione: la crittografia end-to-end è l’impostazione predefinita
Tutto quanto sopra descrive l’impostazione predefinita, e l’impostazione predefinita non è un suggerimento che il client possa far cambiare al server. Un relay appena installato è impostato per richiedere archiviazione crittografata end-to-end: una scrittura in chiaro viene rifiutata con un errore di policy anziché essere accettata in silenzio. I client leggono la policy dall’endpoint features del server prima di creare una sessione, quindi la modalità in cui si trova una sessione è stata concordata prima del suo primo messaggio.
Un operatore del server ha altre due impostazioni disponibili. Una può permettere a un account di scegliere, così sessioni crittografate e in chiaro coesistono sullo stesso relay — richiede sia la policy opzionale sia il permesso di opt-out, e quel permesso è disattivato a meno che l’operatore non lo attivi. L’altra richiede il testo in chiaro, per le organizzazioni che gestiscono la crittografia a livello di infrastruttura e hanno bisogno che il server possa leggere ed elaborare il contenuto delle sessioni. Quest’ultima è un compromesso reale e vale la pena dirlo senza addolcirlo: in una sessione in chiaro il server può leggere la trascrizione. È questo il senso dell’impostazione.
La modalità è fissata per sessione al momento della creazione, così una sessione non è mai metà dell’una e metà dell’altra, e cambiare la modalità di un account cambia cosa succede alle nuove sessioni anziché tornare indietro su quelle vecchie. Nulla viene decrittato retroattivamente, e nulla viene crittografato retroattivamente.
Le variabili che impostano tutti e tre, le opzioni a riposo che stanno sotto e i controlli di identità che le circondano sono la metà che riguarda l’operatore, e vivono su la pagina sul self-hosting per i team.
Le notifiche push le invia il tuo stesso computer
Una notifica push è l’unica cosa che esce dal modello, perché deve arrivare a un telefono che non ha nulla di aperto. La risposta di Happier è che a inviarle è il tuo stesso computer. Il server memorizza i tuoi token push; la CLI sul tuo computer li rilegge e invia la notifica da sé, il che tiene il relay fuori da un percorso in cui altrimenti dovrebbe conoscere i contenuti.
Quello che il payload trasporta è deliberatamente scarno: il tipo di strumento o di richiesta, e un breve indizio dove serve — un file come src/file.ts, il nome di un comando, un conteggio come “3 domande”. L’input grezzo degli strumenti non ci viene messo. Abbastanza per decidere se prendere in mano il telefono, su uno schermo che chiunque sia dietro di te può leggere.
Relay self-hosted: anche i metadati restano sul tuo hardware
Tutto questo vale anche su un relay che non gestisci tu. Il motivo per gestirne uno tuo è la riga qui sopra su identificatori e forma: la crittografia non nasconde chi parla con chi, né quanto spesso, e sul tuo relay anche quel registro è tuo. Un comando mette il relay su hardware che possiedi, e il percorso diventa il tuo dispositivo, il tuo relay, il tuo computer, senza nulla dentro che non abbia deployato tu.
Leggi tu stesso il codice della crittografia
Su questa pagina non c’è nessuna certificazione perché non ce n’è una da riportare, e una pagina sulla sicurezza che allude a una conformità che non ha è peggio di una che non la nomina affatto. Quello che c’è invece è il codice da cui è stata scritta ogni frase qui sopra, con licenza MIT e leggibile prima di eseguirlo: le primitive in packages/protocol/src/crypto, la crittografia di sessione in apps/cli/src/api/encryption.ts, la policy di archiviazione che il server applica nel suo endpoint features, e lo schema che mostra esattamente quali colonne sono in chiaro.
Questa è anche la risposta onesta a come dovresti trattare questa pagina: come una mappa di dove guardare, non come una promessa da prendere sulla fiducia. Leggi i quattro file, oppure esegui il relay tu stesso e leggi cosa dichiara ai suoi client.
Il riferimento sul modello di crittografia copre lo stesso terreno come procedura — cosa ti chiede il ripristino, cosa significa ogni modalità di archiviazione per un account, quale flusso usare quando un dispositivo non riesce ancora a leggere una sessione.

