Aller au contenu principal

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 :

  1. l'audience du projet Pesia : urn:zitadel:iam:org:project:id:<projectId>:aud ;
  2. le scope d'organisation : urn:zitadel:iam:user:resourceowner ;
  3. 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-urlencode pour le paramètre scope. Ce paramètre contient des espaces. --data-urlencode les encode correctement.

Les deux scopes techniques obligatoires​

Ces deux scopes s'ajoutent à vos scopes métier. Ils ne les remplacent pas.

ScopeRôleSi 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:resourceownerAjoute 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 :

HeaderValeurObligatoire
AuthorizationBearer <access_token>Oui
X-Pesia-Envproduction | sandboxNon (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 production accepte une requête sans header (équivalent production).
  • Un grant sandbox exige X-Pesia-Env: sandbox explicite.
  • Il n'existe que deux environnements : production et sandbox. Toute autre valeur renvoie 403.

Codes d'erreur​

CodeErreurCause
401unauthorizedToken absent, signature invalide, expiré, clé révoquée, ou scope urn:zitadel:iam:user:resourceowner absent de la demande de token
403env_mismatchX-Pesia-Env ne correspond pas au grant
403insufficient_scopeLe 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 :

  1. Lisez le contenu de votre token (voir Vérifier le contenu de votre token).
  2. Cherchez le champ urn:zitadel:iam:user:resourceowner:id.
  3. Si le champ est absent, ajoutez le scope, puis demandez un nouveau token.
  4. Si le champ est présent et l'erreur persiste, contactez votre interlocuteur Pesia (partenaires@pesia.fr). Communiquez la valeur du champ jti de 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_in de 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 :

  1. Demandez une rotation de votre clé à votre interlocuteur Pesia.
  2. Récupérez le nouveau clientSecret via le canal sécurisé convenu.
  3. Déployez la configuration mise à jour.
  4. 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​