Come accedere a Hermes dal telefono in sicurezza
Scopri tre modi per usare la dashboard di Hermes dal telefono: rete Tailscale privata, HTTPS pubblico con autenticazione o SSH, con revoca dell'accesso.
I tre modi per accedere al tuo agente Hermes dal telefono
Per accedere al tuo agente Hermes dal telefono usi la sua dashboard web. La decisione principale riguarda il componente che si trova davanti alla dashboard. La prima opzione è una rete mesh privata: la dashboard resta in ascolto solo su un indirizzo Tailscale e nessuna porta è esposta su Internet. La seconda opzione è un endpoint pubblico dietro un reverse proxy con TLS (transport layer security) e autenticazione. In questo caso, l'autenticazione è l'unica protezione davanti a un terminale del server. La terza opzione è SSH (secure shell) da un'app terminale. Richiede la configurazione più semplice e concede il livello di accesso più ampio.
Questa guida parte dal punto in cui termina eseguire un agente Hermes sul proprio VPS. L'agente è installato, risponde sulla riga di comando e ora vuoi averlo a portata di mano.
I comandi seguenti si riferiscono al tag v2026.8.3, pubblicato il 3 agosto 2026 e indicato come v0.20.0 nelle note di rilascio. Hermes rilascia spesso nuove versioni. Per questo, blocca la macchina su un tag invece di seguire main. L'installer accetta un commit:
curl -fsSL https://hermes-agent.nousresearch.com/install.sh | bash -s -- --commit 3c27eb6234bf
hermes versionhermes version mostra ciò che è effettivamente installato. Confrontalo con il tag prima di usare qualsiasi flag riportato in questa pagina.
Cosa fornisce il repository e cosa non fornisce
Nel repository Hermes non è presente alcuna app per iOS o Android. Il client nativo è hermes desktop (alias hermes gui), un'applicazione Electron per macOS, Windows e Linux. Può collegarsi a un agent remoto invece che a uno locale: in Settings, nella sezione Gateway, imposta l'URL remoto su http://<server-address>:9119 oppure esporta HERMES_DESKTOP_REMOTE_URL=http://<server-address>:9119 prima di avviarlo. Questo risolve il caso di un secondo laptop. Non offre alcuna soluzione per un telefono.
L'interfaccia utilizzabile da un telefono è hermes dashboard, cioè l'interfaccia del browser. Gestisce configurazione, sessioni, cron job, skill, log e piattaforme di messaggistica e integra un terminale: il server avvia hermes --tui dietro un PTY (pseudo-terminal) e trasmette l'output nella pagina. Su uno schermo stretto il selettore delle sessioni si apre in un pannello laterale sovrapposto, quindi il layout resta utilizzabile anche da telefono.
Per impostazione predefinita, la dashboard è in ascolto su 127.0.0.1:9119 e apre una scheda del browser direttamente sul server, cosa inutile su un VPS (virtual private server) headless. Avviala senza aprire il browser e controlla il socket:
hermes dashboard --no-open
ss -lntp | grep 9119Un listener su 127.0.0.1:9119 è raggiungibile soltanto dal server. Un listener su 0.0.0.0:9119 è raggiungibile da ogni rete a cui la macchina è connessa, inclusa la rete pubblica. Quella singola riga determina il livello di esposizione, quindi leggila invece di darlo per scontato.
Opzione 1: una mesh privata con Tailscale
Scegli questa opzione, salvo esigenze specifiche. Tailscale è una VPN mesh (rete privata virtuale) basata su WireGuard. Ogni dispositivo registrato riceve un indirizzo stabile e comunica direttamente con gli altri. Anche il telefono entra nella stessa mesh, quindi non è necessario esporre pubblicamente alcuna porta per il dashboard.
Sul server:
curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up
tailscale ip -4Installa l'app Tailscale sul telefono e accedi con lo stesso account. tailscale status sul server elenca quindi il telefono per nome. Ora associa il dashboard all'indirizzo mostrato da tailscale ip -4:
hermes dashboard --host 100.101.102.103 --port 9119 --no-openL'associazione all'indirizzo della mesh, invece che a 0.0.0.0, fa sì che il socket in ascolto esista soltanto sull'interfaccia Tailscale. Una scansione delle porte sull'indirizzo IP pubblico non trova nulla sulla porta 9119, perché non c'è alcun processo in ascolto su quella porta. Il firewall, quindi, non è più l'unico elemento che ti protegge. Verifica nuovamente con ss -lntp | grep 9119.
L'indirizzo di bind determina anche l'autenticazione. Questo è il punto che spesso viene trascurato. Su 127.0.0.1 il dashboard non richiede l'accesso. Su qualsiasi altro indirizzo il controllo di autenticazione è obbligatorio e, se non è configurato alcun provider, il server rifiuta di avviarsi. Il progetto definisce questo comportamento come chiusura in caso di errore. Eseguilo interattivamente la prima volta: ti proporrà di configurare subito un nome utente e una password. Il risultato viene scritto in ~/.hermes/.env:
HERMES_DASHBOARD_BASIC_AUTH_USERNAME=you
HERMES_DASHBOARD_BASIC_AUTH_PASSWORD_HASH=scrypt$16384$8$1$...
HERMES_DASHBOARD_BASIC_AUTH_SECRET=a-long-random-stringGenera il secret con openssl rand -hex 32, quindi non modificarlo. Viene usato per firmare il cookie di sessione, quindi cambiarlo disconnette tutti i dispositivi. Lo stesso file contiene le chiavi API dei tuoi modelli; proteggilo quindi con chmod 600 ~/.hermes/.env.
Verifica il controllo di autenticazione da un altro computer della mesh prima di considerarlo affidabile:
curl -s http://100.101.102.103:9119/api/status | jq '.auth_required, .auth_providers'true seguito da ["basic"] indica che il controllo è attivo e che il provider delle password sta rispondendo. La documentazione del progetto è chiara su questo provider: è pensato per una rete affidabile o per una VPN e non è adatto a un dashboard esposto su Internet. In una mesh, questa è esattamente la situazione in cui ti trovi.
Per usare HTTPS all'interno della tailnet, assegna la porta a Tailscale:
sudo tailscale serve --bg localhost:9119
sudo tailscale serve statusTailscale termina TLS con un certificato rilasciato per il nome MagicDNS della macchina. Il browser non mostra più avvisi e il cookie di sessione riceve il flag Secure. Prima abilita MagicDNS e HTTPS Certificates nella pagina DNS della console di amministrazione Tailscale. Leggi anche l'avvertenza: i nomi delle macchine e il nome DNS della tailnet vengono pubblicati nel registro pubblico di certificate transparency, che chiunque può consultare.
Il costo reale di questa soluzione è il server di coordinamento. Il traffico tra il telefono e il tuo VPS è crittografato end-to-end e non passa attraverso Tailscale, ma l'account che decide quali dispositivi appartengono alla mesh non risiede sul tuo hardware. Se questo aspetto è importante, esegui autonomamente il control plane con Headscale, il server di controllo Tailscale self-hosted e indirizza i client verso di esso usando tailscale up --login-server https://headscale.example.com. Se preferisci abbandonare la mesh e configurare manualmente i peer, il confronto tra WireGuard senza componenti aggiuntivi e Tailscale illustra a cosa rinunci.
Opzione 2: un endpoint HTTPS pubblico e il problema che nasconde
A volte una mesh non è disponibile. Un telefono di lavoro potrebbe non consentire l'installazione di un client VPN. In questo caso, il dashboard passa attraverso un reverse proxy. Mantieni il dashboard in ascolto su loopback e lascia che sia Caddy a gestire il certificato:
hermes.example.com {
reverse_proxy 127.0.0.1:9119
}Caddy scarica e rinnova autonomamente il certificato. Il suo reverse_proxy inoltra gli upgrade WebSocket senza direttive aggiuntive, necessarie per il terminale integrato del dashboard. Con nginx devi aggiungere manualmente gli header Upgrade e Connection. La guida all'emissione di un certificato Let's Encrypt con Certbot su nginx illustra la parte TLS della procedura. Indica a Hermes il nome pubblico, in modo che i callback di login puntino all'host corretto:
dashboard:
public_url: "https://hermes.example.com"Ora il problema. Il controllo dell'autenticazione si basa sull'indirizzo di bind, non sull'indirizzo da cui proviene la richiesta. Un dashboard associato a 127.0.0.1 e pubblicato tramite un proxy vede loopback, stabilisce che il login non è necessario e serve i contenuti a chiunque il proxy lasci passare. Verifica che cosa hai effettivamente pubblicato:
curl -s https://hermes.example.com/api/status | jq '.auth_required'Se restituisce false, basta un URL per raggiungere da Internet un terminale sul server. Non è necessario alcun exploit e nei log non comparirà alcun errore. Esistono due correzioni; devi applicarne almeno una. Puoi configurare l'autenticazione nel proxy, usando Authentik come provider single sign-on self-hosted davanti al servizio tramite forward auth, oppure configurare il provider OIDC (OpenID Connect) integrato nel dashboard:
HERMES_DASHBOARD_OIDC_ISSUER=https://auth.example.com/application/o/hermes/
HERMES_DASHBOARD_OIDC_CLIENT_ID=hermes-dashboard
HERMES_DASHBOARD_OIDC_SCOPES="openid profile email"Anche se configurata correttamente, questa opzione ha un limite minimo che non puoi ridurre. Una pagina di login pubblica è raggiungibile e attaccabile da chiunque; dietro di essa c'è una shell sul tuo VPS. Un nome utente e una password offrono una protezione limitata, per questo la documentazione raccomanda OAuth o OIDC per i bind pubblici. Applica il rate limiting al login, mantieni ufw chiuso a tutto tranne che alle porte del proxy e a SSH e controlla periodicamente l'access log.
Opzione 3: SSH e mosh da un terminale mobile
La soluzione che richiede meno lavoro: installa un'applicazione terminale sul telefono, carica al suo interno una chiave SSH e usa l'interfaccia testuale dell'agent.
ssh you@vps.example.com
tmux new -A -s phone
hermes --tuitmux new -A -s phone si collega a una sessione chiamata phone oppure la crea se non esiste. In questo modo l'agent continua a essere eseguito quando la connessione si interrompe e, la volta successiva, torni nello stesso punto. È lo stesso schema usato per controllare Claude Code da un telefono.
SSH senza ulteriori accorgimenti su una rete mobile è scomodo, perché la connessione si interrompe ogni volta che il telefono cambia indirizzo o passa in sospensione. Mosh risolve questo problema. Usa UDP (user datagram protocol) e sincronizza lo stato del terminale invece di un flusso di byte. Per questo la sessione continua a funzionare anche quando passi dal Wi-Fi alla rete cellulare:
sudo apt install -y mosh
sudo ufw allow 60000:61000/udpDal telefono, esegui mosh you@vps.example.com. Mosh avvia mosh-server tramite la sessione SSH esistente, quindi sposta la sessione su UDP nell'intervallo da 60000 a 61000. Per questo motivo è necessario lasciare aperto tale intervallo.
Il costo in termini di sicurezza è diretto. Una sessione SSH è una shell e una shell può eseguire tutte le operazioni consentite a quell'account. Le richieste di approvazione dell'agent diventano quindi l'ultima barriera tra un telefono sbloccato rubato e i tuoi file. Usa un account dedicato non-root e consenti esclusivamente l'accesso tramite chiave. Prima di aggiungere una chiave a un dispositivo che porti con te, procedi con la messa in sicurezza di SSH su un VPS.
Cosa non funziona su una rete mobile
Sono quattro aspetti, e nessuno può essere risolto modificando la configurazione.
La dashboard chiude la sessione mentre non la stai usando. I token di accesso hanno un TTL (time to live) di 15 minuti e il contratto API attuale non prevede un refresh token. Quando il token scade, la pagina riceve la risposta 401 e torna a /login. Apri la dashboard, metti il telefono in tasca per venti minuti e, quando lo riprendi, trovi la schermata di accesso con tutto ciò che stavi digitando perso. Non c'è alcun guasto. Accedi di nuovo.
Il terminale incorporato non sopravvive a una scheda in background. Il server avvia la TUI (text user interface) dietro un PTY e la chiude correttamente quando la scheda viene chiusa; riaprirla ne avvia una nuova. I browser mobili eliminano le schede in background per recuperare memoria. Di conseguenza, se passi a un'altra applicazione abbastanza a lungo, il terminale viene terminato. La cronologia della chat è al sicuro, perché le sessioni sono memorizzate sul server e hermes sessions list continua a mostrarle. Il terminale, invece, non consente di ricollegarsi alla sessione precedente. Se ti serve una sessione che sopravviva, usa tmux tramite SSH.
Le connessioni inattive si interrompono senza messaggi. Gli operatori mobili eliminano le connessioni TCP inattive per recuperare le voci delle tabelle NAT (network address translation), mentre il telefono interrompe quasi completamente la gestione della rete quando lo schermo è spento. Un WebSocket rimasto inattivo per qualche tempo è generalmente già terminato quando sblocchi il telefono, e la pagina si riconnette soltanto dopo che la tocchi. Per questo mosh risulta più affidabile di SSH su un telefono: non aveva una connessione da perdere.
Nessun componente invia notifiche push. Né la dashboard né una sessione SSH possono riattivare il telefono. Sul dispositivo non è installata alcuna app Hermes, quindi non esiste un percorso verso il servizio di notifiche push della piattaforma. Un'esecuzione prolungata dell'agent termina e te ne accorgi soltanto la volta successiva che controlli.
Le notifiche arrivano tramite il gateway di messaggistica
La soluzione per l’ultimo caso è il gateway, che offre un metodo completamente diverso per raggiungere l’agente. hermes gateway collega l’agente a piattaforme di messaggistica come Telegram, Discord, Slack, WhatsApp, Signal ed email. Puoi quindi interagire con l’agente all’interno di un’app che dispone già di un canale push sul telefono, gestisce già la distribuzione in background e gestisce già le interruzioni della rete.
hermes gateway setup
hermes gateway install
hermes gateway statushermes gateway install registra il gateway come servizio systemd, quindi il servizio torna attivo dopo un riavvio. L’installer Hermes non crea automaticamente alcuna unità di servizio, quindi hermes dashboard non tornerà attivo da solo dopo un riavvio. Scrivi un’unità per ogni componente da cui dipendi; la guida scrivere servizi e timer systemd su un VPS descrive il file da creare.
Un job pianificato può inviare un risultato nello stesso modo, senza alcuna conversazione:
hermes send -t telegram -s "Backup report" -f /home/you/report.txtL’autorizzazione segue il principio del diniego predefinito. Se non è configurata alcuna allowlist e GATEWAY_ALLOW_ALL_USERS non è impostato, ogni utente viene rifiutato. Questo è il punto di partenza corretto. Indica in ~/.hermes/.env gli account che vuoi autorizzare:
TELEGRAM_ALLOWED_USERS=123456789
GATEWAY_ALLOWED_USERS=123456789In alternativa, abilita l’associazione basata su codice invece di incollare ID numerici, impostando unauthorized_dm_behavior: pair in ~/.hermes/config.yaml. Un account sconosciuto che invia un messaggio all’agente riceve un codice di otto caratteri. Non accade altro finché non lo approvi:
hermes pairing list
hermes pairing approve telegram ABC12DEF
hermes pairing revoke telegram 123456789I codici scadono dopo un’ora, un utente può richiederne uno ogni dieci minuti e cinque tentativi non riusciti bloccano l’account.
Ridurre l'impatto di un telefono rubato
Un telefono che può raggiungere il tuo agent può eseguire comandi sul server, e i telefoni possono essere smarriti. Decidi ora quali operazioni potrà eseguire chi lo possiede.
Mantieni attive le approvazioni. approvals.mode è impostato per impostazione predefinita su smart, che chiede a un modello ausiliario di valutare il rischio e approva automaticamente solo i comandi a basso rischio. Impostarlo su off equivale a eseguire tutto con --yolo, mentre HERMES_YOLO_MODE=1 applica la stessa impostazione tramite l'ambiente. Non portare con te un telefono che comunica con un agent quando questa impostazione è attiva. Imposta approvals.cron_mode: deny, in modo che i job pianificati non possano approvare autonomamente i comandi mentre dormi.
approvals:
mode: smart
cron_mode: denyRiduci l'ambiente in cui l'agent può operare. terminal.backend: docker esegue i comandi all'interno di un container che rimuove tutte le Linux capabilities tranne un elenco limitato, imposta no-new-privileges e limita il numero di processi. In questo modo il confine di sicurezza è il container, non il prompt. terminal.cwd fissa la directory di lavoro. HERMES_WRITE_SAFE_ROOT limita write_file e patch alle directory specificate; qualsiasi scrittura al di fuori di queste directory viene bloccata e non può essere autorizzata tramite un'approvazione.
export HERMES_WRITE_SAFE_ROOT=/home/you/projects:/home/you/.hermesHermes blocca già le scritture in ~/.ssh, ~/.aws, ~/.kube e /etc/sudoers, rifiuta la scrittura di file .env ovunque sul disco e rifiuta un elenco rigido di comandi distruttivi, indipendentemente dalle impostazioni delle approvazioni. Considera queste misure il livello minimo di protezione, non il tuo piano di sicurezza. Esegui l'agent come utente normale, mai come root. Lo stesso principio vale per qualsiasi coding agent lasciato in esecuzione senza supervisione; eseguire Claude Code in sicurezza su un VPS lo approfondisce.
Prepara quindi le procedure di revoca prima di averne bisogno. La rimozione del dispositivo nella console di amministrazione di Tailscale interrompe immediatamente l'accesso alla mesh. La modifica di HERMES_DASHBOARD_BASIC_AUTH_SECRET e il riavvio invalidano tutte le sessioni della dashboard su ogni dispositivo, perché quel valore firma il cookie di sessione. L'eliminazione della public key del telefono da ~/.ssh/authorized_keys interrompe l'accesso SSH. hermes pairing revoke telegram <user-id> rimuove un account di messaggistica. Se il dispositivo conteneva dati o credenziali in grado di leggere le chiavi del provider, revocale con hermes auth logout <provider> e generane di nuove nel sistema del provider.
Verifica il risultato invece di darlo per scontato. Questi comandi devono essere eseguiti sul tuo server; l'output dipende dalla configurazione:
tailscale status
hermes pairing list
hermes logs gateway -n 100
hermes status --deepI log si trovano in ~/.hermes/logs/. Consultali dopo un incidente e leggili periodicamente anche quando non si è verificato alcun incidente.
FAQ
Esiste un'app mobile ufficiale di Hermes per iOS o Android?
No. Il repository di Hermes distribuisce un'interfaccia a riga di comando, una dashboard web e un client desktop Electron per macOS, Windows e Linux. Non esiste una build ufficiale per iOS o Android. Da un telefono si usa la dashboard web in un browser, un client SSH o una piattaforma di messaggistica connessa tramite hermes gateway. Esistono anche client mobili di terze parti. Sono codice non ufficiale che conserva le credenziali del tuo agent, quindi leggi il codice sorgente prima di installarne uno.
Perché la dashboard di Hermes esegue il logout sul telefono?
I token di accesso hanno un TTL di 15 minuti e il contratto API attuale non prevede un refresh token. Quando il token scade, la pagina riceve un 401 e passa a /login. La sospensione del browser su un telefono rende il problema evidente, perché bastano venti minuti in un'altra app per raggiungere la scadenza. Imposta HERMES_DASHBOARD_BASIC_AUTH_SECRET su un valore casuale stabile, in modo che la chiave di firma della sessione resti invariata tra i riavvii. Questo elimina la seconda causa del logout.
Posso pubblicare la dashboard di Hermes su Internet in sicurezza?
Solo con un'autenticazione che hai verificato personalmente. Il controllo di autenticazione viene attivato in base all'indirizzo di bind. Di conseguenza, una dashboard associata a 127.0.0.1 e pubblicata tramite un reverse proxy non richiede un login agli utenti su Internet. Esegui curl -s https://your-host/api/status | jq '.auth_required' e leggi l'output. Usa OAuth o OIDC invece di nome utente e password, perché la documentazione del progetto indica che il provider basato su password è destinato alle reti fidate e alle VPN. Una mesh privata evita del tutto il problema ed è quindi l'impostazione predefinita migliore.
Mi serve un account Tailscale o posso self-hostare il control plane?
Puoi self-hostarlo. Headscale è un'implementazione open del server di coordinamento Tailscale e i client ufficiali Tailscale vi si connettono con tailscale up --login-server https://headscale.example.com. In questo modo gestisci direttamente l'elenco dei dispositivi autorizzati ad accedere alla mesh. Il costo è che devi eseguire e sottoporre a backup quel server. Quando il server è inattivo, non puoi registrare nuovi dispositivi né autenticare nuovamente quelli esistenti.
Come ricevo una notifica sul telefono quando l'agent termina un job?
Usa il messaging gateway. La dashboard e SSH non possono riattivare un telefono, perché sul dispositivo non esiste un'app Hermes in grado di ricevere notifiche push. Connetti l'agent a Telegram, Signal, Discord o un'altra piattaforma supportata tramite hermes gateway setup, quindi lascia che sia l'app della piattaforma a recapitare la notifica. Un cron job può anche inviare un singolo messaggio con hermes send -t telegram -s "Job done" -f /path/to/report.txt, senza chiamare il modello.