claria.tools.ssh-client 2.0.0-build.20260819.1

Build Information

Provenance Azure DevOps Pipeline
Owner kntera (Yan Boivin)
Date de compilation 2026-08-20 03:22:20 UTC
Version 2.0.0.20260819.1
SHA256 c459994b8934484f497073c13eb1e289a1d66b28

ssh-client

Outil en ligne de commande qui exécute des commandes sur un serveur distant via SSH, sous le contrôle d'une politique d'autorisation (allow / deny). Conçu pour permettre à des agents d'installer et de maintenir des serveurs en gardant l'humain aux commandes sur toute opération non couverte par la politique.


Contexte

Plutôt que d'exposer ssh brut à un agent, ssh-client s'intercale comme garde-fou : chaque commande est évaluée contre une liste allow et une liste deny avant d'être exécutée. Une commande refusée n'ouvre même pas de connexion ; une commande inconnue signale à l'appelant qu'une décision humaine est requise. Chaque exécution (y compris les refus) est journalisée dans une session.

Spécifications complètes : doc/spec/** (A01 portée, E01 CLI, E02 connexions, E03 politique, E04 exécution, E05 sessions, E06 transferts, E07 espaces de configuration).


Utilisation

ssh-client exec  --host <alias> [--timeout <sec>] [--json] [--once] -- <commande…>
ssh-client upload   --host <alias> [--json] <chemin-local> <chemin-distant>
ssh-client download --host <alias> [--json] <chemin-distant> <chemin-local>
ssh-client policy check [--namespace <espace>] <commande>
ssh-client policy allow [--namespace <espace>] <motif>
ssh-client policy deny  [--namespace <espace>] <motif>
ssh-client policy allow-upload   [--namespace <espace>] <motif-distant>
ssh-client policy allow-download [--namespace <espace>] <motif-distant>
ssh-client policy remove [--namespace <espace>] <motif>
ssh-client policy list [--json]
ssh-client host add <alias> --host <fqdn|ip> --user <utilisateur> --key <chemin> [--passphrase-stdin] [--port <n>]
ssh-client host add <alias> --host <fqdn|ip> --user <utilisateur> --password-stdin [--port <n>]
ssh-client host add <alias> --lxd-host <alias-hôte> --vm <nom-vm>
ssh-client host remove <alias>
ssh-client host list [--json]
ssh-client host test <alias>
ssh-client session start [<id>]
ssh-client session end [<id>]
ssh-client session current [--json]
ssh-client session list [--json]
ssh-client --version | --readme | --help

Option globale : --config-dir <chemin> fixe la racine de configuration (sinon SSHCLIENT_HOME, sinon ./.conf/ssh-client s'il existe, sinon ~/.conf/ssh-client s'il existe, sinon ./.conf/ssh-client créé à la première écriture — voir « Espaces de configuration »). --session <id> cible une session précise (créée si absente). --no-sessions désactive l'inscription locale des sessions (équivaut à SSHCLIENT_NO_SESSIONS=1).


Espaces de configuration (.conf/)

La configuration est lue par agrégation de sous-répertoires, comme les conf.d/ de nginx. La racine .conf/ssh-client/ contient un sous-répertoire par espace de configuration, chacun autonome (ses hôtes et leurs defaults dans config.json, ses secrets dans credentials.json, sa politique — commandes et transferts — dans policies.json) ; les journaux — sessions et debug — vont dans .log/ssh-client/ du répertoire de travail :

.conf/ssh-client/
├── default/   config.json, credentials.json, policies.json   ← espace par défaut
├── prod/      config.json, credentials.json, policies.json   ← autre espace
└── lab/       config.json

.log/ssh-client/
├── sessions/  index.json, <date>-<id>.jsonl
└── ssh-debug-AAAA-MM-JJ.log
  • Racine : --config-dir, sinon SSHCLIENT_HOME, sinon le ./.conf/ssh-client local s'il existe, sinon celui du profil (~/.conf/ssh-client) s'il existe, sinon le local (créé à la première écriture). Une seule racine sert aux lectures et aux écritures d'une invocation ; host list la rappelle sur stderr.
  • Référence d'hôte : <espace>/<alias> (exacte) ou <alias> seul → l'unique espace qui le déclare, sinon l'espace default, sinon erreur 250 (« hôte ambigu » : préciser prod/web01 ou lab/web01). Un alias ne contient pas de /.
  • Déclaration : host add prod/web01 … écrit dans prod/ (créé au besoin) ; host add web01 … remplace l'hôte là où il existe, sinon va dans default/. Un hôte LXD est déclaré dans l'espace de son hôte parent.
  • Politique par espace : les listes d'un policies.json ne gouvernent que les hôtes de leur espace. Les commandes policy visent l'espace de --namespace <espace> ; sans l'option : l'unique espace, sinon default, sinon 250. policy list groupe par espace. Les suggestions émises pour une commande ou un transfert inconnu portent déjà le --namespace voulu.
  • defaults par espace : timeoutSeconds, connectTimeoutSeconds s'appliquent aux hôtes de l'espace ; sessionInactivityMinutes (global) vient de default, sinon de l'unique espace, sinon 10 min.
  • L'ancien ./.ssh-client/ n'est plus lu : un diagnostic invite à déplacer ses fichiers dans ./.conf/ssh-client/default/.

Connexions

Les serveurs sont déclarés par alias dans un espace de configuration (référence <alias> ou <espace>/<alias>, voir « Espaces de configuration »). L'authentification se fait par clé SSH importée ou par mot de passe. Les secrets (contenu de clé, passphrase, mot de passe) sont stockés à part dans credentials.json (durci), jamais dans config.json, et se fournissent sur l'entrée standard.

# Par clé (le contenu de la clé est importé, pas le chemin) — espace default
ssh-client host add web01 --host web01.example.com --user admin --key ~/.ssh/id_ed25519

# Dans un espace de configuration dédié (.conf/ssh-client/prod/) — référence prod/web01
ssh-client host add prod/web01 --host web01.example.com --user admin --key ~/.ssh/id_ed25519

# Par mot de passe
printf '%s' 'le-mot-de-passe' | ssh-client host add db01 --host db01.example.com --user dba --password-stdin

ssh-client host test web01     # vérifie connexion, auth, empreinte d'hôte
ssh-client host list

L'empreinte de la clé d'hôte est capturée à la première connexion (TOFU) ; un changement ultérieur fait échouer la connexion (code 255).

Hôte LXD (VM via un hôte parent)

Une VM LXD hébergée par un hôte déjà déclaré se cible comme un hôte à part entière : la connexion se paramètre avec l'alias de l'hôte parent puis le nom de la VM. Les commandes qui ciblent la VM sont exécutées sur le LXD de l'hôte parent (lxc exec <vm> -- sh -c '…'), avec les identifiants du parent — l'hôte LXD n'a aucun secret propre.

ssh-client host add vm01 --lxd-host web01 --vm app-vm
ssh-client exec --host vm01 -- systemctl status nginx   # → lxc exec app-vm … sur web01

La politique d'autorisation s'évalue sur la commande destinée à la VM (pas sur la forme lxc exec enveloppée). Les transferts upload/download sont supportés : le fichier transite par l'hôte parent (SFTP + lxc file push/pull, fichier temporaire supprimé ensuite), et la liste d'autorisation s'évalue sur le chemin dans la VM.

ssh-client upload   --host vm01 ./app.tar.gz /srv/app/app.tar.gz   # SFTP → web01, puis lxc file push
ssh-client download --host vm01 /var/log/app.log ./app.log         # lxc file pull, puis SFTP → local

Sessions

Une session regroupe les exec d'une période de travail et journalise chaque commande (y compris refusée) avec son résultat dans .log/ssh-client/sessions/<AAAAMMJJhhmmss>-<id>.jsonl (dans le répertoire de travail, commun à tous les espaces).

ssh-client session start maintenance-1
ssh-client session current
ssh-client session end maintenance-1

La session active est la dernière session non terminée et non expirée (expiration : 10 min d'inactivité par défaut). Sans session active, un exec en crée une automatiquement.


Exécution et politique d'autorisation

ssh-client policy check systemctl status nginx     # décision sans exécuter (espace default ou unique)
ssh-client policy check --namespace prod systemctl status nginx   # politique de l'espace prod
ssh-client exec --host web01 -- systemctl status nginx
ssh-client exec --host prod/web01 -- systemctl status nginx         # évalué contre prod/policies.json

La liste deny est prioritaire. Les commandes composées (;, &&, |…) sont découpées en segments évalués individuellement.

code Signification
0–249 Exécutée ; code de sortie distant propagé.
250 Erreur de configuration (hôte inconnu ou ambigu entre plusieurs espaces, identifiants absents).
251 Délai d'inactivité dépassé (aucune sortie ; défaut 300 s, --timeout 0 = illimité).
252 Erreur d'usage.
253 Commande inconnue — autorisation utilisateur requise (rien exécuté).
254 Refusée par une règle deny (rien exécuté).
255 Erreur de connexion SSH (réseau, auth, empreinte).

L'ajout d'un motif à allow ou deny est une décision explicite de l'utilisateur : présenter la commande inconnue, recueillir la décision, puis seulement policy allow / policy deny (ou exec --once pour une autorisation ponctuelle).


Transfert de fichiers (upload / download)

Copie de fichiers entre la machine locale et le serveur via SFTP, sous une liste d'autorisation dédiée dans policies.json (sections upload et download, motifs glob sur le chemin distant, * accepté).

ssh-client policy allow-upload "/srv/app/*"           # décision explicite de l'utilisateur (--namespace <espace> au besoin)
ssh-client upload   --host web01 ./app.tar.gz /srv/app/app.tar.gz
ssh-client download --host web01 /var/log/app.log ./app.log
  • upload prend <chemin-local> <chemin-distant> ; download prend <chemin-distant> <chemin-local>. Une destination répertoire conserve le nom du fichier source.
  • Un chemin distant non couvert par la liste → code 253 (autorisation utilisateur requise) ; l'agent demande, puis policy allow-upload / allow-download sur décision explicite.
  • Chaque transfert (y compris refusé) est journalisé dans la session et le journal de debug avec les métadonnées du fichier : nom, SHA-256, date et taille.

Codes de sortie : 0 succès · 250 config/fichier introuvable · 252 usage · 253 non autorisé · 255 erreur SFTP.


Sécurité

  • Deny prioritaire et défaut fermé : une commande non couverte n'est jamais exécutée silencieusement.
  • Secrets isolés dans credentials.json (permissions propriétaire seul sous POSIX), jamais affichés ni journalisés.
  • Journalisation de chaque décision et de son résultat dans la session.

Le modèle est coopératif : ssh-client structure et trace les actions d'un agent ; il se combine à l'allowlist du harnais (n'autoriser que ssh-client, jamais ssh brut, ni l'édition directe des fichiers de politique).

No packages depend on claria.tools.ssh-client.

Build 2.0.0.20260819.1 du 2026-08-20 03:22:21 UTC - pipeline skill tools - ssh-client run 2118 - commit c459994b8934484f497073c13eb1e289a1d66b28

This package has no dependencies.

Version Downloads Last updated
2.0.0-build.20260819.1 15 08/20/2026