# Blocs Match de la configuration SSH et approbation de l'agent

Une approbation SSH n'a de sens que si la connexion approuvée est celle que SSH va réellement établir. Cela paraît évident, jusqu'à ce qu'un agent lance `ssh prod`, qu'un alias choisisse un autre `HostName`, qu'un bloc `Match` modifie l'utilisateur distant et que `ProxyJump` fasse passer la session par un bastion qui n'était mentionné nulle part dans la demande.

La plupart des erreurs de configuration SSH restent gérables lorsqu'une personne surveille le terminal. Elle voit une invite de clé d'hôte inconnue, remarque `root@...` ou sait que `prod` désigne autre chose sur le réseau du bureau. Un agent autonome n'a pas cette méfiance. Il utilise l'alias qui lui a été fourni et suit exactement la configuration.

C'est pourquoi les blocs `Match` de la configuration SSH doivent faire l'objet d'un audit de sécurité avant qu'un agent obtienne un accès SSH. L'objectif n'est pas d'interdire les alias, les bastions ou la configuration conditionnelle. Il faut que l'action demandée, la configuration SSH effective et la connexion approuvée par une personne décrivent la même chose.

## Un alias d'hôte est une entrée, pas une identité

`ssh app-prod` ne vous indique ni où SSH va se connecter, ni quel compte il utilisera, ni quelle clé il proposera, ni si le trafic passera d'abord par une autre machine. Cette commande indique à OpenSSH quelle entrée de configuration utiliser en premier.

Cette différence est souvent masquée parce que les alias rendent le travail quotidien agréable. Un nom court comme `app-prod` est plus facile à saisir qu'un nom d'hôte complet avec un utilisateur précis et un port non standard. Il est aussi plus facile à transmettre à un agent. Mais l'alias n'est qu'une poignée. Son sens vient de tous les paramètres correspondants des fichiers de configuration lus par SSH.

OpenSSH lit d'abord les options de la ligne de commande, puis `~/.ssh/config`, puis la configuration du système. Pour la plupart des options à valeur unique, la première valeur obtenue est celle utilisée. Le manuel `ssh_config(5)` d'OpenSSH en tire une règle pratique : placez les déclarations précises en premier et les valeurs par défaut générales ensuite. Un bloc `Host *` général placé trop haut peut neutraliser discrètement une règle conditionnelle plus attentive.

Commencez par un inventaire qui décrit chaque alias utilisable par un agent avec des éléments vérifiables :

| Alias | Destination résolue | Utilisateur distant | Itinéraire | Intention liée à l'identité |
|---|---|---|---|---|
| `staging-api` | `api-01.staging.example.net` | `deploy` | direct | identité de déploiement de staging |
| `prod-api` | `api-01.prod.example.net` | `deploy` | `prod-bastion` | identité de déploiement de production |
| `prod-breakfix` | `api-01.prod.example.net` | `ops` | `prod-bastion` | identité réservée aux incidents |

N'écrivez pas « production » dans la colonne de destination. Écrivez la cible réelle utilisée par SSH. N'écrivez pas « utilisateur par défaut ». Écrivez `deploy`, `ubuntu`, `ec2-user` ou le compte reçu par le serveur. Si l'itinéraire comporte un hôte relais, nommez-le. Si l'alias se comporte différemment selon le réseau, créez une ligne distincte, car il s'agit d'une connexion effective différente.

La distinction utile est la suivante : **un alias identifie une entrée de configuration ; une destination identifie le point d'accès distant**. Les confondre conduit à de mauvaises approbations. Un responsable peut approuver l'ouverture d'une session vers `staging-api` tout en se trompant sur le point d'accès réel, parce que l'alias contient un comportement obsolète ou conditionnel.

