# Connect with an OAuth client

With **OAuth client**, the gateway requests a token from your identity provider with the OAuth 2.0 client credentials grant and sends it on every call. Use it when your API verifies tokens issued by Microsoft Entra ID, Auth0, Okta, Keycloak, Amazon Cognito or another provider with a token endpoint.

## Before you begin

Register a client for Faustine at your identity provider and grant it the scope or audience of your API. Each provider has its own page:

- [Connect an API that uses Microsoft Entra ID](https://docs.faustine.ai/technologies/entra-id/)
- [Connect an API that uses Auth0](https://docs.faustine.ai/technologies/auth0/)
- [Connect an API that uses Okta](https://docs.faustine.ai/technologies/okta/)
- [Connect an API that uses Keycloak](https://docs.faustine.ai/technologies/keycloak/)
- [Connect an API that uses Amazon Cognito](https://docs.faustine.ai/technologies/cognito/)

## How the gateway gets the token

On the first call through a connection, the gateway sends a form-encoded `POST` to the token URL with `grant_type=client_credentials`, the scopes and the audience set on the API, and the connection's client ID and secret. It reads `access_token` from the response and adds `Authorization: Bearer <access_token>` to the call.

The gateway keeps the token and renews it 30 seconds before the `expires_in` the provider returned. When the response has no `expires_in`, it uses the `exp` claim of the token. It also requests a new token when a call answers `401`.

## Set the strategy on the API

To describe the token endpoint:

1. In the portal, go to [**APIs**](https://auth.faustine.ai/go?to=%2Fintegrations%2Fapis) and select your API.
2. Select the **Authentication** tab, then **Edit**.
3. In **Sign-in method**, select **OAuth client**.
4. In **Token provider**, select your provider and fill in the fields it shows. The token URL appears under the field as you type.
5. Fill in **Client secret sent**, **Scopes** and **Audience**.
6. Select **Save changes**.

| Token provider | Fields | Token URL |
| --- | --- | --- |
| **Microsoft Entra ID** | **Tenant ID** | `https://login.microsoftonline.com/<TENANT>/oauth2/v2.0/token` |
| **Auth0** | **Domain** | `https://<DOMAIN>/oauth/token` |
| **Keycloak** | **Server URL**, **Realm** | `<SERVER_URL>/realms/<REALM>/protocol/openid-connect/token` |
| **Okta** | **Domain**, **Authorization server** | `https://<DOMAIN>/oauth2/<SERVER>/v1/token` |
| **Amazon Cognito** | **User pool domain** | `https://<DOMAIN>/oauth2/token` |
| **Custom** | **Token URL** | The URL as you enter it. |

| Field | Description |
| --- | --- |
| **Scopes** | Space-separated. Sent as `scope`. |
| **Audience** | Sent as `audience`. Required for Auth0. Leave it empty when the provider does not use one. |
| **Client secret sent** | **In the body** sends `client_id` and `client_secret` as form fields. **HTTP Basic** sends them in the `Authorization` header of the token request. Selecting **Microsoft Entra ID** sets **In the body**, and selecting **Amazon Cognito** sets **HTTP Basic**. |

## Add the client to a connection

To store the client's credentials for one deployment, [add a connection](https://docs.faustine.ai/apis/add-a-connection/) and enter the **Client ID** and **Client secret** of the client you registered in the **Credentials** step.

The test requests a token and then calls the operation, so **Reached the endpoint** with a `2xx` status confirms the client, the scopes and the audience.

## Troubleshooting

| Symptom | Cause | Fix |
| --- | --- | --- |
| `Identity provider refused the client credentials`, with `invalid_client` | The client ID or secret is wrong, or the provider expects the secret the other way. | Correct the values in the connection, or change **Client secret sent**. |
| `Identity provider refused the client credentials`, with `invalid_scope` | The client is not granted the scope. | Grant the scope at the provider, or correct **Scopes**. |
| `Auth0 needs the API identifier as the audience.` | **Audience** is empty for an Auth0 token URL. | Enter the identifier of the API as registered in Auth0. |
| The token request succeeds and calls answer `401` | Your API does not accept the token's audience or scopes. | Compare the token's claims with what your API verifies. |

## Next steps

- [Authentication](https://docs.faustine.ai/apis/authentication/): token exchange, for an API that swaps the provider's token for its own.
- [Write a custom sign-in script](https://docs.faustine.ai/apis/custom-sign-in-script/): for a token request the form does not cover.
- [Add an API to a gateway](https://docs.faustine.ai/agent-gateway/add-an-api/): serve the API through the connection.
