restapi-client.win-amd64 0.5.2-build.20260813.1
Build Information
| Provenance | Azure DevOps Pipeline |
| Owner | kntera (Yan Boivin) |
| Date de compilation | 2026-08-14 02:26:03 UTC |
| Version | 0.5.2.20260813.1 |
| SHA256 | 178b4aa5f76e084a8fe1f0dfcf6057fa28f90d78 |
restapi-client
Outil en ligne de commande qui invoque des API REST sous le contrôle d'une
politique d'autorisation (allow / deny / redact). Conçu pour permettre
à des agents d'appeler des services HTTP en gardant l'humain aux commandes
sur tout appel non couvert par la politique — même modèle de sécurité que
ssh-client.
Contexte
Plutôt que d'exposer curl brut à un agent, restapi-client s'intercale comme
garde-fou : chaque appel (combinaison service + méthode REST + chemin d'URL)
est évalué contre une liste allow et une liste deny avant d'être envoyé. Un
appel refusé n'ouvre même pas de connexion ; un appel inconnu signale à
l'appelant qu'une décision humaine est requise. Une liste redact
complémentaire permet d'autoriser un appel tout en caviardant sa réponse
(corps jamais affiché ni journalisé). Chaque invocation (y compris les refus)
est journalisée dans une session.
Spécifications complètes : doc/spec/** (A01 portée, E01 CLI, E02 services,
E03 politique, E04 invocation, E05 sessions).
Utilisation
restapi-client invoke --service <nom> --method <GET|POST|…> --path <chemin>
[--query clé=valeur]… [--header "Nom: valeur"]…
[--body <json> | --body-file <chemin> | --body-stdin]
[--timeout <sec>] [--json] [--once]
restapi-client policy check <service> <méthode> <chemin>
restapi-client policy allow <service> <méthodes> <motif-chemin>
restapi-client policy deny <service> <méthodes> <motif-chemin>
restapi-client policy redact <service> <méthodes> <motif-chemin> [--mask <champ>[:<regex>]]…
restapi-client policy remove <service> <méthodes> <motif-chemin>
restapi-client policy list [--json]
restapi-client service add <nom> --base-url <url> [--base-path <chemin>] [--auth none]
restapi-client service add <nom> --base-url <url> --auth basic --user <u> --password-stdin
restapi-client service add <nom> --base-url <url> --auth bearer --token-stdin
restapi-client service add <nom> --base-url <url> --auth api-key --token-stdin [--api-key-header <nom>]
restapi-client service remove <nom>
restapi-client service list [--json]
restapi-client service test <nom> [--path <chemin>]
restapi-client session start [<id>]
restapi-client session end [<id>]
restapi-client session current [--json]
restapi-client session list [--json]
restapi-client --version | --help
Option globale : --config-dir <chemin> (sinon RESTAPICLIENT_HOME, puis
./.restapi-client s'il existe, puis ~/.restapi-client). --session <id>
cible une session précise (créée si absente). --no-sessions désactive
l'inscription locale des sessions (équivaut à RESTAPICLIENT_NO_SESSIONS=1).
--no-debug-log désactive le journal de debug HTTP (équivaut à
RESTAPICLIENT_NO_DEBUG_LOG=1).
Services
Les API cibles sont déclarées par nom dans config.json : URL de base,
chemin de base optionnel, méthode d'authentification et en-têtes par défaut.
Les secrets (mot de passe, jeton, clé d'api) sont stockés à part dans
credentials.json (durci), jamais dans config.json, et se fournissent sur
l'entrée standard.
# Sans authentification
restapi-client service add httpbin --base-url https://httpbin.org
# Bearer (le jeton est lu sur stdin)
printf '%s' 'le-jeton' | restapi-client service add github --base-url https://api.github.com --auth bearer --token-stdin
# Basic
printf '%s' 'le-mot-de-passe' | restapi-client service add jira --base-url https://jira.example.com --base-path /rest/api/2 --auth basic --user bot --password-stdin
# Clé d'api dans un en-tête dédié
printf '%s' 'la-clé' | restapi-client service add interne --base-url https://api.interne.local --auth api-key --token-stdin --api-key-header X-Api-Key
restapi-client service test github --path /rate_limit # GET réel, rapporte le statut http
restapi-client service list
L'URL effective d'un appel est base-url + base-path + path. service add et
service list affichent le préfixe tel que les appels le construiront, ce
qui permet de vérifier la déclaration sur-le-champ.
⚠️ Chemins d'URL depuis Git Bash (MSYS)
Git Bash réécrit tout argument ressemblant à un chemin POSIX absolu en chemin
Windows, avant que l'outil ne le reçoive : --base-path /client/v4 arrive comme
C:/Program Files/Git/client/v4. Rien en aval ne peut distinguer cette valeur
d'une valeur voulue.
L'outil refuse donc (code 252) tout chemin qui est un chemin Windows absolu
(C:/…, C:\…) — forme qu'un chemin d'URL ne prend jamais — sur
invoke --path, service add --base-path, service test --path,
policy check et les motifs de policy allow / deny / redact. Le message
nomme la cause et les contournements :
MSYS_NO_PATHCONV=1 restapi-client service add cloudflare --base-url https://api.cloudflare.com --base-path /client/v4
restapi-client service add cloudflare --base-url https://api.cloudflare.com --base-path //client/v4
Les guillemets ne protègent pas : "/client/v4" et '/client/v4' sont
convertis comme la forme nue — le shell les retire avant que MSYS n'intervienne.
Ce que MSYS convertit :
| Valeur | Convertie |
|---|---|
/admin, /client/v4, "/client/v4" |
oui |
/admin/*, /admin?x=1 |
non — un * ou un ? inhibe la conversion |
//admin |
non — la barre oblique doublée est l'échappement MSYS |
Un motif glob (/admin/*) échappe donc à la conversion : c'est le motif
exact (/admin), celui d'une règle deny précise, qui était exposé — une
règle réécrite figure dans policy list sans ne plus rien couvrir. D'où le refus
plutôt qu'un avertissement. policy remove en est exempté, pour que les règles
déjà enregistrées sous cette forme restent supprimables.
Depuis PowerShell ou un shell POSIX, aucune conversion n'a lieu et le contrôle ne se déclenche pas.
Politique d'autorisation (allow / deny / redact)
Une règle est la combinaison de trois éléments :
- service — nom du service déclaré (
*accepté) ; - méthodes —
GET, listeGET,POST, ou*; - motif de chemin — glob simple sur le chemin d'URL (
*seul métacaractère), évalué sans la query string.
restapi-client policy check github GET /repos/kntera/x # décision sans invoquer
restapi-client policy allow github GET "/repos/*" # autoriser
restapi-client policy deny "*" DELETE "*" # interdire DELETE partout
restapi-client policy redact vault "*" "/secrets/*" # cacher tout l'appel
restapi-client policy redact github GET "/user/keys*" --mask "payload-response:\"key\":\s*\"[^\"]*\""
restapi-client policy list
- La liste
denyest prioritaire ; le défaut est fermé : un appel non couvert n'est jamais envoyé silencieusement (code 253, décision humaine requise). - Un motif de chemin doit pouvoir correspondre au chemin comparé, qui commence
toujours par
/: un motif ne commençant ni par/ni par*est refusé (code 252) plutôt qu'enregistré sans jamais rien couvrir. Depuis Git Bash, voir aussi l'avertissement sur la conversion des chemins ci-dessus. - La liste
redactest indépendante : elle ne rend pas un appel autorisé — elle caviarde ce que l'appel expose, à la fois dans la sortie et dans le journal de session :- sans
--mask: tout l'appel est caché (URL, en-têtes, corps requête et réponse →[REDACTED]; seuls service, méthode, chemin, statut et durée restent visibles) ; - avec
--mask <champ>[:<regex>](répétable) : seuls les champs désignés sont masqués — champ entier sans regex, ou uniquement les parties correspondant à la regex. Champs :url,payload-query(corps de la requête),payload-response(corps de la réponse),header-<clé>(ex.header-authorization, côté requête et réponse). - toutes les règles
redactcouvrant l'appel s'appliquent : leurs masques se cumulent et une seule règle sans--maskcache tout l'appel.
- sans
- Masquage automatique en plus de la politique : l'en-tête
d'authentification et toute occurrence littérale ou percent-encodée d'un
secret du service (jeton, mot de passe, blob base64 du
basic— même renvoyés par le serveur) sont toujours remplacés par[REDACTED]dans la sortie et le journal. L'en-tête d'authentification conserve le schéma (Basic/Bearer) et, pourbearer/api-key, un aperçu de la clé — préfixe de type jusqu'au dernier séparateur (-/_/+) des 8 premiers caractères et/ou 5 premiers caractères du secret selon la longueur (ex.Bearer sk-ant-api03[REDACTED],pk_live_[REDACTED]) ; enbasic, seul le schéma est visible.
| code | Signification |
|---|---|
0 |
Réponse HTTP 2xx. |
3 / 4 / 5 |
Classe du statut HTTP final (3xx / 4xx / 5xx) ; statut exact via --json (statusCode) et le diagnostic stderr. Un 3xx final = redirection non suivie. |
250 |
Erreur de configuration (service inconnu, identifiants absents, fichier de politique invalide). |
251 |
Délai dépassé (défaut 30 s, --timeout 0 = illimité). |
252 |
Erreur d'usage. |
253 |
Appel inconnu — autorisation utilisateur requise (rien envoyé). |
254 |
Refusé par une règle deny (rien envoyé). |
255 |
Erreur de connexion HTTP (réseau, DNS, TLS). |
L'ajout d'une règle
allow,denyouredactest une décision explicite de l'utilisateur : présenter l'appel inconnu, recueillir la décision, puis seulementpolicy allow/policy deny(ouinvoke --oncepour une autorisation ponctuelle).
Face à un code 253, les quatre décisions possibles de l'utilisateur :
| Décision | Action de l'agent |
|---|---|
| Autoriser toujours | policy allow <service> <méthode> "<motif>" puis relancer invoke. |
| Autoriser une seule fois | Relancer invoke avec --once ; aucune persistance. |
| Refuser toujours | policy deny <service> <méthode> "<motif>" ; ne pas invoquer. |
| Refuser cette fois-ci | Ne rien persister, ne pas invoquer. |
Ne jamais généraliser un motif au-delà de ce que l'utilisateur a approuvé ; ne
jamais proposer de motif large pour une méthode mutative (POST, PUT,
PATCH, DELETE).
Invocation
restapi-client invoke --service github --method GET --path "/repos/kntera/x/issues" --query "state=open"
restapi-client invoke --service jira --method POST --path "/issue" --body '{"fields":{...}}'
cat payload.json | restapi-client invoke --service jira --method POST --path "/issue" --body-stdin
- Le corps est envoyé en
application/jsonpar défaut ; un--header "Content-Type: …"le remplace. Les en-têtes d'appel priment sur les en-têtes par défaut du service. - Redirections : suivies (5 max par défaut), mais chaque saut est
réévalué contre la politique et journalisé individuellement. Un saut
deny→ 254 ; un saut non couvert → 253 (décision humaine) ; une cible hors des services déclarés n'est pas suivie (la réponse 3xx est retournée). - En mode texte, le corps de la réponse finale est écrit sur stdout ; le
statut, l'URL et la durée sont des diagnostics stderr (préfixés
restapi-client:). --jsonproduit un unique objet structuré sur stdout : service, méthode, chemin, URL, décision, règle,statusCode,contentType,responseHeaders,body,redacted,redirectCount,durationMs,timedOut.
Sessions
Une session regroupe les invoke d'une période de travail et journalise
intégralement chaque requête HTTP (y compris refusée, chaque saut de
redirection et le GET de service test) dans
sessions/<AAAAMMJJhhmmss>-<id>.jsonl (à côté de l'exécutable) : URL, en-têtes requête et réponse, corps requête et
réponse (plafonnés à 64 KiB chacun), décision, statut, durée. Les valeurs
journalisées sont la vue caviardée : une donnée masquée (règle redact ou
secret) n'est jamais persistée.
En complément, chaque requête réellement envoyée est tracée dans un
journal de debug HTTP quotidien, restapi-debug-AAAA-MM-JJ.log (à côté de
l'exécutable) : même vue caviardée, mais corps intégraux (non plafonnés).
Ce journal n'est pas affecté par --no-sessions ; il se désactive par
--no-debug-log ou RESTAPICLIENT_NO_DEBUG_LOG=1. Le fichier est durci à sa
création (600 sous POSIX ; avertissement ACL sous Windows).
restapi-client session start maintenance-1
restapi-client session current
restapi-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 invoke
en crée une automatiquement.
Sécurité
- Deny prioritaire et défaut fermé : un appel non couvert n'est jamais envoyé silencieusement — y compris les cibles de redirection, réévaluées saut par saut.
- Secrets isolés dans
credentials.json(permissions propriétaire seul sous POSIX), jamais affichés ni journalisés en clair — l'en-tête d'authentification et toute occurrence littérale ou percent-encodée d'un secret sont automatiquement remplacés par[REDACTED](l'en-tête garde le schéma et, pourbearer/api-key, un court aperçu de la clé pour l'identifier). - Caviardage : les données sensibles (liste
redact, masques par champ et regex) ne transitent ni par la sortie de l'agent ni par les journaux. - Journalisation intégrale de chaque requête (décision, URL, en-têtes et corps requête/réponse) dans la session.
Le modèle est coopératif : restapi-client structure et trace les appels d'un
agent ; il se combine à l'allowlist du harnais (n'autoriser que
restapi-client, jamais curl brut, ni l'édition directe des fichiers de
politique et d'identifiants).
No packages depend on restapi-client.win-amd64.
| Version | Downloads | Last updated |
|---|---|---|
| 0.5.2-build.20260813.1 | 5 | 08/14/2026 |