Les alias devraient aussi décrire un objectif opérationnel, pas le dissimuler. `prod-readonly`, `prod-deploy` et `prod-breakfix` incitent à s'arrêter au bon endroit. Un alias unique nommé `prod`, qui choisit utilisateurs, clés et itinéraires dans des blocs conditionnels, économise quelques frappes et crée un problème permanent d'examen.

## Les blocs Match sont une logique de connexion exécutable

Un bloc `Match` n'est pas une étiquette pour un groupe d'hôtes. C'est une section conditionnelle de `ssh_config` qui détermine quelles directives s'appliquent. Les conditions peuvent porter sur l'hôte demandé, l'hôte d'origine, l'utilisateur distant, l'utilisateur local, l'état de canonicalisation, le réseau local, une commande demandée ou une commande `exec` exécutée par SSH via le shell local.

Cette puissance est utile. Elle signifie aussi qu'une configuration peut contenir un comportement invisible si l'on inspecte seulement l'alias `Host` voisin.

Considérez cette configuration :

```sshconfig
Host prod-api
    HostName api-01.prod.example.net
    User deploy
    ProxyJump prod-bastion

Match originalhost prod-api user root
    IdentityFile ~/.ssh/breakfix_ed25519
    IdentitiesOnly yes
```

Une personne qui ne lit que le bloc `Host prod-api` voit une connexion de déploiement avec l'utilisateur `deploy`. Si l'appelant exécute `ssh -l root prod-api`, la condition `Match originalhost prod-api user root` peut s'appliquer. La prise en compte de l'identité dépend aussi de l'endroit où les paramètres précédents ont été obtenus et du fait que l'option accepte ou non plusieurs valeurs. L'essentiel est plus simple : la connexion a changé à cause d'un argument utilisateur sur la ligne de commande, et non parce que l'alias a changé.

Pour les agents, évitez les règles `Match user` qui accordent une identité ou un itinéraire plus privilégié. Elles semblent propres parce qu'elles regroupent le comportement par nom de compte. Mais un outil appelant peut facilement les modifier avec `-l`, `user@host` ou une commande générée. Placez plutôt l'utilisateur prévu directement dans un alias correspondant à un objectif précis.

Une version plus sûre rend chaque intention explicite :

```sshconfig
Host prod-deploy
    HostName api-01.prod.example.net
    User deploy
    ProxyJump prod-bastion
    IdentityFile ~/.ssh/prod_deploy_ed25519
    IdentitiesOnly yes

Host prod-breakfix
    HostName api-01.prod.example.net
    User ops
    ProxyJump prod-bastion
    IdentityFile ~/.ssh/prod_breakfix_ed25519
    IdentitiesOnly yes
```

Cela ne rend pas l'accès privilégié inoffensif. Cela rend la connexion demandée compréhensible. Un agent doit recevoir une autorisation distincte pour appeler `prod-breakfix` ; il ne peut pas adopter ce comportement par hasard en changeant simplement un nom d'utilisateur.

`Match exec` mérite encore moins de confiance dans une configuration destinée aux agents. Il exécute une commande shell locale pendant l'évaluation de la configuration SSH. Les équipes l'utilisent pour détecter le réseau, consulter un inventaire ou sélectionner des identifiants. Une tentative de connexion SSH devient alors un chemin de code local dépendant de l'environnement. Si cette souplesse est nécessaire au travail humain, gardez ces alias en dehors de l'ensemble appelable par un agent. Un examen de connexion ne devrait pas exiger la rétro-ingénierie d'une commande shell arbitraire.

## La première valeur correspondante peut neutraliser votre exception

Le problème le plus tenace d'une configuration SSH n'est pas une section invalide. C'est une section valide placée après une règle plus générale qui a déjà défini l'option.

Supposons qu'un développeur écrive ceci pour imposer un bastion à la production :

```sshconfig
Host *
    User deploy
    ProxyJump dev-bastion

Host prod-*
    ProxyJump prod-bastion
```

