claria.tools.windows-client 1.0.0-build.20260819.1
Build Information
| Provenance | Azure DevOps Pipeline |
| Owner | kntera (Yan Boivin) |
| Date de compilation | 2026-08-20 03:36:18 UTC |
| Version | 1.0.0.20260819.1 |
| SHA256 | c459994b8934484f497073c13eb1e289a1d66b28 |
windows-client
Outil en ligne de commande qui exécute des commandes PowerShell et
téléverse des fichiers sur un serveur Windows distant via WinRM
(PowerShell Remoting) ou OpenSSH, sous le contrôle d'une politique
d'autorisation (allow / deny pour les commandes, allow-list upload
pour les transferts). Conçu pour permettre à des agents d'installer et de
maintenir des serveurs Windows en gardant l'humain aux commandes sur toute
opération non couverte par la politique.
Contexte
Plutôt que d'exposer Invoke-Command, winrs ou ssh bruts à un agent,
windows-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.
Même modèle de sécurité, de configuration et de journalisation que le projet
frère ssh-client. Spécifications complètes : doc/spec/** (A01 portée,
E01 CLI, E02 connexions, E03 politique, E04 exécution, E05 sessions,
E06 transfert de fichiers).
Utilisation
windows-client exec --host <alias> [--timeout <sec>] [--json] [--once] (-- <commande…> | --command-stdin)
windows-client upload --host <alias> [--json] <chemin-local> <chemin-distant>
windows-client policy check (<commande> | --command-stdin)
windows-client policy allow (<motif> | --pattern-stdin)
windows-client policy deny (<motif> | --pattern-stdin)
windows-client policy allow-upload (<motif-distant> | --pattern-stdin)
windows-client policy remove (<motif> | --pattern-stdin)
windows-client policy list [--json]
windows-client host add <alias> [--type winrm] --host <fqdn|ip> --user <utilisateur> --password-stdin [--port <n>] [--ssl] [--auth <negotiate|basic>]
windows-client host add <alias> --type openssh --host <fqdn|ip> --user <utilisateur> --key <chemin> [--passphrase-stdin] [--port <n>] [--shell <powershell|pwsh>]
windows-client host add <alias> --type openssh --host <fqdn|ip> --user <utilisateur> --password-stdin [--port <n>] [--shell <powershell|pwsh>]
windows-client host remove <alias>
windows-client host list [--json]
windows-client host test <alias>
windows-client session start [<id>]
windows-client session end [<id>]
windows-client session current [--json]
windows-client session list [--json]
windows-client --version | --readme | --help
Option globale : --config-dir <chemin> (sinon WINDOWSCLIENT_HOME, sinon
./.windows-client — local au projet, créé au besoin ; en lecture seule,
repli sur les fichiers livrés à côté du binaire). --session <id>
cible une session précise (créée si absente).
Connexions
Les serveurs sont déclarés par alias, avec deux types de connexion :
winrm(défaut) : WS-Management sur HTTP (port 5985) ou HTTPS (port 5986,--ssl), authentificationnegotiate(Kerberos/NTLM, défaut) oubasic(HTTPS obligatoire) ;openssh: serveur OpenSSH du serveur Windows (port 22), authentification par clé SSH importée ou par mot de passe ; la commande PowerShell est exécutée au travers d'une enveloppepowershell/pwsh(--shell).
Quel que soit le type, la commande soumise est du PowerShell et la même
politique s'applique. Les secrets (mot de passe, contenu de clé, passphrase)
sont stockés à part dans credentials.json (durci), jamais dans
config.json, et se fournissent sur l'entrée standard.
# WinRM, Negotiate sur HTTP (chiffrement au niveau message)
printf '%s' 'le-mot-de-passe' | windows-client host add srv01 --host srv01.example.com --user Administrator --password-stdin
# WinRM, Basic sur HTTPS (compte local, certificat épinglé en TOFU)
printf '%s' 'le-mot-de-passe' | windows-client host add srv02 --host srv02.example.com --user admin --password-stdin --ssl --auth basic
# OpenSSH, par clé (le contenu de la clé est importé, pas le chemin)
windows-client host add srv03 --type openssh --host srv03.example.com --user admin --key ~/.ssh/id_ed25519
windows-client host test srv01 # vérifie connexion, auth, empreinte (certificat ou clé d'hôte)
windows-client host list
L'empreinte de référence — certificat serveur (winrm + HTTPS) ou clé d'hôte
SSH (openssh) — est capturée à la première connexion (TOFU) ; un changement
ultérieur fait échouer la connexion (code 255).
Sessions
Une session regroupe les exec et les upload d'une période de travail et
journalise chaque commande et transfert (y compris refusés) avec son résultat
dans .log/windows-client/sessions/<yyyyMMddHHmmss>-<id>.jsonl (dans le
répertoire de travail).
windows-client session start maintenance-1
windows-client session current
windows-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.
Guillemets doubles — passer par stdin
Windows PowerShell 5.1 supprime les guillemets doubles d'un argument destiné
à un exécutable natif, avant même que le processus ne démarre : la commande
arrive amputée. Le plus coûteux n'est pas l'erreur de syntaxe, c'est le cas où la
commande reste valide et change de cible — Get-ChildItem "C:\Program Files\X" privé de ses guillemets est découpé sur l'espace et s'exécute sans
erreur sur autre chose. Sur un motif deny, la règle enregistrée n'interdit plus
ce que son auteur a écrit.
Aucun traitement côté outil ne peut récupérer ces guillemets : ils n'atteignent
jamais le processus (--% n'y change rien). D'où un canal qu'aucun shell ne
réécrit — l'entrée standard :
@'
Get-ScheduledTask | Where-Object { $_.TaskName -like "*ocker*" }
'@ | windows-client exec --host srv01 --command-stdin
@'
Get-ChildItem "C:\Program Files\*"
'@ | windows-client policy allow --pattern-stdin
| Appelant | Guillemets doubles en argument | Remède |
|---|---|---|
| Windows PowerShell 5.1 | supprimés | --command-stdin / --pattern-stdin |
| Bash, Git Bash (MSYS) | échappés \", intacts |
argument suffisant |
cmd.exe |
transmis tels quels | argument suffisant |
Les guillemets simples traversent intacts partout : ils restent la forme la
plus simple dès qu'une valeur n'a pas besoin de guillemets doubles. policy check sert de contrôle — si la commande s'affiche sans ses guillemets, l'appelant
les a supprimés.
Côté serveur, la commande est interprétée par PowerShell : dans une chaîne à guillemets doubles,
`et$sont actifs. Pour qu'ils arrivent littéralement (par exemple vers unwsl … bash -c …), les écrire entre guillemets simples dans la commande elle-même. L'outil, lui, ne réécrit rien : la commande voyage en-EncodedCommandBase64.
Exécution et politique d'autorisation
windows-client policy check 'Get-Service W3SVC' # décision sans exécuter
windows-client exec --host srv01 -- Get-Service W3SVC
La liste deny est prioritaire. Les commandes composées (;, &&, |…)
sont découpées en segments évalués individuellement. La correspondance des
motifs est insensible à la casse (PowerShell l'est) ; les alias PowerShell
(gsv, rm…) ne sont pas résolus — utiliser les noms complets des cmdlets.
| code | Signification |
|---|---|
0–249 |
Exécutée ; code de sortie distant propagé. |
250 |
Erreur de configuration (hôte inconnu, identifiants absents ; upload : fichier local introuvable, répertoire parent distant absent). |
251 |
Délai d'inactivité dépassé (aucune sortie ; défaut 300 s, --timeout 0 = illimité). |
252 |
Erreur d'usage. |
253 |
Commande ou transfert inconnu — autorisation utilisateur requise (rien exécuté). |
254 |
Refusée par une règle deny (rien exécuté). |
255 |
Erreur de connexion distante (réseau, auth, certificat ou clé d'hôte) ou de transfert. |
L'ajout d'un motif à
allowoudenyest une décision explicite de l'utilisateur : présenter la commande inconnue, recueillir la décision, puis seulementpolicy allow/policy deny(ouexec --oncepour une autorisation ponctuelle).
Transfert de fichiers (upload)
upload copie un fichier local vers le serveur (destination écrasée), sous
une allow-list dédiée (upload dans policies.json), distincte de la
politique de commandes : motifs glob comparés au chemin distant (absolu,
séparateurs \ ou /, insensible à la casse), défaut fermé — un chemin non
couvert retourne 253 sans ouvrir de connexion. Pas de liste deny ni de
--once pour les transferts.
La liste est toujours comparée au chemin réellement écrit, jamais au
répertoire qui le contient : autoriser un répertoire ne vaut pas blanc-seing sur
les noms qu'on y dépose. Une destination répertoire explicite (terminée par
\ ou /) est composée avec le nom du fichier source avant toute connexion,
et c'est ce chemin qui est évalué ; une destination qui se révèle être un
répertoire côté serveur est réévaluée avant écriture.
windows-client upload --host srv01 ./app.zip 'C:\app\app.zip'
windows-client upload --host srv01 ./app.zip 'C:\app\' # évalué sur C:\app\app.zip
windows-client policy allow-upload 'C:\app\*' # après décision explicite de l'utilisateur
Pour un hôte openssh, le chemin Windows est adressé sous la racine POSIX du
sous-système SFTP (C:\app\f.txt → /C:/app/f.txt). Le répertoire parent est
vérifié avant le transfert ; s'il manque, le message le nomme (la destination,
elle, n'a pas à exister).
Le canal dépend du type d'hôte — le contrat est identique : SFTP pour un
hôte openssh ; pour un hôte winrm, le contenu transite par le shell
WS-Management et l'empreinte SHA-256 distante est vérifiée contre
l'empreinte locale. Chaque transfert (y compris refusé) est journalisé dans la
session avec les métadonnées du fichier (nom, sha256, date, taille).
Sécurité
- Deny prioritaire et défaut fermé : une commande ou un transfert non couvert n'est jamais exécuté silencieusement.
- Secrets isolés dans
credentials.json(permissions propriétaire seul sous POSIX ; ACL à restreindre sous Windows), jamais affichés ni journalisés. - Transport authentifié et chiffré : Negotiate (message-level sur HTTP) ou
HTTPS avec certificat épinglé (TOFU) pour
winrm— Basic refusé hors HTTPS ; chiffrement SSH avec clé d'hôte épinglée (TOFU) pouropenssh. - Journalisation de chaque décision et de son résultat dans la session.
Le modèle est coopératif : windows-client structure et trace les actions
d'un agent ; il se combine à l'allowlist du harnais (n'autoriser que
windows-client, jamais Invoke-Command/winrs/ssh bruts, ni l'édition
directe des fichiers de politique).
No packages depend on claria.tools.windows-client.
| Version | Downloads | Last updated |
|---|---|---|
| 1.0.0-build.20260819.1 | 10 | 08/20/2026 |