Votre gateway partagé ne devrait pas servir tous les profils : multiplex_profile_allowlist dans Hermes


Vous faites tourner un gateway Discord sur un serveur partagé, et la machine a cinq profils Hermes installés : un default polyvalent, un profil restreint pour les enfants, deux profils développeur. Démarrez le gateway et il lance d’un coup les adapters et les cron jobs de tous les profils. Pire : un message censé être routé vers le profil restreint arrive alors que ce profil est indisponible — et le gateway l’exécute tranquillement sous default à la place. Pour un profil restreint, ce n’est pas une dégradation élégante : c’est franchir la frontière des capacités. La PR #83400, fusionnée le 11 août 2026, comble exactement cette lacune : gateway.multiplex_profile_allowlist vous permet de déclarer quels profils votre gateway partagé sert, et le routage qui manque l’ensemble servi fails closed désormais — le message est rejeté, jamais silencieusement rétrogradé.

Une clé de config pour définir l’ensemble servi

Ajoutez l’allowlist à config.yaml :

gateway:
  multiplex_profiles: true
  multiplex_profile_allowlist:
    - worker
    - guest

Avec ces quatre lignes, ce gateway ne démarre et ne sert que default, worker et guest — aucun autre profil installé sur la machine n’est démarré ni exposé via ce gateway.

La sémantique exacte de l’allowlist

Les règles (documentation officielle multi-profile-gateways.md) méritent d’être passées en revue une par une, car tous les cas limites sont gérés :

  • default est toujours servi — inutile de le lister ;
  • Non défini = comportement historique : servir tous les profils nommés valides de la machine ;
  • Liste vide [] = ne servir que default ;
  • Les noms sont normalisés et dédupliqués ; les entrées invalides ou les profils non installés sont ignorés avec un avertissement ; une valeur malformée qui n’est pas une liste retombe sans risque sur default uniquement, pas sur un crash ;
  • L’ensemble servi contrôle aussi les préfixes API et webhook /p/<profile>/, le statut runtime, l’éligibilité profile_routes, et quels profils le planificateur cron intégré fait tourner ;
  • Un profil nommé hors de l’allowlist n’est pas démarré par ce gateway — mais il peut toujours faire tourner son propre gateway autonome. « Non servi par le gateway partagé » ne veut pas dire « inutilisable ».

Fail closed : rejeter, ne pas rétrograder silencieusement

C’est la partie du changement qui compte pour la sécurité. Avant, le risque était le suivant : profile_routes routait explicitement un canal vers un profil restreint, mais si ce profil était indisponible (non installé, cassé, hors de l’ensemble servi), le trafic retombait silencieusement sur default. La règle est désormais inversée :

  • Une route explicite correspond mais son profil cible est non installé ou hors de l’allowlist → le gateway rejette le message et journalise la route et le profil cible — il ne l’exécute jamais sous default ;
  • Le trafic qui ne correspond à aucune route conserve le comportement historique (il va vers default) ;
  • profile_routes ne s’applique que lorsque multiplex_profiles: true.

Scénario réel : un profil restreint sur un gateway partagé

Le cas d’usage classique, c’est un bot familial partagé : un bot Discord où les canaux habituels tournent sur default et le canal des enfants sur un profil restreint. On le met en place en deux couches :

  1. Couche gateway : multiplex_profile_allowlist ne liste que default + kids-safe, et profile_routes envoie le canal des enfants vers kids-safe ;
  2. Couche profil : le durcissement vit dans le config.yaml propre au profil restreint — n’activer que l’ensemble d’outils dont il a besoin, ne pas hériter des identifiants de default, etc. Les profils sont des foyers de configuration isolés, donc cette isolation se fait de toute façon à cette couche.

Une limite à énoncer clairement : la documentation officielle nous rappelle que le routage de profils plus une allowlist ne constituent pas un sandbox de sécurité complet. Quand vous avez besoin d’une frontière dure au niveau du système d’exploitation (disons, du code qui doit s’exécuter dans un environnement isolé), utilisez des processus séparés ou l’isolation par conteneurs — n’attendez pas du routage au niveau config qu’il serve de filet de sécurité.

À retenir

multiplex_profile_allowlist est un petit changement qui résout une vraie douleur des gateways partagés : vous avez des profils installés pour différents usages, mais le gateway servait autrefois tout le monde sans distinction — et se dégradait silencieusement quand une route manquait sa cible. Désormais, vous pouvez déclarer exactement qui ce gateway sert, et transformer cette dégradation en rejet. Pour le concept complet de multi-instance de profils, voir notre guide multi-profils ; le routage de profils dans une configuration Feishu est couvert dans cet article ; les surfaces de commandes vivent dans les pages de référence hermes-gateway et hermes-profile.