L'attente est compréhensible : `prod-*` semble plus précis et devrait donc l'emporter. OpenSSH ne trie pas les blocs selon leur précision. Il les traite dans l'ordre du fichier et, pour de nombreuses directives, la première valeur obtenue l'emporte. `prod-api` conservera `dev-bastion`, car le bloc `Host *` précédent a déjà fourni `ProxyJump`.

Placez les blocs précis en premier :

```sshconfig
Host prod-*
    ProxyJump prod-bastion

Host *
    User deploy
    ServerAliveInterval 30
```

Ce n'est pas qu'une question de style. Un itinéraire passant par le mauvais bastion peut placer la session sur le mauvais chemin réseau. Une valeur par défaut générale `User deploy` peut amener un alias de production à s'authentifier avec un compte qui n'a rien à faire sur cet hôte. Un `IdentityFile` général peut proposer un identifiant inattendu avant celui qui était prévu.

Il ne faut toutefois pas appliquer aveuglément la règle de la première valeur. Certaines directives acceptent volontairement plusieurs valeurs, et `IdentityFile` en est un exemple courant. Plusieurs identités configurées peuvent être ajoutées à l'ensemble examiné par SSH. Le problème devient alors différent : un alias précis peut nommer la bonne identité tout en laissant disponibles d'autres identités provenant d'une configuration précédente ou de l'agent SSH local.

Pour les connexions automatisées, rendez la sélection de l'identité explicite et prévisible :

```sshconfig
Host prod-deploy
    HostName api-01.prod.example.net
    User deploy
    IdentityFile ~/.ssh/prod_deploy_ed25519
    IdentitiesOnly yes
    ProxyJump prod-bastion
```

`IdentitiesOnly yes` indique à OpenSSH d'utiliser uniquement les identités configurées dans SSH ou fournies sur la ligne de commande, au lieu d'essayer librement toutes celles disponibles dans un agent. Cela ne répare pas une configuration négligée. En revanche, cela empêche une clé sans rapport chargée dans l'agent local de devenir une candidate par accident.

On recommande souvent de placer toutes les valeurs par défaut dans `Host *` et de ne les remplacer qu'en cas de besoin. C'est raisonnable pour des paramètres sans incidence sur l'autorité, comme les intervalles de maintien de connexion. C'est une mauvaise pratique pour le choix de l'utilisateur, les itinéraires, les fichiers d'identité, les ports, `ProxyCommand` et la réécriture des hôtes. Les valeurs par défaut qui influencent l'autorité doivent rester rares. Un peu de répétition coûte moins cher que d'expliquer pourquoi un agent a atteint la bonne machine par le mauvais chemin.

## ProxyJump crée une autre connexion à examiner

`ProxyJump` n'est pas un simple attribut de la connexion vers la destination. SSH se connecte d'abord à l'hôte relais, puis établit depuis celui-ci un transfert TCP vers la destination. Plusieurs relais peuvent être indiqués et traversés dans l'ordre. Le manuel OpenSSH précise aussi que la configuration de l'hôte de destination ne s'applique généralement pas aux hôtes relais.

C'est souvent là que les examens échouent. Une configuration peut être précise pour `prod-api` et totalement vague pour `prod-bastion`.

```sshconfig
Host prod-api
    HostName 10.40.8.17
    User deploy
    ProxyJump prod-bastion

Host prod-bastion
    HostName bastion.prod.example.net
    User jump
    IdentityFile ~/.ssh/bastion_ed25519
    IdentitiesOnly yes
```

Il s'agit de deux décisions d'authentification et de deux identités d'hôte :

1. SSH authentifie le client local auprès de `bastion.prod.example.net` avec le compte `jump`.
2. Le bastion transfère un flux TCP vers `10.40.8.17`.
3. SSH s'authentifie à travers ce flux auprès de la destination avec le compte `deploy`.

