# Set up integration with the enterprise identity provider

> Set up integration so that Keycloak delegates authentication to an external enterprise identity provider

Integration consists of these phases:

1. Create a confidential OAuth client in the enterprise identity service provider (IdP).
2. Configure Keycloak with information about this client and the IdP endpoints.
3. Update the OAuth client settings in the enterprise IdP, based on the Keycloak configuration.

## 1. Create a confidential OAuth client in the IdP

### In Microsoft Entra ID

Complete these steps:

1. In Microsoft Entra ID, go to the [app registration page](https://portal.azure.com/#view/Microsoft_AAD_IAM/ActiveDirectoryMenuBlade/~/RegisteredApps).

2. Create an app registration in the target tenant. The app registration is an OAuth client.

   At this stage, no configuration is required, except for a name. This name is a de-facto display name that you can change. You can leave all the other default values as is.

3. Create a secret for this client and save it temporarily to a safe place.

   This secret is required for the configuration of Keycloak. With this secret, the client is confidential. Keycloak uses this secret for authentication.

4. Make a note of this information:

   * The application ID (client ID) that is assigned to the new application
   * The directory ID (tenant ID)

   Both values are GUID, but aren't sensitive data, unlike the client secret.

### In Okta

Complete these steps:

1. In the Okta admin console, select the target Okta organization.

2. Go to **Applications** > **Applications**.

3. Select **Create App Integration**.

4. Provide these settings during the creation:

   * Sign-in method: `OIDC - Open ID Connect`

     * Application type: `web application`

     * In the **General Settings** section:

       * App integration name: a descriptive name for the application. This name is a de-facto display name that you can change later.
       * Grant type: select `Client Credentials`.

     * In the **Assignments** section:

       * Controlled access: `Allow everyone in your organization to access`
       * Enable immediate access: `Enabled`

5. Make a note of this information:

   * The Client ID that is assigned to the new application. This ID is an arbitrary string in this format: `0oaibyvqhz1CgoBQC5d7`.
   * The client secret that Okta has generated. The client secret is sensitive data.

## 2. Configure Keycloak for integration

Complete these steps:

1. In the Keycloak admin console, switch to the **unity** solution realm.

2. Go to **Configure** > **Identity Providers**.

3. Add a new IdP with these settings:

   1. Select the `OpenID Connect v1.0` type for the IdP.

   2. Select an alias for the IdP. The alias must be a short lowercase string without white spaces, for example, `unity`. You can use the same alias for different customers. These requirements are to avoid potential issues, because URIs contain the alias.

   3. Select a display name for the IdP.

   4. Ensure that the **Use discovery endpoint** setting is enabled. Provide the following value for this field:

      * For Entra ID:

        `https://login.microsoftonline.com/<tenant-id>/.well-known/openid-configuration`

        In this URL, replace `<tenant-id>` with the directory ID from the previous step. For example, for the Unity Entra ID tenant, the URL has this format:

        `https://login.microsoftonline.com/45b9a1d4-a8af-40da-8eca-96bebddf6fc7/.well-known/openid-configuration`

      * For Okta:

        `https://<org-name>.okta.com/.well-known/openid-configuration`

        In this URL, replace `<org-name>` with the name of Okta organization of the enterprise IdP. For example, for the Unity Okta organization, the URL has this form:
        `https://unity.okta.com/.well-known/openid-configuration`

   5. In the **Show metadata** section, make sure the values are filled in.

   6. Enter this information:

      * The client ID, which is the application ID from the previous step.
      * The client secret. The client secret must stay in the client configuration, but you don't need to save it. You don't need this value after configuration.

   7. To create the configuration, select **Add**.

4. Open the newly created IdP.

5. On the **Settings** tab, change these settings:

   * Use PKCE: on
   * PKCE method: `S256`

6. In the **Advanced** section, set these values:

   * Backchannel Logout: on
   * Send 'id\_token\_hint' in logout requests: on
   * Scopes: add the `openid email profile` scope

7. On the **Advanced settings** tab, change these settings:

   * Sync mode: `Force`
   * Trust email: on

8. Select **Save**.

Make a note of the value of the **Redirect URI** read-only field in the IdP configuration. You need this value for the next procedure.

### Mappers

Mappers map the user attributes from the IdP to the Keycloak user attributes. On the **Mappers** tab, add the mappers for your identity provider.

In the **Add Identity Provider Mapper** window, leave the **Sync mode override** option to `Inherit` unless specified otherwise.

#### In Entra ID

| Name                             | Mapper Type                | Configuration                                                               | Purpose                                                                                                                                                                                                                                          |
| -------------------------------- | -------------------------- | --------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| idp-broker-id                    | Username template importer | * Template: `${CLAIM.oid}`
* Target: `BROKER_ID`                            | Maps the Keycloak user to the Entra ID user by its object ID.                                                                                                                                                                                    |
| idp-broker-username              | Username template importer | - Template: `${CLAIM.preferred_username}`
- Target: `BROKER_USERNAME`       | Maps the Keycloak user to the Entra ID user by its principal name.                                                                                                                                                                               |
| idp-attribute-email              | Attribute importer         | * Claim: `email`
* User attribute name: `email`                             | Sets the user email in Keycloak based on the IdP user profile.                                                                                                                                                                                   |
| idp-attribute-firstName          | Attribute importer         | - Claim: `given_name`
- User attribute name: `firstName`                    | Sets the user's first name in Keycloak based on the IdP user profile.                                                                                                                                                                            |
| idp-attribute-lastName           | Attribute importer         | * Claim: `family_name`
* User attribute name: `lastName`                    | Sets the user's full name in Keycloak based on the IdP user profile.                                                                                                                                                                             |
| idp-attribute-fullName           | Attribute importer         | - Claim: `name`
- User attribute name: `fullName`                           | Sets the user's full name in Keycloak based on the IdP user profile.&#xA;Use this mapper only as an alternative to the two mappers `idp-attribute-firstName` and `idp-attribute-lastName` and if you can't use the first name and the last name. |
| idp-attribute-enterpriseObjectId | Attribute importer         | * Claim: `oid`
* User attribute name: `Custom Attribute\enterpriseObjectId` | Sets a special custom attribute to the user ID in the IdP.                                                                                                                                                                                       |

#### In Okta

| Name                             | Mapper Type                | Configuration                                                               | Purpose                                                                                                                                                                                                                                                |
| -------------------------------- | -------------------------- | --------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| idp-broker-username              | Username template importer | * Template: `${CLAIM.preferred_username}`
* Target: `BROKER_USERNAME`       | Maps the Keycloak user to the Okta user by its username.                                                                                                                                                                                               |
| idp-attribute-email              | Attribute importer         | - Claim: `email`
- User attribute name: `email`                             | Sets the user's email address in Keycloak based on the IdP user profile.                                                                                                                                                                               |
| idp-attribute-firstName          | Hard-coded attribute       | * User attribute: `firstName`
* User attribute value: \<empty string>       | Sets an empty first name for the user in Keycloak.&#xA;By default, the Okta tokens don't contain the user's first name and last name.                                                                                                                  |
| idp-attribute-lastName           | Attribute importer         | - Claim: `name`
- User attribute name: `lastName`                           | Sets the user's full name in Keycloak based on the IdP user profile.&#xA;By default, the Okta tokens don't contain the user's first name and last name.&#xA;This mapper duplicates the `fullName` attribute to enable search by substring in Keycloak. |
| idp-attribute-fullName           | Attribute importer         | * Claim: `name`
* User attribute name: `Custom Attribute\fullName`          | Sets the user's full name in Keycloak based on the IdP user profile.                                                                                                                                                                                   |
| idp-attribute-enterpriseObjectId | Attribute importer         | - Claim: `sub`
- User attribute name: `Custom Attribute\enterpriseObjectId` | Sets a special custom attribute to the user ID in Okta.                                                                                                                                                                                                |

## 3. Update the OAuth client settings in the enterprise IdP

### For Entra ID

For Entra ID, complete these steps:

1. Go to the app registration for the client, and then go to **Properties** > **Authentication**.

2. To add the Keycloak redirect URI to the application properties, add a platform of type `Web`.

   This URI must start with this string: `https://<solution-domain-name>`.

   If the URI starts with `http://127.0.0.1`, then replace this part with `https` and the correct domain name of the solution. This situation occurs when you access the Keycloak admin console through Kubernetes port forwarding.

   The full redirect URI has this format: `https://<solution-domain-name>/auth/realms/<realm-name>/broker/<alias>/endpoint`.

3. In the app registration properties, go to **Token configuration**.

4. Add the following optional claims to the ID token:

| Claim               | Description                                                                                                                                                            | Token type |
| ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
| email               | For example:```text
The addressable email address for this user,
if the user has one.
```                                                                              | `ID`       |
| preferred\_username | For example:```text
Provides the preferred username claim,
which makes it easier for applications
to provide username hints
and show human readable display names.
``` | `ID`       |

This change might take two to three minutes to take effect.

### For Okta

For Okta, complete these steps:

1. In the Okta admin console, select the application.

2. Go to **General Settings**.

3. Add the Keycloak redirect URI into the application properties as a sign-in redirect URI.

   This URI must start with this string: `https://<solution-domain-name>`.

   If the URI starts with `http://127.0.0.1`, then replace this part with `https` and the correct domain name of the solution. This situation occurs when you access the Keycloak admin console through Kubernetes port forwarding.

   The full redirect URI has this format: `https://<solution-domain-name>/auth/realms/<realm-name>/broker/<alias>/endpoint`.

4. Set a sign-out redirect URI there to the address:

   `https://<solution-domain-name>/auth/realms/<realm-name>/protocol/openid-connect/logout`

The **General** tab shows the resulting application settings:

* **Client credentials** section:

  * The client ID

* **Client secrets** section:

  * The client authentication method: `client secret`
  * The client secrets

* **Application** section:

  * The application name: `unity-keycloak`
  * The application type: `Web`
  * For the grant type:

    * For the client that acts on its behalf: `Client credentials`
    * For the client that acts on the user's behalf: `Authorization code`

* **User consent** section:

  * The user consent set as required

* **Login** section:

  * The sign-in redirect URI: `https://<solution-domain-name>/auth/realms/sample/broker/okta/endpoint`
  * The sign-out redirect URI: `https://<solution-domain-name>/auth/realms/sample/protocol/openid-connect/logout`
  * The entity that can initiate the login: `App only`

* **Federation Broker Mode** section:

  * Immediate app access with this mode: enabled

## Next steps

[Rotate the client secret of the SSO application](./rotate-client-secret.md)
