ADR-115 — CLI air-keystore : outil d’administration des clés (équivalent ssh-keygen élargi) + mode JSON agent-safe, dogfooding de l’API keystore
Statut : Accepté (2026-07-26, décision BDFL). RFC de direction
(ADR-015).
S’appuie sur ADR-108 (API
air-keystore + air-keysign), ADR-109 (certificats/CA),
ADR-114 (air-json — mode JSON), ADR-101
(gate mot de passe admin), ADR-095 (packaging
d’exécutables), ADR-103 (discipline linux-air),
ADR-029 (nommage).
Catégorie : Couche 2 (exécutable d’administration) + outillage. Vague 2 #3.
Contexte
air-keystore ([ADR-108]) est une bibliothèque ; il lui faut un outil en ligne de
commande — l’équivalent Air de ssh-keygen, élargi à la CA, aux hôtes de confiance et à la
révocation. Deux motivations : (1) un administrateur doit pouvoir manipuler le magasin ;
(2) c’est un excellent test bout-en-bout de l’API keystore (dogfooding) — si l’API est
pénible à piloter depuis un outil, elle est mal conçue.
De plus, l’outil doit être utilisable par un agent/outil programmatique (un agent LLM) : le parsing de ligne de commande shell (simples/doubles/back quotes) est un piège — d’où un mode JSON in/out ([ADR-114]).
Directive BDFL (2026-07-26). « Un utilitaire ligne de commande pour manipuler le keystore : lister, exporter, importer… c’est aussi un très bon exemple pour tester notre API keystore. » Puis : « ajouter une capacité de lire/écrire JSON en entrée/sortie, pour qu’un outil (un agent LLM ?) manipule l’in/out de manière sûre, sans problème de parsing shell. »
Décision
1. air-keystore (CLI) — exécutable couche 2, packagé
Un binaire air-keystore (couche 2, « toit » consommant l’API [ADR-108] + air-json
[ADR-114]), compilé *-linux-air ([ADR-103]), livré en paquet Debian (ajouté à la liste
des exécutables packagés, [ADR-095]). Le nommage des sous-commandes suit [ADR-029] (verbes
explicites ; termes hérités OpenSSH — known-hosts, ca, cert — conservés).
2. Surface de commandes (équivalent ssh-keygen élargi)
key generate | list | show | import | export | remove | fingerprinthost-trust(magasin d’hôtes de confiance) ·known-hosts(TOFU/rotation)ca create | show | exportcert issue | inspect | verify | revoke([ADR-109])revoke add | list | check(KRL)expiry list(clés/certs expirés)
Interop OpenSSH : import/export lisent/écrivent les formats OpenSSH/PEM ([ADR-108]) ;
le stockage interne reste binaire scellé.
3. Gate admin et clés privilégiées
Les mutations du magasin propre du système, de la CA et des clés d’hôte sont
gatées par le mot de passe admin ([ADR-101]). Les opérations sur la clé d’hôte privée
passent par le service air-keysign ([ADR-108] §5) ou par root — jamais d’accès direct
au matériel privilégié depuis la CLI non privilégiée. Un magasin utilisateur (clés perso,
known_hosts) ne requiert pas le gate admin.
4. Mode JSON agent-safe (contrat [ADR-114])
--json: sortie structurée (JSON) sur toutes les lectures (list,show,inspect,expiry list…).--json-input: payload de commande lu surstdin(zéro quoting shell).- Erreurs en JSON sur
stdoutavec code de sortie ≠ 0. - Zéro prompt TTY : le secret admin est fourni par champ JSON ou
stdin, jamais par une invite interactive → pilotable sans pseudo-terminal. - C’est l’interface recommandée pour l’usage programmatique/agent : elle contourne tout
parsing shell (anti-injection ticks/backticks) et réutilise le codec
air-jsonfuzzé.
5. Dogfooding
La CLI est un test bout-en-bout de l’API air-keystore : les scénarios (générer → exporter
→ ré-importer → révoquer → vérifier) exercent la surface publique du manager de bout en bout, et
valident l’ergonomie de l’API (une API pénible à piloter est un défaut à corriger).
6. Empreinte SHA-256 + option de compat OpenSSH HostkeyAlias (ajout 2026-07-30)
La clôture d’[ADR-109] (Inc.5) a prouvé que l’interop du cert d’hôte par un client
OpenSSH via HostkeyAlias est inopérante : OpenSSH abaisse la casse de l’alias avant
de le comparer aux valid_principals, or l’identité machine M = SHA256:<base64> ([ADR-137]) est
sensible à la casse ⇒ le principal ne matche jamais. La décision d’[ADR-137] §5 (BDFL) est
« documenter la limite, ne pas affaiblir M par défaut ». La CLI offre néanmoins à
l’opérateur un chemin explicite et opt-in :
-
key fingerprint <clé> [--lowercase]: imprime l’empreinteSHA256:<base64>d’une clé (publique) ; avec--lowercase, imprime la forme entièrement en minuscules (sha256:<base64-minuscule>) — exactement ce que produit OpenSSH sur unHostkeyAlias. Utilitaire de diagnostic/interop, sans effet de bord. -
cert issue-host … --openssh-hostkey-alias-compat: émet le cert d’hôte avec, en plus du principal exactM, un second principallowercase(M). Le cert reste pleinement Air-native (la vérif Air recalculeMexact — [ADR-137] invariant 3) et devient vérifiable par un client OpenSSH configuré@cert-authority+HostkeyAlias(son alias abaissé matchelowercase(M)).
Cadre de sécurité (impératif). L’option est opt-in et jamais le défaut. Le principal
lowercase(M) a une résistance aux collisions réduite (le repli de casse fusionne les 26
paires de lettres base64) — suffisante en pratique mais strictement inférieure à M exact.
Elle sert uniquement la commodité d’un client OpenSSH tiers ; l’identité de référence d’Air
reste M exact. La CLI avertit à l’émission et le documente. Air ne dégrade jamais
son propre modèle d’identité : la vérification Air-native ignore la forme minuscule.
Conséquences
Positives.
- Administration réelle du keystore/CA/hôtes/révocation par un seul outil cohérent.
- Agent-safe : le mode JSON rend l’outil pilotable par un agent/programme sans le piège du shell.
- Dogfooding : valide l’API [ADR-108] et sa qualité d’ergonomie.
- Interop : import/export OpenSSH ⇒ migration et coexistence.
Négatives / coûts assumés.
- Surface CLI large (nombreuses sous-commandes) : coverage + tests d’intégration conséquents ; chaque commande = un chemin à couvrir.
- Exécutable privilégié partiel (mutations gatées, ops clé d’hôte via
air-keysign) : soin requis sur les frontières de privilège. - Paquet supplémentaire à maintenir (PACKAGES, [ADR-095]).
Mise en œuvre (référence, hors décision). Incréments : (a) binaire air-keystore (parsing
d’arguments + sous-commandes) sur l’API [ADR-108] ; (b) mode --json/--json-input via
air-json [ADR-114] ; (c) gate admin [ADR-101] + intégration air-keysign ; (d) packaging .deb
[ADR-095] ; (e) tests bout-en-bout (dogfooding). Non engagés par cet ADR.
Alternatives rejetées
Aucune alternative n’a été consignée lors de l’instruction.