L'hôte relais peut avoir une autre clé, un autre utilisateur, un autre port et un autre enregistrement de clé d'hôte. Il peut aussi être sélectionné par un alias générique ou un bloc conditionnel que personne ne vérifie, puisque l'agent n'a demandé que `prod-api`.

Examinez chaque étape avec `ssh -G`, pas seulement l'alias final :

```sh
ssh -G prod-api | egrep '^(hostname|user|port|proxyjump|identityfile|identitiesonly) '
ssh -G prod-bastion | egrep '^(hostname|user|port|identityfile|identitiesonly) '
```

La sortie contient une option par ligne. Un examen correct peut produire cette forme :

```text
hostname api-01.prod.example.net
user deploy
port 22
proxyjump prod-bastion
identityfile ~/.ssh/prod_deploy_ed25519
identitiesonly yes
```

Vérifiez ensuite le bastion séparément. Si `prod-api` utilise une chaîne séparée par des virgules, comme `edge-bastion,prod-bastion`, exécutez la commande pour les deux alias. Une chaîne n'est pas un itinéraire opaque : elle correspond à plusieurs configurations distinctes du client SSH.

Évitez de définir un itinéraire relais générique dans `Host *` ou dans un motif large comme `Host *.internal`. Il risque de capter des hôtes temporaires, des environnements de staging et des alias ajoutés des mois plus tard. Définissez l'itinéraire dans les alias qui en ont besoin. Si plusieurs alias de production l'utilisent, créez un motif étroit réservé à ces alias et ne le réutilisez pas sans précaution.

Vérifiez également `ProxyCommand`. OpenSSH traite `ProxyJump` et `ProxyCommand` comme des options concurrentes : celle qui est spécifiée en premier empêche les occurrences ultérieures de l'autre de prendre effet. Une configuration qui semble utiliser un bastion peut en réalité exécuter une commande proxy précédente. Les deux paramètres doivent être signalés, car ils modifient l'origine de la connexion réseau et la manière dont elle atteint la destination.

## Le choix de l'utilisateur modifie l'autorité approuvée

Le compte distant fait partie de l'action demandée. `deploy@api-01.prod.example.net` et `ops@api-01.prod.example.net` peuvent atteindre le même serveur, mais ils n'ont ni la même autorité, ni le même profil shell, ni les mêmes commandes forcées, droits sudo ou traces d'audit.

SSH peut obtenir l'utilisateur distant de plusieurs endroits : `user@host` dans la commande, `ssh -l user host`, une directive `User` ou, à défaut, le nom de l'utilisateur local. Un examen de configuration qui demande seulement « Quel hôte ? » est incomplet.

Utilisez des alias qui imposent un utilisateur lorsqu'un agent a une tâche définie :

```sshconfig
Host inventory-read
    HostName inventory.prod.example.net
    User inventory_ro
    IdentityFile ~/.ssh/inventory_ro_ed25519
    IdentitiesOnly yes

Host inventory-deploy
    HostName inventory.prod.example.net
    User deploy
    IdentityFile ~/.ssh/inventory_deploy_ed25519
    IdentitiesOnly yes
```

Ne donnez pas à un agent un nom d'hôte générique en espérant qu'une invite ou un wrapper le maintiendra sur le bon compte. Un générateur de commandes peut produire `ops@inventory.prod.example.net` aussi facilement que `deploy@inventory.prod.example.net`. La configuration doit rendre le chemin autorisé facile et les chemins privilégiés clairement distincts.

Testez les variantes qu'un outil peut générer :

```sh
ssh -G inventory-read | grep '^user '
ssh -G -l ops inventory-read | grep '^user '
ssh -G ops@inventory-read | grep '^user '
```

Si la deuxième ou la troisième commande produit un compte que vous n'aviez pas prévu de laisser utiliser à un agent, la configuration n'est pas validée. Corrigez l'interface appelante ou isolez l'alias. Un bloc `Match user` peut également s'activer avec l'une de ces variantes, ce qui justifie un test explicite plutôt qu'une simple lecture.

