Authentification — API publique Pesia
L'API publique Pesia utilise OAuth2 Client Credentials (RFC 6749 §4.4) avec des jetons JWT signés par le serveur d'autorisation Pesia.
Chaque partenaire dispose d'un Service Account (compte machine) avec un
clientId et un clientSecret dédiés. Ces identifiants permettent d'obtenir
un access token JWT (durée de vie 12 h) à présenter sur chaque requête API.
Fiez-vous à la valeur expires_in de la réponse plutôt qu'à une durée fixe.
Flux d'authentification
┌─────────────┐ 1. POST /oauth/v2/token ┌──────────┐
│ │ grant_type=client_credentials │ │
│ Partenaire │ ───────────────────────────────────► │ Pesia │
│ │ │ │
│ │ ◄─── 2. access_token (JWT, 12h) ──── │ │
└─────────────┘ └──────────┘
│
│ 3. GET /partner/v1/smic
│ Authorization: Bearer <jwt>
│ X-Pesia-Env: production
▼
┌──────────────────────┐
│ api.pesia.fr │ → 4. Vérifie la signature du token
│ /partner/v1/* │ → 5. Vérifie le scope requis
└──────────────────────┘
Obtenir un access token
Le paramètre scope contient trois éléments :
- l'audience du projet Pesia :
urn:zitadel:iam:org:project:id:<projectId>:aud; - le scope d'organisation :
urn:zitadel:iam:user:resourceowner; - un ou plusieurs scopes métier (voir Catalogue de scopes).
Séparez les éléments par une espace.
curl -X POST https://auth.pesia.fr/oauth/v2/token \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'grant_type=client_credentials' \
--data-urlencode 'client_id=<clientId>' \
--data-urlencode 'client_secret=<clientSecret>' \
--data-urlencode 'scope=urn:zitadel:iam:org:project:id:<projectId>:aud urn:zitadel:iam:user:resourceowner salary:read'
Réponse :
{
"access_token": "eyJhbGc...",
"token_type": "Bearer",
"expires_in": 43200
}
Note : Remplacez
<clientId>,<clientSecret>et<projectId>par vos vraies valeurs fournies par l'équipe Pesia lors de l'onboarding.
Note : Utilisez
--data-urlencodepour le paramètrescope. Ce paramètre contient des espaces.--data-urlencodeles encode correctement.
Les deux scopes techniques obligatoires
Ces deux scopes s'ajoutent à vos scopes métier. Ils ne les remplacent pas.
| Scope | Rôle | Si absent |
|---|---|---|
urn:zitadel:iam:org:project:id:<projectId>:aud | Émet le token pour l'API Pesia. | L'API refuse le token. |
urn:zitadel:iam:user:resourceowner | Ajoute au token l'identité de votre organisation. | L'API répond 401. |
Pourquoi le scope d'organisation ? Votre clé appartient à une organisation précise. À chaque requête, l'API compare l'organisation portée par le token et l'organisation de votre clé. Les deux doivent être identiques. Ce contrôle empêche l'usage d'un token dans le périmètre d'une autre organisation.
Le serveur d'autorisation ajoute cette identité au token seulement si vous demandez le scope. Un token sans cette identité reste cryptographiquement valide, mais l'API le refuse.
Vérifier le contenu de votre token
L'access token est un JWT. Vous pouvez lire ses données sans le valider :
payload=$(printf '%s' "$ACCESS_TOKEN" | cut -d. -f2)
while [ $(( ${#payload} % 4 )) -ne 0 ]; do payload="${payload}="; done
printf '%s' "$payload" | tr '_-' '/+' | base64 -d
Un token correct contient un champ urn:zitadel:iam:user:resourceowner:id :
{
"aud": ["<projectId>"],
"client_id": "<clientId>",
"iss": "https://auth.pesia.fr",
"jti": "V2_...",
"urn:zitadel:iam:user:resourceowner:id": "<identifiant de votre organisation>",
"urn:zitadel:iam:user:resourceowner:name": "<nom de votre organisation>"
}
Si ce champ est absent, le scope urn:zitadel:iam:user:resourceowner manque
dans votre demande de token.
Présenter le token
Toutes les requêtes API doivent inclure :
| Header | Valeur | Obligatoire |
|---|---|---|
Authorization | Bearer <access_token> | Oui |
X-Pesia-Env | production | sandbox | Non (défaut production) |
Comportement de X-Pesia-Env
Si le header X-Pesia-Env est absent, l'API utilise production par défaut.
X-Pesia-Env doit correspondre exactement à l'environnement du grant émis
pour votre Service Account. Une discordance renvoie HTTP 403 :
{ "error": "env_mismatch", "expected": "production", "received": "sandbox" }
Conséquences pratiques :
- Un grant
productionaccepte une requête sans header (équivalentproduction). - Un grant
sandboxexigeX-Pesia-Env: sandboxexplicite. - Il n'existe que deux environnements :
productionetsandbox. Toute autre valeur renvoie 403.
Codes d'erreur
| Code | Erreur | Cause |
|---|---|---|
| 401 | unauthorized | Token absent, signature invalide, expiré, clé révoquée, ou scope urn:zitadel:iam:user:resourceowner absent de la demande de token |
| 403 | env_mismatch | X-Pesia-Env ne correspond pas au grant |
| 403 | insufficient_scope | Le grant n'a pas le scope requis (voir Scopes) |
401 alors que le token a bien été délivré
Symptôme : le serveur d'autorisation renvoie un access_token, mais chaque
appel API répond :
{
"type": "https://docs.pesia.fr/partner/errors/unauthorized",
"title": "Unauthorized",
"status": 401,
"detail": "Invalid partner credentials",
"code": "unauthorized"
}
Cause la plus fréquente : le scope urn:zitadel:iam:user:resourceowner manque
dans la demande de token. Le token ne porte alors pas l'identité de votre
organisation, et l'API le refuse.
Marche à suivre :
- Lisez le contenu de votre token (voir Vérifier le contenu de votre token).
- Cherchez le champ
urn:zitadel:iam:user:resourceowner:id. - Si le champ est absent, ajoutez le scope, puis demandez un nouveau token.
- Si le champ est présent et l'erreur persiste, contactez votre interlocuteur
Pesia (partenaires@pesia.fr). Communiquez la valeur du champ
jtide votre token. Ce champ identifie la requête dans nos journaux.
Fenêtre de révocation
La révocation prend effet immédiatement. L'API vérifie l'état de votre clé à chaque requête.
Lorsqu'une clé est révoquée (à votre demande auprès de Pesia, ou en cas d'incident de sécurité) :
- Tout appel est refusé dès la révocation, y compris avec un access token déjà émis et non expiré.
- Ce token reste cryptographiquement valide jusqu'à son expiration naturelle (12 h), mais l'API ne l'accepte plus.
- Si vous mettez en cache vos tokens, fiez-vous à la valeur
expires_inde la réponse plutôt qu'à une durée fixe.
En cas de fuite d'un access token sans révocation de la clé, ce token reste
utilisable jusqu'à 12 h. Écrivez à partenaires@pesia.fr pour faire révoquer la
clé : l'effet est immédiat.
Rotation de clé partenaire
Les clés partenaires ont un TTL maximum défini à l'émission. Procédure côté partenaire :
- Demandez une rotation de votre clé à votre interlocuteur Pesia.
- Récupérez le nouveau
clientSecretvia le canal sécurisé convenu. - Déployez la configuration mise à jour.
- Demandez un nouveau token OAuth2 avec le nouveau secret.
L'ancien clientSecret est révoqué immédiatement lors de la rotation. Les tokens
déjà émis avec l'ancien secret cessent aussitôt d'être acceptés.
Voir aussi
- Catalogue de scopes
- Sandbox
- Statut et incidents : https://status.pesia.fr