> ## Documentation Index
> Fetch the complete documentation index at: https://translations.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# On-Behalf-Of Token Exchange

> Découvrez comment utiliser l’échange de jetons On-Behalf-Of (OBO) pour permettre aux services intermédiaires de préserver l’identité et les permissions de l’utilisateur lorsqu’ils appellent des API en aval.

L’échange de jetons On-Behalf-Of (OBO) ([RFC 8693](https://www.rfc-editor.org/rfc/rfc8693.html)) permet aux services intermédiaires de préserver l’identité et les permissions de l’utilisateur lorsqu’ils appellent des API en aval.

Lorsqu’une application doit appeler une API en aval, elle peut utiliser :

* [Client Credentials Flow](/docs/fr-ca/get-started/authentication-and-authorization-flow/client-credentials-flow) : l’application agit pour son propre compte et s’authentifie elle-même. La requête peut avoir été initiée par un utilisateur, mais ce contexte sera perdu. Le service en aval ne connaît alors que l’identité de l’application appelante.
* On-Behalf-Of (OBO) Token Exchange : l’application reçoit un jeton limité aux portées de l’utilisateur et peut l’échanger contre un nouveau jeton pour appeler des services en aval. Cela préserve l’identité et le contexte de l’utilisateur final d’origine tout au long de la chaîne d’appel.

Par exemple, si un utilisateur déclenche un appel vers le Service A, qui appelle ensuite le Service B, l’échange de jetons OBO permet au Service A d’échanger le jeton d’accès de l’utilisateur contre un nouveau jeton qui :

* conserve l’identité et les permissions de l’utilisateur d’origine
* est limité spécifiquement au Service B
* permet au Service B de prendre des décisions d’autorisation en fonction de l’utilisateur final

Les échanges de jetons OBO déclenchent le trigger d’Action [`post-login`](/docs/fr-ca/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger), où :

* [`event.transaction.protocol`](/docs/fr-ca/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger/post-login-event-object#param-protocol) est défini sur `oauth2-token-exchange`.
* [`event.transaction.actor`](/docs/fr-ca/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger/post-login-event-object#param-actor) suit l’ensemble de la chaîne de délégation.

Comme dans un flux de connexion standard, les portées renvoyées pour les appels d’API en aval sont basées sur les politiques de [contrôle d’accès basé sur les rôles (RBAC)](/docs/fr-ca/manage-users/access-control/rbac) de l’utilisateur.

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  Lorsque vous achetez le module complémentaire Auth0 for AI Agents, vous pouvez utiliser la limite de débit maximale de l’Authentication API de votre niveau d’abonnement pour les échanges de jetons OBO. Par exemple, si vous utilisez [Private Cloud 100 RPS](/docs/fr-ca/troubleshoot/customer-support/operational-policies/rate-limit-policy/rate-limit-configurations/tier-100-rps-private-cloud), vous pouvez dépasser la limite de débit de 30 RPS des échanges de jetons OBO et tirer pleinement parti de la capacité de 100 RPS pour vos requêtes d’échange de jetons OBO. La limite de l’Authentication API est partagée et agit comme plafond global pour toutes les requêtes de l’Authentication API, y compris les connexions, les actualisations de jetons et les échanges de jetons combinés. Communiquez avec votre gestionnaire de compte technique pour en savoir plus.
</Callout>

<div id="use-cases">
  ## Cas d’utilisation
</div>

Parmi les cas d’utilisation courants de l’échange de jeton OBO, on retrouve :

* Les serveurs MCP qui doivent appeler des API de première partie au nom de l’utilisateur
* Les microservices qui doivent appeler des services en aval au nom de l’utilisateur

Pour permettre à vos applications d’appeler des API tierces au nom de l’utilisateur, utilisez [Token Vault](/docs/fr-ca/secure/call-apis-on-users-behalf/token-vault).

<div id="how-it-works">
  ## Fonctionnement
</div>

L’échange de jeton OBO permet aux services intermédiaires d’échanger un jeton utilisateur reçu contre un nouveau jeton limité à un service en aval. Ce nouveau jeton conserve l’identité de l’utilisateur d’origine tout en assurant le suivi de la chaîne des services impliqués dans la charge utile du JSON Web Token (JWT).

<div id="example-mcp-server-calls-first-party-api">
  ### Exemple : appels du serveur MCP à une API de première partie
</div>

Un utilisateur s’authentifie auprès d’Auth0 dans une application cliente, qui appelle ensuite un serveur MCP; celui-ci doit ensuite appeler une API de première partie.

<div id="step-1-user-authentication">
  #### Étape 1 : Authentification de l’utilisateur
</div>

Lorsque l’utilisateur se connecte, Auth0 émet un jeton d’accès limité au serveur MCP, avec les claims suivantes dans la charge utile du JWT :

```json theme={null}
{
  "sub": "auth0|user123",
  "aud": "https://mcp-server.example.com",
  "azp": "spa_client_id" // ou "client_id" selon le dialecte de jeton
}
```

| Claim                                                                                                                    | Valeur                           | Description                                  |
| ------------------------------------------------------------------------------------------------------------------------ | -------------------------------- | -------------------------------------------- |
| `sub`                                                                                                                    | `auth0\|user123`                 | L’identité de l’utilisateur final            |
| `aud`                                                                                                                    | `https://mcp-server.example.com` | Jeton destiné au serveur MCP                 |
| `azp` (ou `client_id` selon le [Profil de jeton d’accès](/docs/fr-ca/secure/tokens/access-tokens/access-token-profiles)) | `spa_client_id`                  | L’application cliente qui a demandé le jeton |

<div id="step-2-obo-exchange">
  #### Étape 2 : échange OBO
</div>

À l’aide de l’échange de jeton OBO, le serveur MCP présente le jeton de l’utilisateur à Auth0 et demande un jeton d’accès dont la portée est limitée à l’API de première partie. Auth0 émet un nouveau jeton d’accès pour l’API, avec les claims suivants :

```json theme={null}
{
  "sub": "auth0|user123",
  "aud": "https://first-party-api.example.com",
  "azp": "mcp_server_client_id", // ou "client_id" selon le dialecte de jeton
  "act": {
    "sub": "mcp_server_client_id",
    "act": {
      "sub": "spa_client_id"
    }
  }
}
```

| Claim                                                                                                                    | Valeur                                                                    | Description                                                             |
| ------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------- | ----------------------------------------------------------------------- |
| `sub`                                                                                                                    | `auth0\|user123`                                                          | Même identité utilisateur conservée                                     |
| `aud`                                                                                                                    | `https://first-party-api.example.com`                                     | Jeton limité à l’API de première partie                                 |
| `azp` (ou `client_id` selon le [profil du jeton d’accès](/docs/fr-ca/secure/tokens/access-tokens/access-token-profiles)) | `mcp_server_client_id`                                                    | Client ayant demandé le jeton (le serveur MCP qui a effectué l’échange) |
| `act`                                                                                                                    | `{"sub": "mcp_server_client_id",`<br />`"act": {"sub": "spa_client_id"}}` | Chaîne de délégation montrant tous les acteurs concernés                |

<div id="the-act-claim">
  #### La claim `act`
</div>

La claim `act` (acteur) retrace l’ensemble de la chaîne de délégation. Chaque niveau `act` représente un service dans la chaîne d’appels, et le `act.sub` le plus externe identifie l’acteur actuel qui a effectué l’échange de jeton.

Dans notre exemple :

* `act.sub` le plus externe : `mcp_server_client_id` (le serveur MCP qui vient tout juste d’échanger le jeton)
* `act.sub` imbriqué : `spa_client_id` (l’application cliente d’origine)

La claim `azp` doit correspondre à la valeur du `act.sub` le plus externe, afin d’identifier le service qui a effectué l’échange de jeton le plus récent.

Si l’API de première partie appelle un autre service en aval (`https://calendar-api.acme.com`), la chaîne de délégation s’étendrait :

```json theme={null}
{
  "sub": "auth0|user123",
  "aud": "https://calendar-api.acme.com",
  "azp": "first_party_api_client_id",
  "act": {
    "sub": "first_party_api_client_id",
    "act": {
      "sub": "mcp_server_client_id",
      "act": {
        "sub": "spa_client_id"
      }
    }
  }
}
```

La chaîne de délégation ne peut pas comporter plus de cinq niveaux imbriqués. Comme l’échange ajoute le client actuel comme niveau supplémentaire, l’échange de jeton OBO échouera si le jeton du sujet comporte déjà quatre niveaux `act` imbriqués.

```json theme={null}
400 Bad Request
{
  "error": "invalid_request",
  "error_description": "Delegation chain (`act` claim) depth exceeds the maximum allowed limit of 4"
}
```

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  Mettez en cache les jetons d’accès pendant toute la durée de validité du jeton au lieu de demander un nouveau jeton pour chaque appel d’API. Les jetons d’accès peuvent être réutilisés tant qu’ils n’ont pas expiré; des échanges de jetons à répétition gaspillent des ressources, augmentent la latence et peuvent vous faire atteindre les limites de requêtes.
</Callout>

<div id="user-mcp-server-api-flow">
  ### Utilisateur > serveur MCP > flux API
</div>

Le diagramme suivant illustre un flux de bout en bout d’échange de jeton OBO dans lequel un serveur MCP appelle une API de première partie pour le compte de l’utilisateur :

```mermaid theme={null}
sequenceDiagram
    participant User
    participant Client App
    participant Auth0
    participant MCP Server
    participant First-Party API

    Note over User,Auth0: Step 1: User Authentication
    User->>Client App: Authenticates (Login)
    Client App->>Auth0: Requests User Token
    Auth0-->>Client App: Issues Token A<br/>(aud: MCP Server, sub: UserX)

    Note over Client App,MCP Server: Step 2: Initial Request
    Client App->>MCP Server: Call Endpoint (Token A)
    Note right of Client App: Authorization: Bearer [Token A]

    Note over MCP Server,Auth0: Step 3: Validation and Token Exchange
    activate MCP Server
    MCP Server->>MCP Server: Validates Token A
    MCP Server->>Auth0: POST /oauth/token (Token Exchange)
    Note right of MCP Server: client_id: MCP_Server_Client_ID<br/>subject_token: [Token A]<br/>audience: First-Party API
    
    Note over Auth0: Step 4: Token Issuance
    activate Auth0
    Auth0-->>MCP Server: Issues Token B<br/>(aud: First-Party API, sub: UserX)
    deactivate Auth0
    Note right of Auth0: Token B contains act claim<br/>showing MCP Server as the actor

    Note over MCP Server,First-Party API: Step 5: Downstream Call
    MCP Server->>First-Party API: Call Endpoint (Token B)
    Note right of MCP Server: Authorization: Bearer [Token B]
    
    activate First-Party API
    First-Party API->>First-Party API: Validates Token B<br/>Identifies subject as UserX
    
    First-Party API-->>MCP Server: 200 OK (Data)
    deactivate First-Party API

    MCP Server-->>Client App: 200 OK (Processed Data)
    deactivate MCP Server
```

1. **Authentification de l’utilisateur** : L’utilisateur s’authentifie auprès de l’application cliente. L’Auth0 Authorization Server émet le jeton A, limité au MCP Server.
2. **Requête initiale** : L’application cliente appelle le MCP Server en transmettant le jeton A dans l’en-tête `Authorization: Bearer`.
3. **Validation et échange de jetons** : Le MCP Server reçoit le jeton A, le valide et le transmet au point de terminaison `/oauth/token` de l’Auth0 Authorization Server. Au moyen de l’échange de jeton OBO, le MCP Server présente le jeton A comme `subject_token` et demande un nouveau jeton pour l’API de première partie.
4. **Émission du jeton** : L’Auth0 Authorization Server émet le jeton B. Le jeton B a le même `sub` (ID utilisateur) que le jeton A, mais le `aud` (audience) correspond maintenant à l’API de première partie.
5. **Requête en aval** : Le MCP Server appelle l’API de première partie au moyen du jeton B. L’API valide le jeton B et constate que la requête est bien effectuée « au nom de » l’utilisateur d’origine.

<div id="user-api1-api2-api3">
  ### Utilisateur > API1 > API2 > API3
</div>

Le schéma suivant illustre le fonctionnement de bout en bout d’une chaîne de microservices qui effectuent des appels aux services en aval au nom de l’utilisateur :

```mermaid theme={null}
sequenceDiagram
    participant User
    participant Client App
    participant Auth0
    participant API1
    participant API2
    participant API3

    Note over User,Auth0: Étape 1 : Authentification de l'utilisateur
    User->>Client App: S'authentifie (connexion)
    Client App->>Auth0: Demande un jeton utilisateur
    Auth0-->>Client App: Émet le jeton A<br/>(aud: API1, sub: UserX)

    Note over Client App,API1: Étape 2 : Requête initiale
    Client App->>API1: Requête vers l'endpoint (jeton A)
    Note right of Client App: Authorization: Bearer [Token A]

    Note over API1,Auth0: Étape 3 : API1 délègue à API2
    activate API1
    API1->>API1: Valide le jeton A
    API1->>Auth0: POST /oauth/token (échange de jeton)
    Note right of API1: client_id: API1_ID<br/>subject_token: [Token A]<br/>audience: API2

    Note over Auth0: Étape 4 : Émission du jeton
    activate Auth0
    Auth0-->>API1: Émet le jeton B<br/>(aud: API2, sub: UserX)
    deactivate Auth0
    Note right of Auth0: Le jeton B contient le claim act<br/>indiquant API1 comme acteur

    Note over API1,API2: Étape 5 : Requête en aval
    API1->>API2: Requête vers l'endpoint (jeton B)
    Note right of API1: Authorization: Bearer [Token B]
    activate API2
    API2->>API2: Valide le jeton B<br/>Identifie le sujet comme UserX

    Note over API2,Auth0: Étape 6 : API2 délègue à API3
    API2->>Auth0: POST /oauth/token (échange de jeton)
    Note right of API2: client_id: API2_ID<br/>subject_token: [Token B]<br/>audience: API3
    activate Auth0

    Note over Auth0: Étape 7 : Émission du jeton
    Auth0-->>API2: Émet le jeton C<br/>(aud: API3, sub: UserX)
    deactivate Auth0
    Note right of Auth0: Le jeton C contient le claim act<br/>indiquant API2 comme acteur

    Note over API2,API3: Étape 8 : Requête en aval
    API2->>API3: Requête vers l'endpoint (jeton C)
    Note right of API2: Authorization: Bearer [Token C]
    activate API3
    API3->>API3: Valide le jeton C<br/>Identifie le sujet comme UserX
    API3-->>API2: 200 OK
    deactivate API3

    API2-->>API1: 200 OK (Données)
    deactivate API2
    API1-->>Client App: 200 OK (Données traitées)
    deactivate API1
```

1. **Authentification de l’utilisateur** : L’utilisateur s’authentifie avec succès auprès d’une application cliente. L’Auth0 Authorization Server émet le jeton A, dont la portée est limitée à API1.
2. **Requête initiale** : L’application cliente envoie une requête à API1 en transmettant le jeton A dans l’en-tête `Authorization: Bearer`.
3. **API1 délègue à API2** : API1 reçoit le jeton A, le valide, puis le transmet au point de terminaison `/oauth/token` de l’Auth0 Authorization Server. En utilisant l’échange de jeton OBO, API1 présente le jeton A comme `subject_token` et demande un nouveau jeton pour API2.
4. **Émission de jeton** : L’Auth0 Authorization Server accorde un nouveau jeton d’accès, le jeton B, à API1. Le jeton B a le même `sub` (ID utilisateur) que le jeton A, mais le `aud` (audience) est maintenant API2.
5. **Requête en aval** : API1 envoie une requête à API2 à l’aide du jeton B.
6. **API2 délègue à API3** : API2 reçoit le jeton B, le valide, puis le transmet au point de terminaison `/oauth/token` de l’Auth0 Authorization Server. En utilisant l’échange de jeton OBO, API2 présente le jeton B comme `subject_token` et demande un nouveau jeton pour API3.
7. **Émission de jeton** : L’Auth0 Authorization Server accorde un nouveau jeton d’accès, le jeton C, à API2. Le jeton C a le même `sub` (ID utilisateur) que les jetons A et B, mais le `aud` (audience) est maintenant API3.
8. **Requête en aval** : API2 envoie une requête à API3 à l’aide du jeton C. API3 valide le jeton C et constate que la requête est bien effectuée « au nom de » l’utilisateur d’origine.

<div id="prerequisites">
  ## Prérequis
</div>

Seuls les clients d’API personnalisée associés à un serveur de ressources peuvent utiliser l’échange de jetons OBO. Un client d’API personnalisée est lié à un serveur de ressources lorsqu’ils ont le même identifiant.

Les clients d’API personnalisée doivent respecter les exigences suivantes :

* Définissez `app_type` sur `resource_server`.
* Définissez `resource_server_identifier` sur un identifiant de serveur de ressources valide, c.-à-d. `https://my-api.example.com`. Auth0 utilise l’identifiant du serveur de ressources comme paramètre `audience` dans les requêtes d’autorisation.

Comme les clients d’API personnalisée sont des clients de première partie, assurez-vous de [ne pas demander le consentement de l’utilisateur](/docs/fr-ca/get-started/applications/confidential-and-public-applications/user-consent-and-third-party-applications#skip-consent-for-first-party-applications) pour les API auxquelles votre client de première partie doit accéder.

<div id="create-custom-api-client">
  ### Créer un client d’API personnalisé
</div>

Vous pouvez créer un client d’API personnalisé à l’aide de l’Auth0 Dashboard ou de la Management API.

<Tabs>
  <Tab title="Auth0 Dashboard">
    Pour créer un client d’API personnalisé dans l’Auth0 Dashboard :

    1. Accédez à [**Applications > APIs**](https://manage.auth0.com/#/apis) et sélectionnez votre API backend.

    <Frame>
      <img src="https://mintcdn.com/translations/raZlN0BXDjNonwyb/docs/images/call_apis_on_users_behalf/my_test_obo_api.png?fit=max&auto=format&n=raZlN0BXDjNonwyb&q=85&s=d26bdd077254562d855cbf3b13c48584" alt="My Test OBO API" width="1410" height="180" data-path="docs/images/call_apis_on_users_behalf/my_test_obo_api.png" />
    </Frame>

    2. Sélectionnez **Add Application** et saisissez un nom d’application.
    3. Sélectionnez **Add**.

    Une fois l’application créée, consultez-la en sélectionnant **Configure Application**, puis faites défiler jusqu’à **Application Properties**. Le champ **Application Type** est **Custom API Client**.

    <Frame>
      <img src="https://mintcdn.com/translations/raZlN0BXDjNonwyb/docs/images/call_apis_on_users_behalf/create_custom_api_client.png?fit=max&auto=format&n=raZlN0BXDjNonwyb&q=85&s=4961bf0cbaf2a19b9612f7d39930e050" alt="My Test OBO API" width="1404" height="870" data-path="docs/images/call_apis_on_users_behalf/create_custom_api_client.png" />
    </Frame>
  </Tab>

  <Tab title="Management API">
    Pour créer un client d’API personnalisé avec le même identifiant que votre serveur de ressources, envoyez une requête `POST` au point de terminaison [`/api/v2/clients`](https://auth0.com/docs/api/management/v2/clients/post-clients) avec le corps de requête suivant :

    ```bash theme={null}
    curl --request POST 'https://{yourDomain}/api/v2/clients' \
      --header 'Content-Type: application/json' \
      --header 'Authorization: Bearer YOUR_MANAGEMENT_API_TOKEN' \
      --data '{
        "name": "Custom API Client",
        "app_type": "resource_server",
        "resource_server_identifier": "https://my-api.example.com"
      }'
    ```

    | Paramètre                    | Description                                                                                                                                               |
    | ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
    | `name`                       | Nom de votre client d’API personnalisé.                                                                                                                   |
    | `app_type`                   | Type d’application de votre client d’API personnalisé. Définissez-le sur `resource_server`.                                                               |
    | `resource_server_identifier` | Identifiant unique de votre client d’API personnalisé. Définissez-le sur l’audience de votre serveur de ressources, c.-à-d. `https://my-api.example.com`. |
  </Tab>
</Tabs>

<div id="create-client-grant">
  ### Créer un client grant
</div>

Vous devez créer un client grant avec accès délégué par l’utilisateur entre le client d’API personnalisée et l’API en aval afin d’autoriser l’accès.

<Tabs>
  <Tab title="Auth0 Dashboard">
    1. Accédez à [**Applications > Applications**](https://manage.auth0.com/#/applications) et sélectionnez votre client d’API personnalisée.
    2. Sous **API Access**, repérez votre serveur de ressources (c.-à-d. `https://my-api.example.com`) et sélectionnez **Edit**.
    3. Sous **User-Delegated Access**, sélectionnez **Grant Access**, puis sélectionnez les permissions à accorder, ou **Always grant all permissions**.
    4. Sélectionnez **Save**.
  </Tab>

  <Tab title="Management API">
    Faites une requête `POST` vers le point de terminaison [`/api/v2/client-grants`](https://auth0.com/docs/api/management/v2/client-grants/post-client-grants) avec le corps de la requête suivant :

    ```bash theme={null}
    curl --location 'https://{yourDomain}/api/v2/client-grants' \
      --header 'Content-Type: application/json' \
      --header 'Authorization: Bearer YOUR_MANAGEMENT_API_TOKEN' \
      --data '{
        "client_id": "YOUR_CLIENT_ID",
        "audience": "https://my-api.example.com",
        "scope": [
          "read:item"
        ],
        "subject_type": "user"
      }'
    ```
  </Tab>
</Tabs>

<div id="configure-the-obo-token-exchange">
  ### Configurer l’échange de jetons OBO
</div>

Découvrez comment configurer votre client d’API personnalisé pour utiliser le type d’octroi d’échange de jetons OBO.

<Tabs>
  <Tab title="Auth0 Dashboard">
    1. Accédez à **Applications > Applications** et sélectionnez votre client d’API personnalisé.
    2. Sous **Token Exchange**, activez **On-Behalf-Of Token Exchange**.
    3. Sélectionnez **Save**.

    <Frame>
      <img src="https://mintcdn.com/translations/raZlN0BXDjNonwyb/docs/images/call_apis_on_users_behalf/configure_obo_token_exchange.png?fit=max&auto=format&n=raZlN0BXDjNonwyb&q=85&s=15ce6671b8ffe6defd6fc94ddaa1e784" alt="Mon API OBO de test" width="1956" height="426" data-path="docs/images/call_apis_on_users_behalf/configure_obo_token_exchange.png" />
    </Frame>
  </Tab>

  <Tab title="Management API">
    Effectuez une requête `PATCH` au point de terminaison [`/api/v2/clients/{clientId}`](https://auth0.com/docs/api/management/v2/clients/patch-clients-by-id) avec le corps de requête suivant :

    ```bash theme={null}
    curl --location --request PATCH 'https://{yourDomain}/api/v2/clients/{clientId}' \
      --header 'Content-Type: application/json' \
      --header 'Authorization: Bearer YOUR_MANAGEMENT_API_TOKEN' \
      --data '{
        "token_exchange": {
          "allow_any_profile_of_type": ["on_behalf_of_token_exchange"]
        }
      }'
    ```
  </Tab>
</Tabs>

<div id="perform-obo-token-exchange">
  ## Effectuer un échange de jetons OBO
</div>

Pour effectuer l’échange de jetons OBO, vous pouvez utiliser [`auth0-api-js`](https://github.com/auth0/auth0-auth-js), [`auth0_api_python`](https://github.com/auth0/auth0-api-python) ou l’[Authentication API](https://auth0.com/docs/api/authentication).

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  Mettez les jetons d’accès en cache pour toute la durée de vie du jeton au lieu de demander un nouveau jeton pour chaque appel d’API. Les jetons d’accès peuvent être réutilisés jusqu’à leur expiration; des échanges de jetons répétés gaspillent des ressources, augmentent la latence et peuvent entraîner l’application de limites de débit.
</Callout>

<Tabs>
  <Tab title="JavaScript">
    Avant de commencer, assurez-vous d'avoir installé la bibliothèque [`auth0-api-js`](https://github.com/auth0/auth0-auth-js) et ses dépendances.

    Commencez par initialiser `ApiClient` avec les identifiants de votre serveur MCP :

    ```javascript theme={null}
    import { ApiClient } from '@auth0/auth0-api-js';

    const apiClient = new ApiClient({
      domain: 'YOUR_AUTH0_DOMAIN',
      audience: 'YOUR_MCP_SERVER_AUDIENCE',
      clientId: 'YOUR_CLIENT_ID',
      clientSecret: 'YOUR_CLIENT_SECRET',
    });
    ```

    Ensuite, utilisez la méthode `getTokenOnBehalfOf()` pour procéder à l’échange de jetons :

    ```javascript theme={null}
    const result = await apiClient.getTokenOnBehalfOf(accessToken, {
      audience: 'YOUR_DOWNSTREAM_API_AUDIENCE',
      scope: 'read:private',  // Facultatif
    });
    ```

    `getTokenOnBehalfOf()` retourne un objet contenant :

    * `accessToken` : Le nouveau token pour votre API en aval
    * `scope` : Les scopes accordés
    * `expiresIn` : La durée d’expiration du token, en secondes
  </Tab>

  <Tab title="Python">
    Avant de commencer, assurez-vous d'avoir installé la bibliothèque [`auth0_api_python`](https://github.com/auth0/auth0-api-python) ainsi que ses dépendances.

    Commencez par importer les classes nécessaires et initialiser `ApiClient` avec les identifiants de votre serveur MCP :

    ```python theme={null}
    from auth0_api_python import ApiClient, ApiClientOptions

    api_client = ApiClient(
        ApiClientOptions(
            domain='YOUR_AUTH0_DOMAIN',
            audience='YOUR_MCP_SERVER_AUDIENCE',
            client_id='YOUR_CLIENT_ID',
            client_secret='YOUR_CLIENT_SECRET',
        )
    )
    ```

    Ensuite, utilisez la méthode `get_token_on_behalf_of()` pour procéder à l’échange de jetons :

    ```python theme={null}
    result = await api_client.get_token_on_behalf_of(
        access_token=access_token,
        audience='YOUR_DOWNSTREAM_API_AUDIENCE',
        scope='read:private'  # Facultatif
    )
    ```

    `get_token_on_behalf_of()` retourne un dictionnaire contenant :

    * `access_token` : Le nouveau jeton destiné à votre API en aval
    * `scope` : Les portées accordées
    * `expires_in` : La durée de validité du jeton, en secondes
  </Tab>

  <Tab title="cURL">
    Faites une requête `POST` au point de terminaison `/oauth/token` avec le corps de requête suivant :

    ```bash theme={null}
    curl --location 'https://YOUR_DOMAIN.us.auth0.com/oauth/token' \
      --header 'Content-Type: application/json' \
      --data '{
        "client_id": "YOUR_CLIENT_ID",
        "client_secret": "YOUR_CLIENT_SECRET",
        "subject_token": "AUTH0_SUBJECT_TOKEN",
        "grant_type": "urn:ietf:params:oauth:grant-type:token-exchange",
        "subject_token_type": "urn:ietf:params:oauth:token-type:access_token",
        "requested_token_type": "urn:ietf:params:oauth:token-type:access_token",
        "audience": "https://my-api.example.com"
      }'
    ```

    | Paramètre              | Exemple                                           | Description                                                                                                                                                                                                                                                    |
    | ---------------------- | ------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
    | `grant_type`           | `urn:ietf:params:oauth:grant-type:token-exchange` | Obligatoire. Indique au serveur d’autorisation d’effectuer un échange plutôt qu’une ouverture de session standard.                                                                                                                                             |
    | `client_id`            | `<custom_api_client_id>`                          | Obligatoire. L’ID unique du service intermédiaire qui envoie la requête.                                                                                                                                                                                       |
    | `client_secret`        | `<custom_api_client_secret>`                      | Facultatif. Le secret (ou l’assertion) utilisé pour authentifier le service intermédiaire lui-même. Vous pouvez utiliser n’importe quelle méthode d’authentification du client; toutefois, vous ne pouvez pas définir `token_endpoint_auth_method` sur `none`. |
    | `subject_token`        | `<auth0_access_token>`                            | Obligatoire. Le jeton entrant provenant de l’utilisateur ou du client que le service intermédiaire détient actuellement.                                                                                                                                       |
    | `subject_token_type`   | `urn:ietf:params:oauth:token-type:access_token`   | Obligatoire. Définit le format du `subject_token` (par exemple, un jeton d’accès plutôt qu’un jeton d’identité).                                                                                                                                               |
    | `requested_token_type` | `urn:ietf:params:oauth:token-type:access_token`   | Obligatoire. Indique le type de jeton que vous souhaitez recevoir en retour (habituellement un jeton d’accès pour l’API suivante).                                                                                                                             |
    | `audience`             | `https://my-api.example.com`                      | Obligatoire. L’identifiant du service en aval qui recevra et validera le nouveau jeton.                                                                                                                                                                        |
    | `scope`                | `read:data write:data`                            | Facultatif. Une liste de permissions précises demandées pour la requête en aval, séparées par des espaces.                                                                                                                                                     |

    Si tout se passe bien, vous devriez recevoir une réponse semblable à ce qui suit :

    ```json theme={null}
    {
      "access_token": "YOUR_AUTH0_ACCESS_TOKEN",
      "expires_in": 86400,
      "token_type": "Bearer",
      "issued_token_type": "urn:ietf:params:oauth:token-type:access_token"
    }
    ```

    | Paramètre           | Exemple                                         | Description                                                                                                                                                                                                                                                              |
    | ------------------- | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
    | `access_token`      | `eyJ...`                                        | Le « nouveau » jeton d’accès Auth0. Il s’agit du JWT ou de la chaîne opaque que le service intermédiaire utilisera pour effectuer une requête vers l’API en aval.                                                                                                        |
    | `issued_token_type` | `urn:ietf:params:oauth:token-type:access_token` | Confirme le format du jeton renvoyé. Il correspond au `requested_token_type` de votre requête (ou à un sous-ensemble de celui-ci).                                                                                                                                       |
    | `token_type`        | `Bearer`                                        | Indique le schéma d’authentification dans l’en-tête `Authorization`. Pour OBO, il s’agit de `Bearer`, à moins que le service intermédiaire et l’API en aval n’utilisent DPoP, auquel cas `DPoP` sera utilisé.                                                            |
    | `expires_in`        | `3600`                                          | La durée de vie du jeton, en secondes, selon la configuration de l’API en aval. Notez qu’elle est souvent plus courte que celle du jeton utilisateur d’origine.                                                                                                          |
    | `scope`             | `read:data`                                     | Les permissions précises accordées au jeton. Vous devez activer ces permissions à l’aide d’une [autorisation client pour l’accès délégué par l’utilisateur](/docs/fr-ca/get-started/applications/application-access-to-apis-client-grants#user-access-vs-client-access). |
  </Tab>
</Tabs>

<div id="token-binding">
  ## Token Binding
</div>

<Warning>
  Lorsque des jetons sont liés à l’émetteur au moyen de [DPoP](/docs/fr-ca/secure/sender-constraining/demonstrating-proof-of-possession-dpop) ou de [mTLS](/docs/fr-ca/secure/sender-constraining/mtls-sender-constraining), seul le détenteur de la clé ou du certificat en question peut en prouver la possession et utiliser le jeton.

  Lors d’un échange OBO, le [service intermédiaire](/docs/fr-ca/secure/call-apis-on-users-behalf/on-behalf-of-token-exchange) détient le jeton.

  Auth0 ne peut pas vérifier cryptographiquement que le service intermédiaire détient la clé ou le certificat du détenteur initial; il ne vérifie donc pas de nouveau le Token Binding du jeton initial durant l’échange.

  Le service intermédiaire doit :

  * Vérifier le Token Binding
  * Lier les nouveaux jetons
  * Gérer le mécanisme de commutation entre DPoP et mTLS
</Warning>

La vérification du Token Binding relève du service intermédiaire. La liaison est une preuve cryptographique que le détenteur du jeton possède la clé ou le certificat du détenteur initial. Avant d’échanger un jeton lié, validez que le Token Binding du jeton initial a été vérifié :

* DPoP : calculez l’empreinte JWK SHA-256 du `jwk` dans la preuve DPoP entrante (conformément à la [RFC 7638](https://www.rfc-editor.org/rfc/rfc7638)) et vérifiez qu’elle correspond à la revendication `cnf.jkt` du jeton de sujet. Auth0 n’effectue pas cette vérification durant l’échange de jetons.
* mTLS : calculez l’empreinte SHA-256, encodée en base64url, de l’encodage DER du certificat client et vérifiez qu’elle correspond à la revendication `cnf.x5t#S256` du jeton de sujet.

Si la validation échoue, rejetez la requête sans tenter l’échange.

**Liaison du nouveau jeton** : Auth0 liera le jeton d’accès nouvellement émis à l’émetteur lorsque le [serveur de ressources en aval a la liaison à l’émetteur activée ou obligatoire](/docs/fr-ca/secure/sender-constraining) et que le service intermédiaire présente une preuve DPoP ou un certificat mTLS valide au point de terminaison `/oauth/token`.

| **Mécanisme** | **Comment lier le nouveau jeton**                                                                                                                                                                                                                                                                                                                                                                                                         |
| ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| DPoP          | Incluez un en-tête de preuve `DPoP` fraîchement généré dans la requête `/oauth/token`. La preuve doit être limitée à cette requête : définissez `htm` sur `POST` et `htu` sur l’URI du point de terminaison `/oauth/token` de votre tenant Auth0. Le jeton émis sera lié à DPoP et la valeur de `token_type` dans la réponse sera `DPoP`.                                                                                                 |
| mTLS          | Pour une liaison mTLS, l’échange de jetons OBO exige TLS mutuel : le service intermédiaire doit s’authentifier au moyen d’un certificat client, plutôt que de s’appuyer uniquement sur TLS côté serveur. Le certificat doit être [provisionné pour le client de niveau intermédiaire dans Auth0](/docs/fr-ca/get-started/applications/configure-mtls). Auth0 émettra un jeton contenant une revendication de confirmation `cnf.x5t#S256`. |

Si aucune preuve DPoP ni aucun certificat mTLS n’est présenté, Auth0 émet un jeton porteur non lié, quel que soit l’état de liaison du jeton de sujet initial.

**Transitions entre les mécanismes de liaison et capacités incompatibles** : Le service intermédiaire peut changer de mécanisme de liaison durant un échange OBO (par exemple, de DPoP à mTLS), à condition de posséder les identifiants nécessaires au nouveau mécanisme (par exemple, un certificat mTLS provisionné). Le jeton nouvellement émis reflète le nouveau type de liaison.

Avant l’échange, vérifiez que l’API en aval prend en charge le mécanisme de liaison présenté. Auth0 ne valide pas la compatibilité des mécanismes; il émettra le jeton dans tous les cas. Si l’API en aval ne prend pas en charge le mécanisme présenté, elle rejettera le jeton à l’exécution. Si les mécanismes ne peuvent pas être conciliés, ne tentez pas l’échange; retournez plutôt une erreur à l’appelant.

**Nonces DPoP** : Si le jeton de sujet initial a été émis pour un client public (comme une SPA ou une application mobile) à l’aide de DPoP avec un nonce émis par le serveur, le service intermédiaire pourrait ne pas disposer d’un nonce valide pour établir une nouvelle liaison au point de terminaison `/oauth/token`. Dans ce cas, Auth0 retourne une erreur `use_dpop_nonce` accompagnée d’un nouveau nonce dans l’en-tête de réponse `DPoP-Nonce`. Réessayez la requête en utilisant ce nonce dans la nouvelle preuve DPoP.

<Callout icon="triangle-exclamation" color="#F59E0B" iconType="regular">
  Si le jeton de sujet initial était lié à l’émetteur, mais que le service intermédiaire ne présente pas de justificatifs de liaison (preuve DPoP ou certificat mTLS) au point de terminaison `/oauth/token`, Auth0 ne rejette pas la requête; il émet plutôt un jeton porteur non lié sans signaler d’erreur. L’API en aval l’acceptera sans preuve de possession, ce qui le rend réutilisable s’il est intercepté. Si le serveur de ressources en aval exige des jetons liés à l’émetteur, ne transmettez pas le jeton non lié. Rejetez-le et renvoyez une erreur à l’appelant.
</Callout>

<div id="organizations-support">
  ## Prise en charge d’Organizations
</div>

Lorsqu’un utilisateur s’authentifie via une organisation, le jeton d’accès comprend une claim `org_id`. L’échange de jeton OBO préserve ce contexte de l’organisation tout au long de la chaîne de délégation.

Quand Auth0 reçoit une demande d’échange de jeton OBO avec un jeton d’accès associé à une organisation, il vérifie :

* que `org_id` existe dans votre tenant
* que l’utilisateur (identifié par `sub`) est membre de cette organisation

Si la validation échoue, Auth0 rejette la demande d’échange de jeton. Si elle réussit, Auth0 émet un nouveau jeton d’accès qui :

* contient la même claim `org_id` que le jeton d’origine
* applique les mêmes politiques RBAC propres à l’organisation
* rend le contexte de l’organisation accessible dans le [déclencheur `post-login` d’Actions](/docs/fr-ca/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger/post-login-event-object#event-organization) via la propriété `event.organization`