Pour les équipes, réservez l'accès `root` à un alias d'urgence nommé séparément et gardez-le hors des permissions ordinaires de l'agent. Masquer `User root` derrière une condition `Match` est pire que de l'écrire clairement. La condition devient une chasse au trésor pendant un incident, et un appelant peut parfois la satisfaire en modifiant un paramètre de la ligne de commande.

## IdentityFile contrôle plus que le chemin de la clé

`IdentityFile` semble ne servir qu'à sélectionner un fichier. En pratique, il détermine quel identifiant SSH peut présenter, et donc quelles règles d'autorisation distantes le serveur évaluera.

Voici un échec fréquent :

```sshconfig
Host *
    IdentityFile ~/.ssh/id_ed25519

Host prod-*
    IdentityFile ~/.ssh/prod_ed25519
```

L'opérateur pense que la production utilise `prod_ed25519`. SSH peut avoir les deux fichiers d'identité dans sa liste de candidats, car `IdentityFile` accepte plusieurs entrées. Si un agent SSH contient d'autres clés et que `IdentitiesOnly` est absent, celles-ci peuvent aussi être proposées. Certains serveurs rejettent tôt les propositions répétées, d'autres acceptent une identité inattendue qui donne par hasard accès. Aucun de ces résultats n'exprime clairement l'intention.

Un alias destiné à un agent doit exprimer un objectif d'identité unique et limiter les propositions :

```sshconfig
Host reports-export
    HostName reports.prod.example.net
    User exporter
    IdentityFile ~/.ssh/reports_export_ed25519
    IdentitiesOnly yes
```

Examinez ensuite la configuration effective au lieu de faire confiance à la section :

```sh
ssh -G reports-export | grep '^identityfile '
ssh -G reports-export | grep '^identitiesonly '
```

Plusieurs lignes `identityfile` ne sont pas automatiquement incorrectes. Les configurations fondées sur des certificats et une rotation planifiée des clés peuvent le justifier. Mais chaque identité listée doit appartenir à la même frontière d'autorité. Si un alias peut proposer une clé personnelle d'administrateur, une ancienne clé de déploiement et une clé d'automatisation de production, son histoire d'autorisation n'est pas claire.

Ne résolvez pas le problème en stockant des clés privées dans les fichiers, l'environnement, les invites ou les scripts générés de l'agent. Vous ne feriez que transformer une ambiguïté de configuration en exposition d'identifiants. Sallyport conserve les clés SSH dans son coffre chiffré et exécute les actions SSH par son intermédiaire, mais ne peut pas rendre honnête une configuration SSH ambiguë. L'alias, l'itinéraire, l'utilisateur et l'intention liée à l'identité doivent rester clairs avant l'approbation de l'agent.

La même règle vaut pour les noms de clés. Un chemin comme `~/.ssh/id_ed25519` n'indique pas l'usage prévu. `prod_deploy_ed25519` est préférable, mais la configuration doit encore expliquer quels groupes d'hôtes, quel utilisateur et quel itinéraire l'utilisent. Les noms de fichiers facilitent l'examen, ils ne le remplacent pas.

## La canonicalisation peut faire correspondre un alias deux fois

La canonicalisation des noms d'hôte est l'un des moyens les moins visibles par lesquels SSH modifie une configuration. Lorsque `CanonicalizeHostname yes` est activé, OpenSSH peut prendre un nom incomplet, lui ajouter des suffixes de domaine configurés, le résoudre, puis relire la configuration avec la nouvelle cible. `Match canonical` s'applique lors de cette seconde passe. `Match final` demande une analyse finale et correspond pendant cette passe ; lorsque la canonicalisation est activée, les conditions canonical et final correspondent ensemble.

Ce comportement peut être utile dans de grands réseaux internes. Il peut aussi transformer un alias court en piège de configuration conditionnelle.

