Jetons et durées de vie
Code, id_token, access_token, jeton client_credentials et clé de signature webhook : à quoi sert chacun, combien de temps il vit, comment le protéger.
Plusieurs « jetons » interviennent dans une intégration. Ils ne se ressemblent pas et ne servent pas aux mêmes choses : les confondre est la première source d’erreurs.
Vue d’ensemble
| Code d’autorisation | id_token |
access_token (flux utilisateur) |
Jeton client_credentials |
Clé de signature webhook | |
|---|---|---|---|---|---|
| Qui s’authentifie auprès de qui | A3BC vers votre site (via l’utilisateur) | A3BC prouve l’identité à votre serveur | Votre serveur vers A3BC, au nom de l’utilisateur | Votre serveur vers A3BC, sans utilisateur | A3BC vers votre serveur |
| Où l’obtenir | Paramètre code du retour |
Réponse du endpoint token | Réponse du endpoint token | Endpoint token, grant_type=client_credentials |
Remise par A3BC lors de la configuration du webhook |
| Forme | Chaîne opaque | JWT signé (3 parties) | Chaîne opaque | Chaîne opaque | Clé de 32 octets en base64 (44 caractères) |
| À quoi il sert | Être échangé contre les jetons | Lire les claims, après vérification | Appeler userinfo et l’API document |
Appeler l’API de partage différé | Vérifier que le webhook vient bien d’A3BC |
| Durée de vie | Très courte, usage unique | Donnée par exp (10 minutes dans l’exemple du guide) |
Donnée par expires_in ; l’accès aux informations est garanti 30 minutes |
Environ 10 minutes (expires_in: 599 dans le guide) |
Jusqu’à rotation (clé versionnée : v1, v2…) |
| Où le conserver | Nulle part : l’échanger immédiatement | Ne conserver que les claims utiles, pas le jeton | En mémoire, le temps des appels | En mémoire ; en redemander un à chaque fois | Gestionnaire de secrets, côté serveur |
Le code d’autorisation
Il arrive dans l’URL de retour (?code=…&state=…). Il n’a de valeur que quelques instants : votre serveur l’échange tout de suite au endpoint token, avec ses identifiants. Il est à usage unique : un second essai est refusé. Il transite par le navigateur, c’est pourquoi il ne donne rien sans votre client_secret.
L’id_token : la preuve d’identité
C’est un JWT : trois blocs encodés en base64url séparés par des points (en-tête, contenu, signature). Le contenu contient :
- les claims que l’utilisateur a partagés (
given_name,birthdate…) ; - des informations sur le jeton lui-même :
iss(qui l’a émis),aud(pour qui : votreclient_id),sub(l’utilisateur),iat/exp(émis le / expire le),nonce(le vôtre), et des claims techniques (at_hash,auth_time,jti,sid,rat).
Ne lisez jamais le contenu sans avoir vérifié la signature : n’importe qui peut fabriquer un JWT qui a l’air valide. La vérification se fait avec les clés publiques du jwks_uri ; voir Vérifier les jetons. Une fois vérifié, extrayez et stockez les claims dont vous avez besoin : le jeton lui-même expire vite.
L’access_token : la clé pour appeler les API de l’utilisateur
Il représente le consentement donné par cet utilisateur pour cette transaction. Vous le présentez dans l’en-tête Authorization: Bearer <access_token> à :
- l’endpoint
userinfo(qui renvoie les mêmes claims que l’id_token) ; - l’URL d’un claim de document (
private:doc.*).
Dans les exemples du guide, ce n’est pas un JWT : traitez-le comme une chaîne opaque, ne cherchez pas à le décoder. Sa durée de validité est indiquée par expires_in dans la réponse du endpoint token. Dans tous les cas, les informations ne sont récupérables que 30 minutes après le consentement : appelez les API tout de suite.
Règles de sécurité : jamais dans une URL (elle serait journalisée), jamais dans le navigateur ou une application mobile, jamais dans les logs, jamais envoyé ailleurs que vers les endpoints A3BC.
refresh_token a été activé pour votre RP (c’est optionnel et réservé au partage différé), vous recevez aussi un refresh_token. Ne l’utilisez que si A3BC vous l’a indiqué.Le jeton client_credentials : l’accès sans utilisateur
Pour le partage différé, l’utilisateur n’est plus là au moment où vous interrogez l’API (c’est justement le but). Votre serveur s’authentifie donc lui-même, avec ses identifiants :
curl -s -u "$CLIENT_ID:$CLIENT_SECRET" \
-d grant_type=client_credentials -d scope=private:delayed_sharing \
https://oidc-sandbox.a3bc.io/oauth2/token
Il ne vaut que pour le scope private:delayed_sharing et vit environ 10 minutes : redemandez-en un à chaque appel, ou mettez-le en cache jusqu’à expires_in moins une marge.
La clé de signature webhook : l’authentification dans l’autre sens
Pour toutes les autres clés, c’est vous qui prouvez votre identité à A3BC. Ici, c’est A3BC qui prouve son identité à votre serveur : chaque notification porte une signature calculée avec une clé que vous êtes seul(e) à partager avec A3BC. Ce n’est pas un jeton d’accès, on ne l’envoie jamais nulle part. Voir Webhooks.
Les identifiants du RP
| Identifiant | Rôle | Confidentiel ? |
|---|---|---|
client_id |
Identifie votre service (également dans aud de l’id_token). |
Non |
client_secret |
Vous authentifie auprès du endpoint token (client_secret_basic). |
Oui |
client_secret_basic signifie que vous envoyez Authorization: Basic base64(client_id:client_secret). Les bibliothèques HTTP le font avec un paramètre auth=(client_id, client_secret) (Python requests) ou -u client_id:client_secret (curl).