ADR-095 — Packaging des exécutables air-ssh : deux binaires séparés (air-ssh client / air-sshd serveur), client à verbes style git, pas de binaire « config-only »
Statut : Accepté (2026-07-23, décision BDFL). Fixe la granularité des
exécutables de la famille air-ssh, au-dessus de la vision
ADR-074, du transport
ADR-093 (cœur sans-IO air-ssh-proto) et de la phase 2
ADR-094 (ssh-userauth). S’appuie sur la doctrine de
configuration binaire
ADR-033/ADR-040/ADR-073,
la coexistence /etc ADR-041, le motif réseau sans-IO
ADR-091 et le nommage
ADR-029. Cadre l’orientation figée dans
la note sauvegarde/restauration (§5).
Catégorie : Architecture (couche 2, packaging du premier service réseau). Toute évolution structurante passe par un RFC (ADR-015).
Note de portée. Le présent ADR ratifie la seule granularité des exécutables de la famille
air-ssh. D’autres consignes BDFL propres àair-ssh(jeu exact de verbes, format de config cliente, session/PTY) sont attendues et seront gravées par addendum ou RFC (ADR-015) sans rouvrir la décision de packaging.
Contexte
air-sshd (phases 1–2) fournit le serveur. Il faut décider comment sont packagés les
exécutables de la famille air-ssh, sur deux axes indépendants :
- Client vs serveur — un seul exécutable multi-appel (dispatch
argv[0], façon busybox) ou deux exécutables distincts ? - Responsabilités du client — le client fait-il à la fois l’établissement de connexion et la manipulation de sa configuration, ou faut-il un exécutable dédié à la seule production de configuration cliente ?
La config Air étant binaire (ADR-073), il n’existe pas d’édition « à l’éditeur de texte » : un chemin d’outillage pour produire/muter la config binaire par-utilisateur est nécessaire. La question est où il vit, pas s’il existe.
Décision
1. Deux exécutables séparés — air-ssh (client) et air-sshd (serveur)
Le client et le serveur sont deux binaires distincts. Pas d’exécutable unique multi-appel.
- Frontière de privilège / surface d’attaque. Le serveur est un daemon privilégié
(écoute, privsep,
drop_to_user, lecture de la config système/etc/air+ desauthorized_keyspar-utilisateur). Le client tourne comme l’utilisateur non privilégié et lit son home. Un binaire unique ferait cohabiter les deux surfaces dans le même exécutable — contraire à la posture secure-first d’Air (doctrine SecurityManager). Une invocation cliente ne doit jamais embarquer le code serveur (listen/accept/privsep). - Moindre surprise. Le crate est déjà
air-sshd;air-ssh/air-sshdcalquessh/sshd(ADR-029 :sshest le nom propre du protocole, pas une abréviation à proscrire). - Système de base & reproductibilité. Un serveur headless livre
air-sshdsans client, et inversement — inventaire du « système Air de base » plus net (cf. note d’orientation §1–§2). - Coût nul. Toute la logique protocolaire vit dans le cœur sans-IO
air-ssh-proto(ADR-093) ; les deux binaires ne sont que de minces pilotes I/O au-dessus du même cœur. On sépare deuxmain, on ne duplique aucune logique.
2. Client — binaire unique air-ssh à verbes style git
Le client est un seul binaire avec sous-commandes ; on n’introduit pas de troisième exécutable dédié à la seule manipulation de configuration cliente.
air-ssh connect user@host # chemin quotidien (verbe primaire)
air-ssh config … # lecture/écriture de la config binaire par-utilisateur (XDG)
air-ssh keygen … # production d'identités / artefacts
(Le jeu exact de verbes et leur surface CLI seront figés par les incréments d’implémentation et d’éventuelles consignes BDFL complémentaires ; cet ADR fixe le principe « un binaire, des verbes ».)
- Séparation par verbe, pas par binaire. Côté client il n’y a aucune frontière de privilège à isoler : connexion (chemin chaud) et écriture de config (chemin froid) tournent comme le même utilisateur, propriétaire de son home. L’argument de surface d’attaque du §1 ne s’applique donc pas ici ; séparer par binaire coûterait en ergonomie sans rien acheter.
- Convention CLI moderne (git, cargo) : un outil à installer, un arbre de doc, verbes découvrables.
- Logique dans les crates. L’écriture de config s’appuie sur
air-config-compile(ADR-040) ; le verbe n’est qu’un pilote. Un verbe peut être ré-adossé à un autre crate plus tard sans changer l’UX deair-ssh connect.
3. Emplacement & format de la config cliente
- Config cliente = propriété de l’utilisateur, dans son home, sous la cascade XDG /
freedesktop.org (
$XDG_CONFIG_HOME, défaut~/.config/air/ssh/…), conformément à la note d’orientation §3. Format binaire Cap’n Proto viaair-config(ADR-073/040) : XDG fixe où, la doctrine binaire fixe comment. - Sauvegarder le home capture donc par construction la config cliente (cohérent avec l’invariant de la note d’orientation §1).
4. Config système sshd — hors du client
La production/mutation de la config système du serveur (/etc/air : politique sshd, host
keys ; authorized_keys système) relève d’un outil admin-gated (air-config-based,
côté serveur), soumis au « CLI dédié exigeant la ressaisie du mot de passe administrateur »
d’ADR-073. Ce n’est pas une responsabilité du client air-ssh.
| Rôle | Binaire | Modèle |
|---|---|---|
| Serveur | air-sshd | daemon privilégié séparé (privsep, /etc/air + authorized_keys) |
| Client | air-ssh | binaire unique, verbes git-style : connect + config/keygen (config user-owned, XDG, binaire) |
| Config système sshd | outil admin-gated (air-config-based, côté serveur) | ADR-073 (ressaisie mot de passe admin) — pas le client |
Conséquences
- La topologie de crates d’ADR-093 est respectée :
air-ssh-proto(cœur sans-IO invariant),air-sshd(pilote serveur). Ajout :air-ssh(pilote client), mince, au-dessus du même cœur. Le partage de code passe par les crates, pas par un binaire commun. - Aucune duplication de logique protocolaire : client et serveur consomment
air-ssh-proto. - L’ergonomie cliente suit la convention git ; l’utilisateur n’a qu’un binaire client à connaître.
- Cadre le « emplacement figé par l’incrément » laissé ouvert par ADR-094 (U.3) côté serveur, et fixe la cascade XDG côté client.
- Dette / à figer par les incréments : jeu exact de verbes
air-ssh, schéma.capnpde la config cliente, articulationconnect↔ session/PTY (phase 3,ssh-connection).
Alternatives rejetées
- Exécutable unique multi-appel (busybox, dispatch
argv[0]). Mêle les surfaces client/serveur dans un même binaire — contraire à secure-first. Le seul bénéfice (empreinte) est illusoire : le gros du code est déjà partagé par lien sur les crates ; deuxmainminces ne coûtent presque rien, y compris sur matériel modeste (Pi 4). - Binaire client dédié « config-only » séparé de
air-ssh connect. Aucune frontière de privilège à isoler côté client (même utilisateur, même home) ; multiplier les binaires dégrade l’ergonomie sans gain de sécurité. La séparation des concerns est obtenue par verbe. - Édition texte de la config cliente. Exclue par la doctrine binaire (ADR-073) : jamais de config texte comme source de vérité vivante.