Hermes peut désormais utiliser votre gestionnaire de mots de passe : connexions, cartes et 2FA sans jamais confier le mot de passe


Vous demandez à Hermes de se connecter à votre tableau de bord d’administration pour changer une valeur de configuration. Il y navigue sans problème, puis s’arrête net devant le formulaire de connexion. Non pas parce qu’il ne sait pas cliquer — mais parce que le mot de passe, vous seul le connaissez. Vous le collez donc dans le chat et, à partir de cet instant, le texte en clair vit dans l’historique de la session, dans les journaux et dans la prochaine vague de contexte envoyée au modèle. Vous avez échangé un clic contre la remise de votre mot de passe à toute la chaîne de traitement.

Le coffre d’identifiants (credential vault) fraîchement fusionné vise exactement ce problème. L’agent se rend lui-même sur la page de connexion, saisit l’identifiant de son côté, et Hermes injecte le mot de passe côté serveur. Ce que le modèle reçoit en retour tient en une ligne : {filled_fields: 1, origin: "https://github.com"}. Le mot de passe n’entre jamais dans la conversation, les journaux, la base de sessions ni la ligne de commande d’un quelconque processus.

Comment les rôles se répartissent

Deux couches : une réserve qui contient les identifiants, et des outils de navigateur qui les posent sur la page. L’agent ne reçoit jamais qu’un handle — une poignée, c’est-à-dire un identifiant opaque — accompagné de métadonnées visibles (libellé, identifiant, origine). Le secret réel est résolu au moment du remplissage par le backend, puis écrit directement dans la page.

Outil Ce qu’il fait
browser_vault_list Liste les identifiants remplissables — libellés, identifiants, origines. Jamais les mots de passe.
browser_vault_save_login Enregistre un nouvel identifiant depuis la page où se trouve l’agent
browser_vault_fill Injecte un identifiant dans la page courante, après vérification de l’origine
browser_vault_enter_code Gère l’étape du code à usage unique
browser_vault_unlock Déverrouille un gestionnaire externe (1Password / Bitwarden)

Les entrées vivent chiffrées sous ~/.hermes/vault/ (une clé Fernet plus le fichier du coffre, tous deux en 0600) et sont cloisonnées par profil — la même idée d’isolation que derrière la navigation avec un vrai profil.

La première fois : il vous demande directement sur la page de connexion

Le plus agréable, c’est l’absence totale de configuration. Pas besoin d’apprendre hermes vault add ni de chercher un interrupteur à activer. Dites « connecte-toi à GitHub » : lorsque l’agent atteint une page de connexion sans rien d’enregistré pour ce site, il vous sollicite là où vous êtes.

  • CLI / TUI — un panneau en deux étapes sur la même fenêtre modale que celle de sudo : l’e-mail ou le nom d’utilisateur est affiché, puis le mot de passe se saisit en masqué.
  • Application de bureau — une carte « Enregistrer votre identifiant github.com ? » avec des champs libellés Email ou nom d’utilisateur et Mot de passe, plus deux boutons : Ne pas enregistrer / Enregistrer et se connecter.

Si vous acceptez, Hermes le chiffre, le lie à l’origine de la page et le remplit aussitôt. Si vous refusez, l’outil renvoie save_declined et l’agent cesse de demander pour ce tour. Dans les deux cas, le mot de passe ne transite jamais par le chat : il a été saisi dans une invite masquée, pas dans un message.

Un détail de conception qui mérite d’être signalé : ces outils sont embarqués avec le jeu d’outils navigateur, et non placés derrière un contrôle du type « le coffre contient des entrées ». Or un coffre vide est précisément le moment où l’enregistrement d’un identifiant devient nécessaire ; une version antérieure cachait la fonctionnalité derrière ce contrôle, d’où le fait que personne ne l’ait trouvée.

2FA : trois cas, trois comportements

Le mot de passe n’est pas la dernière étape. L’agent se heurtait ici à un mur : le classificateur de connexion ignore délibérément les champs de code à usage unique (un mot de passe ne doit jamais atterrir dans une case OTP), et aucun outil ne gérait la seconde étape — la seule option restante était de demander dans le chat.

