> For the complete documentation index, see [llms.txt](https://docs.coherent.global/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.coherent.global/identity-and-access-management/single-sign-on/microsoft-entra-id-saml-v2.0.md).

# Microsoft Entra ID (SAML v2.0)

## Prerequisites

<details>

<summary>Permissions required for registering and configuring an app in Microsoft Entra ID.</summary>

The account must have permission to manage applications in Microsoft Entra ID. Ideally, the account should be in the Global Admin role to grant admin consent.

</details>

## Implement single sign-on (SSO) - Baseline

It is recommended to use two separate browser tabs for the Azure (A) and Keycloak (K) portals to make it easier to apply the settings.

1. (K) Open a new tab in your browser and sign in to the target Spark tenant. Access the **Keycloak console** from the [Navigation menu](/navigation/navigation-menu.md#user-menu).
2. (K) Select **Identity Providers** from the left pane.
3. (K) Expand the **Add provider** dropdown and choose **SAML v2.0**.
4. (K) Enter values for the **Alias** and **Display Name** fields. The **Alias** should be a lowercase name without special symbols. Please note this **Display Name** will appear in the button on the Spark sign-in page.
5. (K) Copy the **Redirect URI** value.
6. (A) In a second browser tab, sign in to [Azure Portal](https://portal.azure.com).
7. (A) Navigate to Microsoft Entra ID → Enterprise Applications → All applications.
8. (A) On the **All applications** page, select **New application**.
9. (A) Select **Create your own application**.
10. (A) Type a name for your application.
11. (A) In the section **What are you looking to do with your application?**, select **Integrate any other application you don't find in the gallery**.
12. (A) Select **Create**.
13. (A) On the **Overview** page, in the **Getting Started** area, select **Set up single sign on**.
14. (A) In the **Select a single sign-on method** area, select **SAML**.
15. (A) On the **Set up Single Sign-On with SAML** page, in the **Basic SAML Configuration** area, select **Edit**.
16. (A) Under the **Basic SAML configuration**, configure the following settings:
    1. In **Identifier (Entity ID)**, select **Add identifier**, use the Redirect URI copied earlier and remove everything after the tenant name, i.e. `https://keycloak.{environment}.coherent.global/auth/realms/{tenant}`.
    2. Select **Add reply URL** and paste the edited Redirect URI into the **Reply URL (Assertion Consumer Service URL)**, i.e. `https://keycloak.{environment}.coherent.global/auth/realms/{tenant}/broker/{alias}/endpoint`.
    3. Leave the default values for other fields and select **Save**.
17. (A) In the **SAML Certificates Token signing certificate** section, copy the **App Federation Metadata Url**. You will use this link when creating an Entra ID SAML provider on Keycloak.
18. In the **Manage** section in the left pane, ensure that **Assignment required?** is set to **Yes**.
19. In **Users and groups** in the left pane, select **Add user/group** to add the users and groups that will be allowed to use Spark.
    * If you are a Global Administrator in Microsoft Entra, the user assignment requirement does not apply. Global Administrators can bypass Enterprise Application assignment restrictions.
20. (K) Return to Keycloak. Paste the **App Federation Metadata Url** into the **SAML entity descriptor** field.
21. (K) Select **Add**.
22. (K) In **NameID policy format**, select **Email**.
23. (K) Select **Save**.
24. (K) Select the *Mappers* tab and then select **Add mapper**.
25. (K) Create 3 mappers with the following properties:
    1. | Key                     | Value                                                             |
       | ----------------------- | ----------------------------------------------------------------- |
       | **Name**                | `firstName`                                                       |
       | **Sync mode override**  | `Force`                                                           |
       | **Mapper type**         | `Attribute Importer`                                              |
       | **Attribute Name**      | `http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname` |
       | **Name Format**         | `ATTRIBUTE_FORMAT_BASIC`                                          |
       | **User Attribute Name** | `firstName`                                                       |
    2. | Key                     | Value                                                           |
       | ----------------------- | --------------------------------------------------------------- |
       | **Name**                | `lastName`                                                      |
       | **Sync mode override**  | `Force`                                                         |
       | **Mapper type**         | `Attribute Importer`                                            |
       | **Attribute Name**      | `http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname` |
       | **Name Format**         | `ATTRIBUTE_FORMAT_BASIC`                                        |
       | **User Attribute Name** | `lastName`                                                      |
    3. | Key                     | Value                                                                |
       | ----------------------- | -------------------------------------------------------------------- |
       | **Name**                | `email`                                                              |
       | **Sync mode override**  | `Force`                                                              |
       | **Mapper type**         | `Attribute Importer`                                                 |
       | **Attribute Name**      | `http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress` |
       | **Name Format**         | `ATTRIBUTE_FORMAT_BASIC`                                             |
       | **User Attribute Name** | `email`                                                              |
26. For SAML SSO, it is important to validate signatures to prevent unauthorized access. For more information see [Importance of validating signatures in SAML](/identity-and-access-management/single-sign-on/importance-of-validating-signatures-in-saml.md).
    1. (K) For the identity provider you have set up, scroll down to **Signature and Encryption settings**.
    2. (K) Enable the option **Validate Signature**.
    3. (K) Enable the option **Metadata Descriptor URL**.
27. Navigate to your Spark tenant and sign in using the newly created provider. The Keycloak sign-in page shows a button with the display name you defined earlier.

## Set up users against user groups

In the documentation below, we describe how Spark user group assignment can be done with either Entra ID app roles or Entra ID groups.

* **App roles**: Use app roles when you need fine-grained, application-specific permissions. This is ideal for defining what users can do within a specific application.
* **Groups**: Use groups for broader access management that spans multiple applications and resources. This is useful for organizational roles like departments, teams, or project groups where access to various resources needs to be managed collectively.

| Feature                | App roles                                | Groups                                   |
| ---------------------- | ---------------------------------------- | ---------------------------------------- |
| **Scope**              | Specific to an application               | Cross-application                        |
| **Management**         | Defined in the application's manifest    | Managed in Microsoft Entra ID            |
| **Assignment**         | Assigned to users or groups              | Users are added to groups                |
| **Granularity**        | Fine-grained, application-specific roles | Broader, resource-wide access control    |
| **Dynamic Membership** | No                                       | Yes                                      |
| **Use Case Example**   | Role-based access within a single app    | Access control across multiple resources |

### Configure Entra ID app roles to Spark user groups

{% hint style="info" %}
Do not configure a mapper for the `user:pf` group. This is the default minimal Spark group that users must belong to in order to sign in to Spark. Configuring a mapper for this group unnecessarily duplicates sign-in permission management already controlled by your Identity Provider.
{% endhint %}

It is recommended to use two separate browser tabs for the Azure and Keycloak portals to make it easier to apply the settings. In this guide, we will set up the automatic roles for the `tenant-admin` role.

1. (A) In the first tab sign in to [Azure Portal](https://portal.azure.com).
2. (A) Search for and select **Microsoft Entra ID***.*
3. (A) Select **App registrations**, then select the application you previously created and select **App roles**.
4. (A) Select **Create app role**.
5. (A) Provide the following values and then select **Apply**.<br>

   | Key                                      | Value                     |
   | ---------------------------------------- | ------------------------- |
   | **Allowed member types**                 | `User/Groups`             |
   | **Display name**                         | `tenant-admin`            |
   | **Value**                                | `tenant-admin`            |
   | **Description**                          | Your app role description |
   | **Do you want to enable this app role?** | `True`                    |
6. (A) Select **Overview** in the left pane and then on your application in **Managed application in local directory**.
7. (A) Select on **Set up single sign on**.
8. (A) Under **Attributes & Claims** select **Edit**.
9. (A) Select on **Add new claim**.
10. (A) Assign the following values:

    | Key                  | Value                |
    | -------------------- | -------------------- |
    | **Name**             | `roles`              |
    | **Source attribute** | `user.assignedroles` |
11. (A) Select **Users and Groups** from the left pane and then **Add user/group**.
12. (A) Assign your test account to the `tenant-admin` role.
13. (K) Open a new tab in your browser and sign in to the target Spark tenant. Access the **Keycloak console** from the [Navigation menu](/navigation/navigation-menu.md#user-menu).
14. (K) Select **Identity Providers** from the left pane and then the identity provider you configured in the previous section.
15. (K) Select the **Mappers** tab and then select **Add mapper**.
16. (K) Provide the following values.

    | Name                   | Value                         |
    | ---------------------- | ----------------------------- |
    | **Name**               | `tenant-admin`                |
    | **Sync mode override** | `force`                       |
    | **Mapper type**        | `Advanced Attribute to Group` |
17. (K) Select **Add Claims**.
18. (K) Provide the following values:

    | Key                                                            | Value          |
    | -------------------------------------------------------------- | -------------- |
    | `http://schemas.microsoft.com/ws/2008/06/identity/claims/role` | `tenant-admin` |
19. (K) Leave **Regex Claim Values** as **Off** (which is the default).
20. (K) Select **Select Group***,* choose `tenant-admin` , then select **Select**.
21. (K) Select **Save**.
22. Sign in to Coherent Spark with your test account. Select your initials and hover over the groups icon to confirm your membership in `tenant-admin`.
23. We highly recommend creating at least a few additional app groups relevant for [Private tenant](https://docs.coherent.global/tenant-administration/private-tenant)s:
    * Group for `supervisor:pf` user accounts. In Spark, `supervisor:pf` members can manage permissions across all folders.
    * Groups for "standard" user accounts, e.g. `user:teamA`, `user:teamB`. These groups can be assigned to the users in your organization not responsible for tenant administration. Creating multiple roles for "standard" user accounts can be useful to separate access between teams.

### Map Entra ID groups to Spark user groups

{% hint style="info" %}
Optional if Entra ID is not the source of truth for group membership.
{% endhint %}

{% hint style="info" %}
Do not configure a mapper for the `user:pf` group. This is the default minimal Spark group that users must belong to in order to sign in to Spark. Configuring a mapper for this group unnecessarily duplicates sign-in permission management already controlled by your Identity Provider.
{% endhint %}

It is recommended to use two separate browser tabs for the Azure and Keycloak portals to make it easier to apply the settings. In this guide, we will set up the automatic roles for the `tenant-admin` role.

1. (A) In the first tab sign in to [Azure Portal](https://portal.azure.com).
2. (A) Search for and select **Microsoft Entra ID***.*
3. (A) Select App registrations, then select the application you previously created and select **Token Configuration**.
4. (A) Select **Add groups claim**.
5. (A) Select the group types you want to include.
   * Note: If you have users who are members of more than `150` groups, please select the option: **Groups assigned to the application**. This is recommended for large enterprises to avoid exceeding the limit on the number of groups a token can emit. Additionally, ensure that you add the necessary groups as members to the application you previously created.
6. (A) Expand the SAML section, select **Group ID** and select **Save**.
7. (A) On the left pane select **Groups**.
8. (A) Create or search for your Spark `tenant-admin` group.
9. (A) Ensure your test account is a member of the group and copy the object ID of the group.
10. (K) Open a new tab in your browser and sign in to the target Spark tenant. Access the **Keycloak console** from the [Navigation menu](/navigation/navigation-menu.md#user-menu).
11. (K) Select **Identity Providers** from the left pane and then the identity provider you configured in the previous section.
12. (K) Select the **Mappers** tab and then **Add mapper**.
13. (K) Provide the following values.

    | Name                   | Value                         |
    | ---------------------- | ----------------------------- |
    | **Name**               | `tenant-admin`                |
    | **Sync mode override** | `force`                       |
    | **Mapper type**        | `Advanced Attribute to Group` |
14. (K) Select **Add Claims**.
15. (K) Provide the following values:

    | Key                                                              | Value                       |
    | ---------------------------------------------------------------- | --------------------------- |
    | `http://schemas.microsoft.com/ws/2008/06/identity/claims/groups` | Group object ID from Step 9 |
16. (K) Leave *Regex Claim Values* as *Off* (which is the default).
17. (K) Select **Select Group***,* choose `tenant-admin` , then select **Select**.
18. (K) Select **Save**.
19. Sign in into Coherent Spark with your test account. Select your initials and hover over the groups icon to confirm your membership in `tenant-admin`.
20. We highly recommend creating at least a few additional app groups relevant for [Private tenant](https://docs.coherent.global/tenant-administration/private-tenant)s:
    * Group for `supervisor:pf` user accounts. In Spark, `supervisor:pf` members can manage permissions across all folders.
    * Groups for "standard" user accounts, e.g. `user:teamA`, `user:teamB`. These groups can be assigned to the users in your organization not responsible for tenant administration. Creating multiple roles for "standard" user accounts can be useful to separate access between teams.

## Enable SAML assertion encryption - Advanced

The following steps configure:

* Keycloak to generate an RSA encryption keypair and accept encrypted SAML assertions.
* Microsoft Entra ID to encrypt SAML assertions using Keycloak’s certificate.

### Configure Keycloak for SAML assertion decryption

#### Create an RSA encryption key

1. In **Keycloak**, open your realm, for example `mytenant`.
2. Select **Realm Settings** → **Keys** (left panel).
3. Select **Add provider**.
4. Choose **rsa-enc-generated** from the list.
5. Fill in the following fields:

   | Key           | Value                |
   | ------------- | -------------------- |
   | **Name**      | Any descriptive name |
   | **Priority**  | `100`                |
   | **Enabled**   | `On`                 |
   | **Active**    | `On`                 |
   | **Key size**  | `2048`               |
   | **Algorithm** | `RSA-OAEP`           |
6. Select **Save**.

#### Export the public certificate

1. Go back to the **Keys list** tab.
2. Locate the newly created rsa-enc-generated key (Provider = Name).
3. Select **Certificate**.
4. Copy the entire certificate text and save it as a `.cer` file, for example `keycloak-saml-encryption.cer`.

#### Enable assertion encryption on the SAML Identity Provider

1. In the left navigation, select **Identity Providers.**
2. Select your previously configured Microsoft Entra SAML provider.
3. Scroll down to the **SAML Settings** section.
4. Apply the following settings:

   | Key                           | Value      |
   | ----------------------------- | ---------- |
   | **Want Assertions Encrypted** | `On`       |
   | **Encryption Algorithm**      | `RSA-OAEP` |
5. Select **Save**.

### Configure Microsoft Entra ID to encrypt SAML tokens

1. In the Microsoft Entra admin center, open your Enterprise Application (the SAML app pointing to Keycloak).
2. In the left menu, under *Security*, select **Token encryption**.
3. Select **Import certificate** and upload the `.cer` file you exported from Keycloak.
4. After the certificate appears in the list, select the ellipsis menu next to the certificate and select **Activate Token Encryption Certificate**.

## Enforce SAML request signing and certificate validation - Advanced

### Enable Keycloak to sign SAML requests

#### Export the Keycloak Signing Certificate

1. In Keycloak, open your realm (e.g., `mytenant`).
2. Select **Realm Settings** → **Keys** → **Key List**.
3. Locate the key with:

   | Key       | Value   |
   | --------- | ------- |
   | Algorithm | `RS256` |
   | Type      | `RSA`   |
   | Use       | `SIG`   |
4. Select **Certificate**.
5. Copy the full certificate text and save it as a `.cer` file, e.g. `keycloak-saml-sig.cer`.

#### Enable signed AuthnRequests in Keycloak

1. Go to **Identity Providers** in the left pane.
2. Select your Microsoft Entra SAML provider.
3. Scroll to the SAML Settings section.
4. Apply the following settings:

   | Key                           | Value        |
   | ----------------------------- | ------------ |
   | **Want AuthnRequests Signed** | `On`         |
   | **Signature Algorithm**       | `RSA_SHA256` |
   | **SAML Signature Key Name**   | `KEY_ID`     |
   | **Want Assertions Signed**    | `On`         |
5. Select **Save**.

### Configure Microsoft Entra ID to verify the certificate

#### Upload the Keycloak Signing Certificate in Entra

1. In the Microsoft Entra admin center, open your enterprise application (the SAML app pointing to Keycloak).
2. Go to Single sign-on, scroll to **SAML Certificates**, and open **Verification certificates (optional)**.
3. Check:
   1. **Require verification certificates** is `Enabled`.
   2. **Allow requests signed with RSA-SHA1** is checked (optional fallback).
4. Upload the `.cer` file you exported from Keycloak earlier.
5. Select **Save**.

## Enable privileged identity management (PIM)

See [Microsoft Entra ID privileged identity management (PIM)](/identity-and-access-management/single-sign-on/microsoft-entra-id-privileged-identity-management-pim.md).

## Create an enterprise application for Coherent Spark

See [Microsoft Apps](/identity-and-access-management/single-sign-on/microsoft-apps.md).
