Accéder à votre agent Hermes depuis un téléphone
Accédez à l’interface web Hermes depuis votre téléphone avec Tailscale, un endpoint HTTPS public ou SSH, puis révoquez l’accès si le téléphone est perdu.
Les trois façons d’accéder à votre agent Hermes depuis votre téléphone
Pour accéder à votre agent Hermes depuis votre téléphone, vous utilisez son tableau de bord web. Le vrai choix concerne donc ce qui se trouve devant ce tableau de bord. La première option est un réseau mesh privé. Le tableau de bord écoute uniquement sur une adresse Tailscale et aucun port n’est exposé sur Internet. La deuxième option est un endpoint public derrière un reverse proxy avec TLS (transport layer security) et une authentification. Cette authentification est alors la seule protection d’un terminal donnant accès à votre serveur. La troisième option est SSH (secure shell) depuis une application de terminal. Cette solution demande le moins de configuration et accorde le plus de privilèges.
Ce guide prend le relais de l’exécution d’un agent Hermes sur votre propre VPS. L’agent est installé, il répond sur la ligne de commande et vous voulez maintenant l’avoir avec vous.
Les commandes ci-dessous correspondent au tag v2026.8.3, publié le 3 août 2026 et identifié comme v0.20.0 dans les release notes. Hermes publie fréquemment de nouvelles versions. Épinglez donc la machine sur un tag au lieu de suivre main. L’installateur accepte un commit :
curl -fsSL https://hermes-agent.nousresearch.com/install.sh | bash -s -- --commit 3c27eb6234bf
hermes versionhermes version affiche ce qui est réellement installé. Comparez-le avec le tag avant de faire confiance à un flag présenté sur cette page.
Ce que le dépôt fournit et ce qu’il ne fournit pas
Le dépôt Hermes ne contient aucune application iOS ou Android. Le client natif est hermes desktop (alias hermes gui), une application Electron pour macOS, Windows et Linux. Il peut se connecter à un agent distant au lieu d’utiliser un agent local : définissez l’URL distante sur http://<server-address>:9119 dans Settings, sous Gateway, ou exportez HERMES_DESKTOP_REMOTE_URL=http://<server-address>:9119 avant de le lancer. Cela permet d’utiliser un second ordinateur portable. Cette solution ne fonctionne pas sur un téléphone.
Depuis un téléphone, vous utilisez hermes dashboard, l’interface du navigateur. Elle gère la configuration, les sessions, les tâches cron, les skills, les journaux et les plateformes de messagerie. Elle intègre aussi un terminal : le serveur lance hermes --tui derrière un PTY (pseudo-terminal), puis diffuse la sortie dans la page. Sur un écran étroit, le sélecteur de session se replie dans un panneau coulissant. La mise en page reste donc utilisable sur un téléphone.
Par défaut, le dashboard écoute sur 127.0.0.1:9119 et ouvre un onglet du navigateur sur le serveur lui-même. Cela ne sert à rien sur un VPS (virtual private server) headless. Lancez-le sans ouvrir le navigateur et examinez le socket :
hermes dashboard --no-open
ss -lntp | grep 9119Un listener sur 127.0.0.1:9119 est accessible uniquement depuis le serveur. Un listener sur 0.0.0.0:9119 est accessible depuis tous les réseaux auxquels la machine est connectée, y compris le réseau public. Cette seule ligne détermine votre niveau d’exposition. Lisez-la au lieu de le supposer.
Option 1 : un réseau privé avec Tailscale
Choisissez cette option sauf si vous avez une raison de ne pas le faire. Tailscale est un VPN mesh (réseau privé virtuel) basé sur WireGuard. Chaque appareil que vous inscrivez reçoit une adresse stable et communique directement avec les autres. Votre téléphone rejoint le même mesh. Le dashboard n’a donc jamais besoin d’un port public.
Sur le serveur :
curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up
tailscale ip -4Installez l’application Tailscale sur le téléphone et connectez-vous avec le même compte. tailscale status sur le serveur affiche ensuite le téléphone avec son nom. Liez maintenant le dashboard à l’adresse affichée par tailscale ip -4 :
hermes dashboard --host 100.101.102.103 --port 9119 --no-openLe fait de lier le service à l’adresse du mesh plutôt qu’à 0.0.0.0 signifie que le socket en écoute existe uniquement sur l’interface Tailscale. Un scan des ports de votre adresse IP publique ne trouve rien sur 9119, car aucun service n’y est en écoute. Votre pare-feu n’est donc plus votre seule protection. Vérifiez-le de nouveau avec ss -lntp | grep 9119.
L’adresse d’écoute détermine également l’authentification. C’est le point souvent oublié. Sur 127.0.0.1, le dashboard n’a pas de connexion utilisateur. Sur toute autre adresse, la passerelle d’authentification est obligatoire. Si aucun provider n’est configuré, le serveur refuse de démarrer. Le projet appelle cela un échec en mode sécurisé. Lancez-le en mode interactif la première fois. Il propose alors de définir immédiatement un nom d’utilisateur et un mot de passe. Le résultat est écrit dans ~/.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-stringGénérez ce secret avec openssl rand -hex 32, puis ne le modifiez plus. Il signe le cookie de session. Si vous le changez, tous les appareils sont déconnectés. Le même fichier contient vos clés d’API de modèle. Protégez-le donc avec chmod 600 ~/.hermes/.env.
Vérifiez la passerelle depuis une autre machine du mesh avant de lui faire confiance :
curl -s http://100.101.102.103:9119/api/status | jq '.auth_required, .auth_providers'true suivi de ["basic"] signifie que la passerelle est active et que le password provider répond correctement. La documentation du projet est claire à propos de ce provider : il est prévu pour un réseau de confiance ou un VPN. Il ne convient pas à un dashboard exposé sur Internet. Dans un mesh, c’est précisément votre situation.
Pour utiliser HTTPS à l’intérieur du tailnet, confiez le port à Tailscale :
sudo tailscale serve --bg localhost:9119
sudo tailscale serve statusTailscale termine TLS avec un certificat émis pour le nom MagicDNS de la machine. Le navigateur n’affiche alors plus d’avertissement et le cookie de session reçoit son indicateur Secure. Activez d’abord MagicDNS et HTTPS Certificates dans la page DNS de la console d’administration Tailscale. Lisez également l’avertissement affiché à cet endroit : les noms de vos machines et le nom DNS de votre tailnet sont publiés dans le registre public de transparence des certificats, que tout le monde peut consulter.
Le coût réel concerne le coordination server. Le trafic entre votre téléphone et votre VPS est chiffré de bout en bout et ne passe pas par Tailscale. En revanche, le compte qui détermine quels appareils appartiennent au mesh n’est pas hébergé sur votre matériel. Si cela vous pose problème, exécutez vous-même le control plane avec Headscale, le control server Tailscale auto-hébergé, puis indiquez-le aux clients avec tailscale up --login-server https://headscale.example.com. Si vous préférez abandonner le mesh et configurer manuellement les pairs, la comparaison entre WireGuard classique et Tailscale explique ce que vous perdez.
Option 2 : un endpoint HTTPS public et le piège qu’il contient
Un mesh n’est pas toujours disponible. Un téléphone professionnel peut empêcher l’installation d’un client VPN. Le dashboard passe alors derrière un reverse proxy. Laissez le dashboard lié à loopback et laissez Caddy gérer le certificat :
hermes.example.com {
reverse_proxy 127.0.0.1:9119
}Caddy récupère et renouvelle le certificat automatiquement. Son reverse_proxy transmet les upgrades WebSocket sans directive supplémentaire, ce dont le terminal intégré du dashboard a besoin. Avec nginx, vous devez ajouter vous-même les en-têtes Upgrade et Connection. La page émettre un certificat Let’s Encrypt avec Certbot sur nginx couvre la partie TLS de cette configuration. Indiquez à Hermes son nom public afin que les callbacks de connexion pointent vers le bon hôte :
dashboard:
public_url: "https://hermes.example.com"Voici le piège. Le contrôle d’authentification dépend de l’adresse d’écoute, et non de l’adresse depuis laquelle la requête a été envoyée. Un dashboard lié à 127.0.0.1 derrière un proxy voit loopback, considère qu’aucune connexion n’est nécessaire et sert le contenu à toute personne que le proxy laisse passer. Vérifiez ce que vous avez réellement publié :
curl -s https://hermes.example.com/api/status | jq '.auth_required'Si cette commande affiche false, Internet est à une URL d’un terminal sur votre serveur. Aucun exploit n’est nécessaire et rien ne sera signalé dans les journaux. Il existe 2 correctifs et vous devez en appliquer au moins un. Vous pouvez soit placer l’authentification dans le proxy, avec Authentik comme fournisseur single sign-on auto-hébergé devant celui-ci via forward auth, soit configurer le fournisseur OIDC (OpenID Connect) intégré au 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"Même correctement configurée, cette option impose une limite que vous ne pouvez pas réduire. Une page de connexion publique est accessible et attaquable par n’importe qui. Elle protège un shell sur votre VPS. Un nom d’utilisateur et un mot de passe offrent une protection faible dans ce contexte. C’est pourquoi la documentation recommande OAuth ou OIDC pour les binds publics. Limitez le débit des connexions, gardez ufw fermé à tout sauf aux ports du proxy et à SSH et consultez régulièrement le access log.
Option 3 : SSH et mosh depuis un terminal mobile
La solution qui demande le moins d’efforts consiste à installer une application de terminal sur le téléphone, à y charger une clé SSH et à utiliser l’interface texte de l’agent.
ssh you@vps.example.com
tmux new -A -s phone
hermes --tuitmux new -A -s phone s’attache à une session appelée phone, ou la crée si elle n’existe pas. L’agent continue ainsi de fonctionner lorsque la connexion est interrompue, et vous retrouvez le même environnement la fois suivante. Le principe est le même que pour piloter Claude Code depuis un téléphone.
SSH seul sur un réseau mobile est peu pratique, car la connexion est interrompue dès que le téléphone change d’adresse ou passe en veille. Mosh résout ce problème. Il utilise UDP (user datagram protocol) et synchronise l’état du terminal plutôt qu’un flux d’octets. La session survit ainsi au passage du wifi au réseau cellulaire :
sudo apt install -y mosh
sudo ufw allow 60000:61000/udpDepuis le téléphone, exécutez mosh you@vps.example.com. Mosh démarre mosh-server via votre session SSH existante, puis transfère la session vers UDP dans la plage 60000 à 61000. Cette plage doit donc être ouverte.
Le risque de sécurité est direct. Une session SSH fournit un shell, et un shell permet tout ce que ce compte est autorisé à faire. Les demandes d’approbation de l’agent deviennent alors le dernier obstacle entre un téléphone déverrouillé volé et vos fichiers. Utilisez un compte non-root dédié à cette tâche, uniquement avec une clé, et appliquez le durcissement de SSH sur un VPS avant d’installer une clé sur un appareil que vous transportez avec vous.
Ce qui ne fonctionne pas sur un réseau mobile
Quatre éléments posent problème. Aucun ne peut être corrigé par la configuration.
Le dashboard vous déconnecte pendant que vous ne le consultez pas. Les access tokens ont une durée de vie de 15 minutes (TTL, time to live) et le contrat API actuel ne prévoit aucun refresh token. Lorsque le token expire, la page reçoit une réponse 401 et revient à /login. Ouvrez le dashboard, mettez le téléphone dans votre poche pendant vingt minutes, puis vous revenez à l’écran de connexion et le texte saisi a disparu. Rien n’est cassé. Reconnectez-vous.
Le terminal intégré ne résiste pas à la mise en arrière-plan de l’onglet. Le serveur lance la TUI (text user interface) derrière un PTY et la termine proprement lorsque l’onglet est fermé. Sa réouverture en lance une nouvelle. Les navigateurs mobiles suppriment les onglets en arrière-plan pour récupérer de la mémoire. Si vous passez assez longtemps à une autre application, le terminal est donc terminé. L’historique de vos conversations est conservé, car les sessions sont stockées sur le serveur et hermes sessions list les affiche toujours. En revanche, vous ne pouvez pas vous rattacher au terminal lui-même. Si vous avez besoin d’une session persistante, utilisez tmux via SSH.
Les connexions inactives meurent en silence. Les opérateurs mobiles suppriment les connexions TCP inactives pour récupérer des entrées dans la table NAT (network address translation), et le téléphone cesse presque complètement de gérer le réseau lorsque l’écran est éteint. Un WebSocket resté silencieux pendant un certain temps est généralement déjà mort lorsque vous déverrouillez le téléphone. La page ne se reconnecte qu’après une interaction. C’est pourquoi mosh est plus fiable que SSH sur un téléphone : il n’avait jamais de connexion à perdre.
Aucune notification n’est envoyée. Ni le dashboard ni une session SSH ne peuvent sortir votre téléphone de veille. L’app Hermes n’est pas installée sur l’appareil. Aucun chemin ne permet donc d’accéder au service de notifications push de la plateforme. Une longue exécution d’agent se termine, et vous ne le découvrez que lorsque vous consultez à nouveau le téléphone.
Les notifications passent par la passerelle de messagerie
La solution à ce dernier problème consiste à utiliser la passerelle, qui fournit une autre méthode pour joindre l’agent. hermes gateway connecte l’agent à des plateformes de messagerie comme Telegram, Discord, Slack, WhatsApp, Signal et la messagerie électronique. Vous échangez ensuite avec votre agent dans une application qui dispose déjà d’un canal push sur votre téléphone, gère déjà la livraison en arrière-plan et supporte déjà les interruptions réseau.
hermes gateway setup
hermes gateway install
hermes gateway statushermes gateway install enregistre la passerelle comme service systemd afin qu’elle redémarre après un reboot. L’installateur Hermes ne crée aucune unité de service pour vous. hermes dashboard ne redémarrera donc pas automatiquement après un redémarrage. Créez une unité pour chaque composant dont vous dépendez. La section écrire des services et des timers systemd sur un VPS décrit le fichier à créer.
Une tâche planifiée peut envoyer un résultat de la même manière, sans conversation :
hermes send -t telegram -s "Backup report" -f /home/you/report.txtL’autorisation est ici refusée par défaut. Si aucune allowlist n’est définie et que GATEWAY_ALLOW_ALL_USERS n’est pas défini, tous les utilisateurs sont refusés. C’est le comportement initial recommandé. Indiquez dans ~/.hermes/.env les comptes à autoriser :
TELEGRAM_ALLOWED_USERS=123456789
GATEWAY_ALLOWED_USERS=123456789Vous pouvez aussi activer l’association par code au lieu de coller des identifiants numériques, en définissant unauthorized_dm_behavior: pair dans ~/.hermes/config.yaml. Lorsqu’un compte inconnu envoie un message à l’agent, il reçoit un code de huit caractères. Rien d’autre ne se produit tant que vous ne l’avez pas approuvé :
hermes pairing list
hermes pairing approve telegram ABC12DEF
hermes pairing revoke telegram 123456789Les codes expirent au bout d’une heure. Un utilisateur peut en demander un toutes les dix minutes. Cinq tentatives échouées verrouillent ce compte.
Limiter l’impact d’un téléphone volé
Un téléphone qui peut joindre votre agent peut exécuter des commandes sur votre serveur, et les téléphones se perdent. Décidez dès maintenant de ce que la personne qui le détient pourra faire.
Laissez les approbations activées. approvals.mode vaut smart par défaut, ce qui demande à un modèle auxiliaire d’évaluer le risque et n’approuve automatiquement que les commandes à faible risque. Le définir sur off revient à tout exécuter avec --yolo, et HERMES_YOLO_MODE=1 permet de le faire via l’environnement. Ne transportez pas un téléphone qui communique avec un agent dans cet état. Définissez approvals.cron_mode: deny afin que les tâches planifiées ne puissent pas s’approuver elles-mêmes pendant votre sommeil.
approvals:
mode: smart
cron_mode: denyDonnez à l’agent un périmètre de destruction plus réduit. terminal.backend: docker exécute les commandes dans un conteneur qui supprime toutes les Linux capabilities sauf une courte liste, définit no-new-privileges et limite le nombre de processus. Le conteneur devient ainsi la boundary, plutôt qu’une simple invite. terminal.cwd fixe le répertoire de travail. HERMES_WRITE_SAFE_ROOT restreint write_file et patch aux répertoires que vous indiquez, et toute écriture en dehors de ces répertoires est bloquée sans possibilité de la passer outre par une approbation.
export HERMES_WRITE_SAFE_ROOT=/home/you/projects:/home/you/.hermesHermes bloque déjà les écritures vers ~/.ssh, ~/.aws, ~/.kube et /etc/sudoers, refuse d’écrire des fichiers .env où que ce soit sur le disque et rejette une liste stricte de commandes destructrices, quels que soient vos paramètres d’approbation. Considérez cela comme un socle, pas comme votre plan de sécurité. Exécutez l’agent avec un utilisateur ordinaire, jamais avec root. Le même raisonnement s’applique à tout coding agent laissé sans surveillance, et exécuter Claude Code en toute sécurité sur un VPS l’explique plus en détail.
Notez ensuite les étapes de révocation avant d’en avoir besoin. La suppression de l’appareil dans la console d’administration Tailscale coupe immédiatement l’accès au mesh. Modifier HERMES_DASHBOARD_BASIC_AUTH_SECRET et redémarrer invalide toutes les sessions du dashboard sur tous les appareils, car cette valeur signe le cookie de session. Supprimer la clé publique du téléphone dans ~/.ssh/authorized_keys met fin à l’accès SSH. hermes pairing revoke telegram <user-id> supprime un compte de messagerie. Si l’appareil contenait quoi que ce soit permettant de lire les clés de votre provider, révoquez-les avec hermes auth logout <provider> et émettez-en de nouvelles auprès du provider.
Vérifiez le résultat au lieu de le supposer. Exécutez ces commandes sur votre propre machine ; leur sortie dépend de votre configuration :
tailscale status
hermes pairing list
hermes logs gateway -n 100
hermes status --deepLes logs se trouvent sous ~/.hermes/logs/. Consultez-les après un incident, et consultez-les aussi régulièrement lorsqu’il ne s’en est pas produit.
FAQ
Existe-t-il une application mobile Hermes officielle pour iOS ou Android ?
Non. Le dépôt Hermes fournit une interface en ligne de commande, un tableau de bord web et un client de bureau Electron pour macOS, Windows et Linux. Il n’existe pas de version iOS ou Android officielle. Depuis un téléphone, utilisez le tableau de bord web dans un navigateur, un client SSH ou une plateforme de messagerie connectée via hermes gateway. Des clients mobiles tiers existent. Ils contiennent du code tiers qui détient les identifiants de votre agent. Lisez donc le code source avant d’en installer un.
Pourquoi le tableau de bord Hermes me déconnecte-t-il sur mon téléphone ?
Les jetons d’accès ont une durée de vie de 15 minutes et le contrat d’API actuel ne prévoit pas de refresh token. Lorsque le jeton expire, la page reçoit une réponse 401 et navigue vers /login. La mise en arrière-plan d’un navigateur sur un téléphone rend ce comportement évident : vingt minutes dans une autre application suffisent pour atteindre cette limite. Définissez HERMES_DASHBOARD_BASIC_AUTH_SECRET avec une valeur aléatoire stable afin que la clé de signature de session reste identique après les redémarrages. Cela supprime la seconde cause de déconnexion.
Puis-je exposer le tableau de bord Hermes sur Internet en toute sécurité ?
Uniquement avec une authentification que vous avez vous-même vérifiée. Le mécanisme d’authentification est activé selon l’adresse d’écoute. Ainsi, un tableau de bord lié à 127.0.0.1 derrière un reverse proxy ne demande jamais d’identifiant aux utilisateurs venant d’Internet. Exécutez curl -s https://your-host/api/status | jq '.auth_required' et examinez le résultat. Utilisez OAuth ou OIDC plutôt qu’un nom d’utilisateur et un mot de passe, car la documentation du projet indique que le fournisseur par mot de passe est destiné aux réseaux de confiance et aux VPN. Un mesh privé évite entièrement cette question. C’est donc le meilleur choix par défaut.
Ai-je besoin d’un compte Tailscale ou puis-je auto-héberger le control plane ?
Vous pouvez l’auto-héberger. Headscale est une implémentation libre du serveur de coordination Tailscale, et les clients Tailscale officiels s’y connectent avec tailscale up --login-server https://headscale.example.com. Vous contrôlez alors la liste des appareils autorisés à rejoindre le mesh. En contrepartie, vous devez exploiter et sauvegarder ce serveur. Tant qu’il est indisponible, vous ne pouvez pas inscrire un appareil ni réauthentifier un appareil existant.
Comment recevoir une notification sur mon téléphone lorsque l’agent termine une tâche ?
Utilisez la messaging gateway. Le tableau de bord et SSH ne peuvent pas réveiller un téléphone, car aucun agent Hermes n’est installé sur l’appareil pour recevoir une notification push. Connectez l’agent à Telegram, Signal, Discord ou une autre plateforme prise en charge avec hermes gateway setup, puis laissez l’application de cette plateforme distribuer la notification. Une tâche cron peut également envoyer un message unique avec hermes send -t telegram -s "Job done" -f /path/to/report.txt. Cette méthode envoie le message sans appeler le modèle.