Désormais, cela se répartit en trois cas :

Ce que le site demande Ce que fait Hermes
Un code, et l’identifiant enregistré porte une clé d’authentification (coffre local, ou une entrée 1Password / Bitwarden avec une graine TOTP) Génère le code courant et le saisit. Personne n’est sollicité.
Un code envoyé par téléphone / e-mail / application, sans clé enregistrée Une petite invite apparaît dans votre interface (« Code de vérification pour github.com »), vous le saisissez, Hermes l’entre. Le code n’entre pas non plus dans la conversation.
Une passkey, une clé matérielle ou une validation à taper dans une application Rien à saisir. L’agent vous indique de terminer l’opération sur votre appareil et attend que la page avance.

Une clé d’authentification, c’est la « clé de configuration » — ou le lien otpauth:// — qu’un site affiche quand vous activez la 2FA. Ajoutez-la dans Paramètres → Mots de passe et identifiants → Ajouter (champ facultatif), ou via l’assistant hermes vault add ; les entrées qui en portent une reçoivent un badge 2FA auto.

La saisie du code est elle aussi volontairement prudente : les chiffres ne sont tapés un par champ que lorsque le widget est sans ambiguïté — exactement autant de contrôles que le code compte de chiffres, tous en maxlength=1, dans le même formulaire et adjacents. Sinon, le code entier est saisi d’un coup, pour qu’une page comportant des champs « code » de promo, de code postal ou de parrainage ne reçoive jamais une pluie de chiffres.

Déjà sur 1Password ou Bitwarden ? Rien à activer

Si la CLI op ou bw est installée et connectée, Hermes la détecte automatiquement et ses identifiants de sites deviennent des handles remplissables au même titre que les vôtres en local. Les handles sont préfixés par backend — vault_… pour le local, op:…, bw:… pour les gestionnaires — de sorte que les outils n’ont besoin d’aucun changement de schéma pour router vers le bon.

La première fois qu’il a besoin de l’un de ces identifiants, il vous demande de déverrouiller le gestionnaire : invite masquée, une fois par session, expirant après 30 minutes d’inactivité. Le mot de passe principal part vers la CLI du gestionnaire par son propre canal non interactif (op signin sur stdin, bw unlock --passwordenv dans l’environnement du processus enfant). Hermes ne conserve en mémoire que le jeton de session — rien sur disque, rien dans les sauvegardes d’environnement — et ne voit jamais le mot de passe principal, le jeton, ni aucun identifiant.

Vous préférez ne pas utiliser du tout un gestionnaire détecté ? hermes vault sources --disable bitwarden, ou l’interrupteur dans les Paramètres.

Paiement et remplissage d’adresses : chaque carte exige votre accord

Les cartes et les adresses s’enregistrent de la même façon — une fois, liées au site de paiement, et remplies uniquement là. La différence tient à la confirmation : chaque remplissage de carte vous demande d’abord, via la même invite d’approbation que pour une commande dangereuse, et un refus n’écrit rien. Le remplissage d’adresse ne demande aucune confirmation.

L’autre frontière à retenir : les sessions headless ne peuvent pas remplir de carte. Les tâches cron, les webhooks et le serveur API n’ont personne pour cliquer sur confirmer, donc ces remplissages sont refusés. Une injection de prompt qui atteint une page de paiement peut demander — elle ne peut pas dépenser. C’est le même principe que les approbations sans surveillance : quand personne ne peut répondre, la valeur par défaut est non, pas oui.

Le gérer depuis la CLI

L’application de bureau gère tout dans Paramètres → Mots de passe et identifiants ; côté CLI, il y a quatre sous-commandes :

# Ajout interactif d'un identifiant, d'une carte ou d'une adresse. Le mot de passe
# passe par getpass — il n'est jamais accepté comme argument de ligne de commande.
hermes vault add
hermes vault add --kind payment     # carte de paiement
hermes vault add --kind address     # adresse de livraison / facturation