```sshconfig
CanonicalizeHostname yes
CanonicalDomains corp.example.net

Host build
    User ci

Match canonical host *.prod.example.net
    ProxyJump prod-bastion
```

L'appelant saisit `ssh build`. La première passe voit `build`. Si la canonicalisation résout ce nom en `build.prod.example.net`, SSH relit la configuration et le bloc `Match canonical host *.prod.example.net` peut définir une route de production. La connexion n'a pas changé parce que l'appelant a demandé un autre alias. Elle a changé parce que le DNS et une seconde passe ont modifié l'hôte vu par les règles suivantes.

Le manuel OpenSSH distingue deux conditions souvent confondues :

- `Match originalhost` teste le jeton d'hôte fourni par l'appelant.
- `Match host` teste la cible après substitution de `HostName` ou canonicalisation.

Utilisez `originalhost` lorsque le comportement doit être lié à un alias nommé intentionnellement. Utilisez `host` lorsque le comportement doit dépendre de la destination réellement résolue. N'utilisez ni l'un ni l'autre à la légère pour modifier des privilèges.

La canonicalisation comporte une autre subtilité avec les bastions. `CanonicalizeHostname yes` ne s'applique normalement pas aux connexions utilisant `ProxyCommand` ou `ProxyJump` ; `CanonicalizeHostname always` l'étend aux connexions passant par un proxy. Deux alias qui semblent structurés de la même façon peuvent donc suivre des règles de réécriture différentes simplement parce que l'un possède un hôte relais.

Pour les permissions d'un agent, la politique la plus simple est souvent la meilleure : désactivez la canonicalisation pour les alias remis à un agent et utilisez des valeurs `HostName` complètes et explicites. Si votre environnement exige la canonicalisation, testez chaque alias autorisé dans le contexte réseau exact où l'agent s'exécute. Ne supposez pas qu'un nom court sera résolu de la même façon sur un réseau domestique, un réseau d'entreprise, un VPN et le Wi-Fi du bureau.

`Match localnetwork` pose le même problème. OpenSSH précise que l'adresse du réseau local n'est pas fiable pour une configuration sensible à la sécurité, notamment sur les réseaux configurés par DHCP. Elle convient aux réglages pratiques. Ne l'utilisez pas pour décider si un agent reçoit une identité plus privilégiée, contourne un bastion ou atteint la production.

## Rendez la connexion visible avant de l'autoriser

`ssh -G` est le moyen le plus rapide de transformer une configuration SSH en quelque chose de testable. Il affiche la configuration utilisée par SSH après le traitement des règles `Host` et `Match`, puis quitte sans ouvrir de connexion.

Exécutez-le avec l'alias et les arguments exacts utilisés par l'agent. Ne testez pas seulement une version nettoyée de la commande.

```sh
ssh -G prod-deploy | egrep '^(hostname|user|port|proxyjump|proxycommand|identityfile|identitiesonly|canonicalizehostname) '
```

Pour un audit sérieux, enregistrez la sortie complète comme référence dans le dépôt qui contient l'automatisation. Utilisez un fichier de configuration explicitement nommé afin que le test n'hérite pas silencieusement des paramètres personnels d'un développeur :

```sh
ssh -F ./agent-ssh-config -G prod-deploy > ./testdata/prod-deploy.effective
```

Examinez cette référence lorsque la configuration change. Une différence utile détecte une modification de `hostname`, `user`, `proxyjump` ou de la liste d'identités avant qu'elle n'atteigne un processus d'approbation. Une comparaison complète et bruyante vaut mieux que de faire confiance à une section copiée dans une demande de modification.

N'utilisez `ssh -vvv` qu'après avoir vérifié que `ssh -G` affiche les valeurs attendues. Les journaux détaillés aident à confirmer les clés d'hôte et les méthodes d'authentification réellement tentées par SSH, mais ils mélangent décisions de configuration et bruit réseau. `-G` répond d'abord à la question « Que dit cette configuration ? ». C'est ce qu'il faut établir avant de chercher un problème d'accès.

