Authentification#
L’API utilise OAuth2 client_credentials — le flux de machine à machine. Pas d’utilisateur, pas de redirection navigateur, pas d’écran de consentement.
Deux hôtes sont impliqués, et ton client parle aux deux :
Rôle |
Hôte |
Objet |
|---|---|---|
Fournisseur d’identité |
|
émet les jetons |
Shard |
depuis le claim |
sert les données |
Présenter tes identifiants#
Les deux méthodes standard d’authentification client OAuth2 (RFC 6749 §2.3.1) sont acceptées. Utilise celle que ta bibliothèque HTTP ou OAuth rend la plus simple — elles sont équivalentes ici.
client_secret_post — identifiants dans le corps du formulaire :
POST /identity/o/api/token HTTP/1.1
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials
client_id=cust-acme-integration
client_secret=<secret>
scope=shifts.read
client_secret_basic — identifiants dans un en-tête HTTP Basic, seul client_id dans le corps :
POST /identity/o/api/token HTTP/1.1
Authorization: Basic base64("cust-acme-integration:<secret>")
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials
client_id=cust-acme-integration
scope=shifts.read
client_secret_basic est la valeur par défaut de la spécification et ce que produisent la plupart des bibliothèques OAuth du marché ; client_secret_post est plus simple à construire à la main, sans étape base64.
Expiration et renouvellement#
Les jetons durent 1800 secondes par défaut. Le flux client_credentials n’a pas de jeton de rafraîchissement — c’est voulu (RFC 6749 §4.4.3), et cela ne te coûte rien : ton client détient déjà le client_id et le client_secret, donc « rafraîchir » revient simplement à demander un nouveau jeton avec le même appel. Un jeton de rafraîchissement ne serait qu’un secret de plus à stocker.
Deux règles rendent un client robuste :
Mets le jeton en cache et réutilise-le jusqu’à approcher d’
expires_in. Le renouveler ~30 secondes à l’avance évite les courses au moment de l’expiration.En cas de
401renvoyé par l’API de données — un jeton peut être invalidé plus tôt, par exemple lors d’une rotation de clé — supprime le jeton mis en cache, demandes-en un nouveau et réessaie la requête une fois.
Routage : le claim api_base#
Le jeton est un JWT. Au-delà des champs OAuth standard, il porte :
Claim |
Exemple |
Signification |
|---|---|---|
|
|
URL de base de l’hôte à appeler |
|
|
API du shard cible |
|
|
L’entreprise à laquelle tu es rattaché |
|
|
Nom affiché |
|
|
Les entreprises non actives se voient refuser un jeton |
Lis api_base et appelle cet hôte. Garde un repli configuré au cas où le claim serait absent, mais privilégie le claim : c’est lui qui nous permet d’ajouter ou de déplacer un shard sans aucun changement de ton côté.
aud et le rattachement à l’entreprise sont définis côté serveur à partir du tenant auquel appartiennent tes identifiants. Ils ne sont pas demandables — un client ne peut physiquement pas viser une autre entreprise ni un autre shard.
Ce qu’un jeton machine n’est pas#
Les jetons machine n’ont aucun sub ni claim d’utilisateur ou d’affiliation. Chaque appel agit en tant qu’intégration elle-même, limitée par ses scopes. Deux conséquences :
L’API ne peut pas deviner qui est responsable d’une écriture : certaines écritures t’obligent donc à nommer explicitement une personne — voir Nommer la personne derrière une écriture.
Un jeton utilisateur de première partie (issu de l’app web ou mobile) est rejeté sur cette surface. Elle est réservée aux machines.
Erreurs à ce stade#
Symptôme |
Cause |
|---|---|
|
|
|
tu as demandé un scope qui n’a pas été accordé à ton client |
|
jeton expiré, invalide ou invalidé par anticipation — renouvelle-le et réessaie une fois |
|
jeton valide, autorisation manquante — voir Scopes |