# Métadonnées uniquement : handle, source, kind, label, identifier, origin
hermes vault list

# Suppression par handle
hermes vault rm vault_3f9c1a

# Quels gestionnaires de mots de passe ont été détectés ; désactiver ou réactiver
hermes vault sources
hermes vault sources --disable onepassword
hermes vault sources --enable onepassword

Les libellés, les origines de site et les identifiants de connexion sont des métadonnées visibles — l’agent peut les lire et saisir lui-même l’identifiant. Les mots de passe et les données de carte, non.

Une précision, car les noms se recoupent : ce coffre n’est pas le SecretSource externe de la v0.19. SecretSource lit les clés API destinées à Hermes dans Bitwarden Secrets Manager ou 1Password pour les placer dans des variables d’environnement, configurées sous secrets. Le coffre d’identifiants stocke les identifiants de sites web, les cartes et les adresses, configurés sous vault. Des noms proches, des rôles sans rapport.

Sessions headless (cron, webhooks, serveur API)

Personne ne peut y répondre à une invite, et les modes d’échec se distinguent nettement :

  • Les identifiants enregistrés localement continuent de fonctionner — aucune invite nécessaire.
  • Un gestionnaire de mots de passe verrouillé renvoie unavailable_in_this_session.
  • Aucun identifiant enregistré pour le site renvoie prompt_unavailable.

Pour rendre 1Password utilisable sans surveillance, fournissez-lui un jeton de compte de service — définissez-le dans OP_SERVICE_ACCOUNT_TOKEN et l’invite de mot de passe principal disparaît :

vault:
  onepassword:
    enabled: true                      # false opts OUT of a detected manager
    account: ""                        # `op --account` shorthand; empty = default
    service_account_token_env: OP_SERVICE_ACCOUNT_TOKEN
  bitwarden:
    enabled: true
    binary_path: ""                    # absolute path to bw; empty = PATH

Ce que cela garantit — et ce que cela ne garantit pas

« Le modèle ne voit jamais le mot de passe » se laisse facilement surinterpréter, il vaut donc la peine d’être précis.

Ce que ça fait : garder le mot de passe hors du contexte du modèle à travers Hermes — ni dans les résultats d’outils, ni dans les journaux, ni dans la base de sessions, ni dans les arguments d’un processus. Les remplissages passent par la socket CDP directe de la session de navigateur supervisée, et l’origine est revérifiée dans la page juste avant l’écriture : elle doit correspondre exactement à l’origine enregistrée, sinon le remplissage est refusé.

Ce que ça ne fait pas : vous protéger de la page elle-même. Une fois le mot de passe saisi dans un site, ce site — et tout script qu’il exécute — le possède, exactement comme quand vous le tapez vous-même. Sur un backend de navigateur cloud, le navigateur du fournisseur voit la page comme n’importe quelle autre. La liaison à l’origine protège contre un remplissage sur le mauvais site, pas contre un bon site compromis.

Le coffre lui-même repose sur du chiffrement local, un mécanisme distinct du chiffrement opt-in via le trousseau de l’OS : il utilise une clé Fernet et des fichiers en 0600, et ne touche pas au trousseau système.

Statut de publication : uniquement sur main, pour l’instant

À l’heure où nous écrivons, la fonctionnalité n’a atteint aucune version étiquetée. La dernière version, v0.21.1 (tag v2026.9.7, publiée le 7 septembre), ne contient ni agent/vault_backends/, ni tools/browser_vault_tool.py, ni hermes_cli/vault.py — tout cela a atterri sur main le 10 septembre.

Donc :

  • hermes update vers la v0.21.1 ne vous l’apportera pas. Attendez qu’une prochaine version étiquetée l’embarque.
  • Pour l’utiliser dès aujourd’hui, il faut suivre main (la voie d’installation par git) et accepter que main bouge tous les jours.

Dans un cas comme dans l’autre, le premier test après votre prochaine mise à jour tient en une ligne : demandez à l’agent de se connecter à un site, et regardez s’il s’arrête sur la page de connexion et vous demande — pour la première fois — si vous voulez enregistrer cet identifiant.