Testez volontairement les variantes :

```sh
ssh -F ./agent-ssh-config -G prod-deploy
ssh -F ./agent-ssh-config -G -l ops prod-deploy
ssh -F ./agent-ssh-config -G ops@prod-deploy
ssh -F ./agent-ssh-config -G prod-deploy.prod.example.net
```

Les résultats doivent rester dans la frontière d'autorité attendue ou échouer. Si un remplacement d'utilisateur modifie le compte, si une forme complète contourne le bastion ou si un nom court obtient une autre identité après canonicalisation, vous avez trouvé un chemin de configuration à fermer.

Vérifiez aussi les fichiers inclus. `Include` peut faire du `~/.ssh/config` une simple porte d'entrée vers un répertoire rempli de règles générées par la machine, l'entreprise ou le projet. Examinez la sortie effective avec le même compte local et le même chemin de configuration que ceux utilisés par l'agent. Tester depuis votre shell alors que l'agent utilise un autre compte donne une fausse impression de certitude.

## Gardez une configuration SSH réduite et conçue pour les agents

La meilleure configuration SSH pour un agent de programmation autonome n'est généralement pas votre configuration personnelle à laquelle vous avez ajouté quelques commentaires. Les configurations personnelles accumulent raccourcis, exceptions de client, anciens alias, comportements liés au réseau local, agents transférés et identités qui ont été pratiques un jour. Un agent a besoin d'un catalogue de connexions limité.

Créez un fichier de configuration dédié qui ne contient que les alias approuvés et les hôtes relais nécessaires. Dirigez l'agent ou son wrapper d'exécution vers ce fichier avec `-F`. Donnez à chaque alias une seule fonction, un `HostName`, un utilisateur, un itinéraire et une intention d'identité explicites. Évitez la logique conditionnelle sauf si vous pouvez démontrer qu'un alias statique ne suffit pas.

Un exemple compact :

```sshconfig
Host prod-bastion
    HostName bastion.prod.example.net
    User jump
    IdentityFile ~/.ssh/prod_bastion_ed25519
    IdentitiesOnly yes

Host prod-deploy
    HostName api-01.prod.example.net
    User deploy
    ProxyJump prod-bastion
    IdentityFile ~/.ssh/prod_deploy_ed25519
    IdentitiesOnly yes

Host staging-deploy
    HostName api-01.staging.example.net
    User deploy
    IdentityFile ~/.ssh/staging_deploy_ed25519
    IdentitiesOnly yes
```

Cette configuration se répète. C'est une bonne chose. Le fichier indique au responsable ce que signifie chaque connexion sans lui demander d'exécuter mentalement la priorité des jokers et l'état des conditions.

Ne confondez pas un fichier dédié avec un moteur de politique. Il ne peut pas prouver qu'une commande est sûre après l'ouverture de la session. Il peut rendre la connexion de transport suffisamment concrète pour être examinée : cet alias, ce point d'accès, cet utilisateur, cet itinéraire, cette identité. C'est une limite utile.

Les autorisations par session et les journaux d'activité de Sallyport donnent aux opérateurs un point de contrôle humain et une trace des actions de l'agent, mais la configuration SSH fournit toujours les faits qui sous-tendent l'action. Si `prod-deploy` peut se transformer en plusieurs chemins réseau ou comptes, la configuration a déjà rendu l'approbation moins fiable.

Avant d'autoriser un agent à utiliser un alias SSH, rendez-le effectif, examinez chaque hôte relais et testez les variantes de ligne de commande que l'agent peut produire. Si la connexion effective vous surprend une fois, supposez qu'elle surprendra quelqu'un au pire moment. Corrigez l'alias jusqu'à ce qu'il ressemble à une approbation qu'une personne peut réellement donner.
