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

# Setting up Microsoft Entra

> Step-by-step guide to configure Microsoft Entra ID (Azure AD) as your identity provider for Bifrost Enterprise SSO authentication.

## Overview

This guide walks you through configuring Microsoft Entra ID (formerly Azure Active Directory) as your identity provider for Bifrost Enterprise. After completing this setup, your users will be able to sign in to Bifrost using their Microsoft credentials, with roles and team memberships automatically synchronized.

## Prerequisites

* A Microsoft Azure account with access to Entra ID (Azure AD)
* Admin access to create app registrations
* Bifrost Enterprise deployed and accessible
* The redirect URI for your Bifrost instance (e.g., `https://your-bifrost-domain.com/login`)

***

## Step 1: Register an Application

1. Sign in to the [Azure Portal](https://portal.azure.com)
2. Navigate to **Microsoft Entra ID** (or **Azure Active Directory**)
3. Go to **App registrations**
4. Click **New registration**

Configure the registration:

| Field                       | Value                                                          |
| --------------------------- | -------------------------------------------------------------- |
| **Name**                    | Bifrost Enterprise                                             |
| **Supported account types** | Accounts in this organizational directory only (Single tenant) |
| **Redirect URI**            | Web: `https://your-bifrost-domain.com/login`                   |

5. Click **Register**

<Tip>
  You can add an app icon to make the application easily recognizable. The Bifrost logo is available at:
  [https://www.getmaxim.ai/bifrost/bifrost-logo-only.png](https://www.getmaxim.ai/bifrost/bifrost-logo-only.png)
</Tip>

### Enable assignment requirement on the Enterprise Application

This step controls which users can access Bifrost. The toggle lives on the **Enterprise Application**, which is a different blade from the **App Registration** you just created (both share the same app name and Application ID, but they are separate entries in the Entra ID left navigation).

1. From the Entra ID main menu, go to **Enterprise applications**
2. Find and select **Bifrost Enterprise** (the service principal created automatically when you registered the app above)
3. Go to **Properties**

<Frame>
  <img src="https://mintcdn.com/bifrost/81g5ib9Jdgu71153/media/user-provisioning/entra-enable-assignment.png?fit=max&auto=format&n=81g5ib9Jdgu71153&q=85&s=6498d6d325a8a19f2f15d03ef0a69154" alt="Entra Enterprise Application Properties" width="2896" height="2428" data-path="media/user-provisioning/entra-enable-assignment.png" />
</Frame>

4. Set **Assignment required?** to **Yes**
5. Set **Enabled for users to sign-in?** to **Yes**
6. Click **Save**

***

## Step 2: Capture App Registration Information

Navigate to **Entra Home → App Registrations → \<your app name> → Overview** to capture the values below.

<Frame>
  <img src="https://mintcdn.com/bifrost/dz99ORrLhBK1BnEd/media/user-provisioning/entra-app-information.png?fit=max&auto=format&n=dz99ORrLhBK1BnEd&q=85&s=95b12a3d0c1f1748491897cf0cda033d" alt="Entra App Registration Overview" width="4686" height="2570" data-path="media/user-provisioning/entra-app-information.png" />
</Frame>

| Value                       | Where to Find         |
| --------------------------- | --------------------- |
| **Application (client) ID** | Overview → Essentials |
| **Directory (tenant) ID**   | Overview → Essentials |

## Step 3: Create App Roles (Optional)

<Note>
  This step is optional. You can create custom roles if that's the preferred way. Or you can map any attribute to role/team/business unit.
  Role mapping is a required step.
</Note>

Configure roles in Entra that map to Bifrost's role hierarchy (Admin, Developer, Viewer).

1. In your app registration, go to **App roles**
2. Click **Create app role**
3. Create the following three roles:

<Frame>
  <img src="https://mintcdn.com/bifrost/uNN-IjBaT-ndAUVL/media/user-provisioning/entra-create-app-roles.png?fit=max&auto=format&n=uNN-IjBaT-ndAUVL&q=85&s=8452f0ab6cc3172347e9265f97f2ab70" alt="Entra App Roles configuration" width="4006" height="2039" data-path="media/user-provisioning/entra-create-app-roles.png" />
</Frame>

### Viewer Role

| Field                    | Value                  |
| ------------------------ | ---------------------- |
| **Display name**         | Viewer                 |
| **Allowed member types** | Users/Groups           |
| **Value**                | `viewer`               |
| **Description**          | Viewer role on Bifrost |
| **State**                | Enabled                |

### Developer Role

| Field                    | Value                     |
| ------------------------ | ------------------------- |
| **Display name**         | Developer                 |
| **Allowed member types** | Users/Groups              |
| **Value**                | `developer`               |
| **Description**          | Developer role on Bifrost |
| **State**                | Enabled                   |

### Admin Role

| Field                    | Value                 |
| ------------------------ | --------------------- |
| **Display name**         | Admin                 |
| **Allowed member types** | Users/Groups          |
| **Value**                | `admin`               |
| **Description**          | Admin role on Bifrost |
| **State**                | Enabled               |

***

## Step 4: Create a Client Secret

Bifrost requires a client secret for OAuth authentication.

1. Go back to **App registrations** → **Bifrost Enterprise**
2. Navigate to **Certificates & secrets**
3. Click **New client secret**

<Frame>
  <img src="https://mintcdn.com/bifrost/81g5ib9Jdgu71153/media/user-provisioning/entra-create-client-secret.png?fit=max&auto=format&n=81g5ib9Jdgu71153&q=85&s=38f5c6e9884fc89fefb33e63e5a3b3a8" alt="Entra Enterprise Client Secrets" width="3710" height="1966" data-path="media/user-provisioning/entra-create-client-secret.png" />
</Frame>

| Field           | Value                                                  |
| --------------- | ------------------------------------------------------ |
| **Description** | Bifrost Enterprise Secret                              |
| **Expires**     | Choose based on your security policy (e.g., 24 months) |

4. Click **Add**
5. **Copy the secret value immediately** - it won't be shown again!

<Warning>Store the client secret securely. You'll need it for the Bifrost configuration.</Warning>

***

## Step 5: Configure API Permissions

Ensure your application has the necessary permissions.

<Frame>
  <img src="https://mintcdn.com/bifrost/81g5ib9Jdgu71153/media/user-provisioning/entra-api-permissions.png?fit=max&auto=format&n=81g5ib9Jdgu71153&q=85&s=56c69fa20de78dd4d412f429974e4b19" alt="Entra Enterprise API Permissions" width="3948" height="2064" data-path="media/user-provisioning/entra-api-permissions.png" />
</Frame>

1. In your app registration, go to **API permissions**

2. Click **Add a permission**

3. Select **Microsoft Graph**

4. Choose the permission type as indicated in the next steps

5. Add the following **Delegated** permissions (Add a permission → Microsoft Graph → **Delegated permissions**):
   * `openid`
   * `profile`
   * `email`
   * `offline_access` (for refresh tokens)
   * `User.Read`

6. Add the following **Application** permissions (Add a permission → Microsoft Graph → **Application permissions**):
   * `User.Read.All`
   * `GroupMember.Read.All`
   * `Group.Read.All`
   * `Application.Read.All` — required for syncing app-role-based role mappings during user import. If you don't want to do bulk syncing, you can skip this permission.
   * `AppRoleAssignment.ReadWrite.All` — required to read each user's app role assignments via Microsoft Graph

<Warning>
  Permission **type** matters: `openid`, `profile`, `email`, `offline_access`,
  and `User.Read` must be **Delegated**, while `User.Read.All`,
  `GroupMember.Read.All`, `Group.Read.All`, `Application.Read.All`, and
  `AppRoleAssignment.ReadWrite.All` must be **Application**. The same name can
  exist under both types — adding the wrong one will cause sign-in or sync
  failures even though the permission appears granted.
</Warning>

7. Click **Add permissions**
8. Click **Grant admin consent for \[Your Organization]** (this is required — without admin consent, Application permissions are not effective even though they appear in the list)

<Note>
  `Application.Read.All` and `AppRoleAssignment.ReadWrite.All` are only needed if you plan to use **app role based role mappings** (i.e.
  mappings whose attribute is `roles`) during the bulk user sync. Login-time role mapping works from the JWT alone, but bulk sync from
  Microsoft Graph needs these permissions to read each user's app-role assignments and resolve them to their role values (e.g. `admin`,
  `developer`).
</Note>

***

## Step 6: Configure Token Claims

<Note>Groups and other attributes are required in the claim when you configure their mapping in Bifrost.</Note>

By default, Entra includes the `roles` claim when app roles are assigned. To include group memberships for team synchronization:

1. Go to **Token configuration**
2. Click **Add groups claim**
3. Select:
   * **Security groups** or **Groups assigned to the application**
   * For token type, enable **ID** and **Access**
4. Click **Add**

***

## Step 7: Assign Users and Roles

<Frame>
  <img src="https://mintcdn.com/bifrost/81g5ib9Jdgu71153/media/user-provisioning/entra-user-assignments.png?fit=max&auto=format&n=81g5ib9Jdgu71153&q=85&s=01726e04c0f87dd6a364e988bf3c867e" alt="Entra User Assignments" width="4552" height="2574" data-path="media/user-provisioning/entra-user-assignments.png" />
</Frame>

1. Go to **Enterprise applications** → **Bifrost Enterprise**
2. Navigate to **Users and groups**
3. Click **Add user/group**
4. Select users or groups
5. Select the appropriate role (Admin, Developer, or Viewer)
6. Click **Assign**

<Warning>
  You **must** select a role when assigning a user or group. Adding a user to the application without picking a role causes Entra to omit
  the `roles` claim from the issued ID token, and login will be rejected with `Claim "roles" is not present in the token`. If you don't want
  to use app roles, configure your Bifrost role mappings on the `groups` attribute instead (see [Attribute Mappings](#attribute-mappings)
  below).
</Warning>

<Tip>
  You can assign roles to groups for easier management. All users in a group will inherit the assigned role. The group itself must be added
  as an assignment with a role selected — adding users to a group that isn't assigned to the application will not propagate roles.
</Tip>

***

## Step 8: Configure App Manifest

<Frame>
  <img src="https://mintcdn.com/bifrost/DI7XIVV33XNLaXJJ/media/user-provisioning/entra-app-manifest.png?fit=max&auto=format&n=DI7XIVV33XNLaXJJ&q=85&s=5e8d961ba35ff5c567e890f1ebb77627" alt="Microsoft entra app manifest" width="3470" height="2270" data-path="media/user-provisioning/entra-app-manifest.png" />
</Frame>

You will need to make the following changes in the app manifest.

Set the access token version to v2.

For the **Microsoft Graph App Manifest** (current schema, default in the Azure Portal "Manifest" blade for app registrations created or migrated after the 2023 redesign):

```json theme={null}
"requestedAccessTokenVersion": 2
```

For the **AAD Graph App Manifest** (legacy schema, deprecated; only present on older app registrations that have not been migrated):

```json theme={null}
"accessTokenAcceptedVersion": 2
```

Add the optional `roles` and `groups` claims to the ID token:

```json theme={null}
"optionalClaims": {
  "idToken": [
    {
      "name": "roles",
      "source": null,
      "essential": false,
      "additionalProperties": []
    },
    {
      "name": "groups",
      "source": null,
      "essential": false,
      "additionalProperties": ["cloud_displayname", "sam_account_name"]
    }
  ],
  "accessToken": [],
  "saml2Token": []
}
```

Restrict the `groups` claim to groups assigned to this application (recommended):

```json theme={null}
"groupMembershipClaims": "ApplicationGroup"
```

<Note>
  Setting `groupMembershipClaims` to `"ApplicationGroup"` ensures the `groups`
  claim only contains groups that are explicitly assigned to the Bifrost
  Enterprise application — not every group the user belongs to tenant-wide.
  This keeps your team and role mappings predictable and avoids leaking
  unrelated group memberships into the token. Use `"SecurityGroup"` or
  `"All"` only if you intentionally want broader group visibility.
</Note>

## Step 9: Configure Bifrost

Now configure Bifrost to use Microsoft Entra as the identity provider.

### Using the Bifrost UI

<Frame>
  <img src="https://mintcdn.com/bifrost/DI7XIVV33XNLaXJJ/media/user-provisioning/entra-form.png?fit=max&auto=format&n=DI7XIVV33XNLaXJJ&q=85&s=594aeba6024dfe02d57f3383ff688a7c" alt="Create token dialog in Entra" width="2720" height="4671" data-path="media/user-provisioning/entra-form.png" />
</Frame>

1. Navigate to **Governance** → **User Provisioning** in your Bifrost dashboard
2. Select **Microsoft Entra** as the SCIM Provider
3. Enter the following configuration:

| Field             | Value                                            |
| ----------------- | ------------------------------------------------ |
| **Client ID**     | Application (client) ID from Azure               |
| **Tenant ID**     | Directory (tenant) ID from Azure                 |
| **Client Secret** | The secret you created in Step 4                 |
| **Audience**      | Your Client ID (optional, defaults to Client ID) |
| **App ID URI**    | `api://{client-id}` (optional, for v1.0 tokens)  |

5. **Verify** configuration and see if you get any errors. Make sure you get no errors/warnings.
6. Toggle **Enabled** to activate the provider
7. Click **Save Configuration**

<Warning>After saving, you'll need to restart your Bifrost server for the changes to take effect.</Warning>

### Configuration Reference

| Field                           | Required | Description                                                |
| ------------------------------- | -------- | ---------------------------------------------------------- |
| `tenantId`                      | Yes      | Azure Directory (tenant) ID                                |
| `clientId`                      | Yes      | Application (client) ID                                    |
| `clientSecret`                  | Yes      | Client secret for OAuth authentication                     |
| `audience`                      | No       | JWT audience for validation (defaults to clientId)         |
| `attributeRoleMappings`         | Yes      | Ordered list of attribute→role mappings. First match wins. |
| `attributeTeamMappings`         | No       | Attribute→team mappings (all matches apply).               |
| `attributeBusinessUnitMappings` | No       | Attribute→business-unit mappings (all matches apply).      |

***

### Attribute Mappings

Attribute mappings let you translate Entra claim values into Bifrost roles, teams, or business units without restructuring your Okta claims. Bifrost supports three mapping types:

* **`attributeRoleMappings`**: map a claim value to a Bifrost role (Admin, Developer, Viewer, or a custom role)
* **`attributeTeamMappings`**: map a claim value to a Bifrost team
* **`attributeBusinessUnitMappings`**: map a claim value to a Bifrost business unit

These mappings work with any Entra claim - the `groups` claim from Step 6, the app-role `roles` claim from Step 3, or any other claim your authorization server includes in the token (e.g., `department`, `organization`).

To configure attribute mappings:

1. In the User Provisioning configuration, scroll down to **Attribute Mappings**
2. Click **Add Mapping** under the relevant mapping type (Role, Team, or Business Unit)
3. Enter the **Attribute** (the claim name from the token), the **Value** to match, and the target **Role**, **Team**, or **Business Unit**
4. Repeat for each rule you need

<Frame>
  <img src="https://mintcdn.com/bifrost/DI7XIVV33XNLaXJJ/media/user-provisioning/attribute-to-entity-mapping.png?fit=max&auto=format&n=DI7XIVV33XNLaXJJ&q=85&s=1aef784dda8b8e684b2404fdcaf04859" alt="Attribute Mappings configuration in Bifrost" width="1444" height="2524" data-path="media/user-provisioning/attribute-to-entity-mapping.png" />
</Frame>

<Note>When you mark value as "\*" - the claim value is mapped as is to the entity name. Values comparisons are case-insensitive.</Note>

### Custom attribute mapping

You can also map any custom attributes to any entity (role, team or business unit). Make sure these are configured to send back to Bifrost in token configuration.

<Frame>
  <img src="https://mintcdn.com/bifrost/DI7XIVV33XNLaXJJ/media/user-provisioning/custom-attribute-mapping.png?fit=max&auto=format&n=DI7XIVV33XNLaXJJ&q=85&s=e4d0117fb7d9b829d07095ca3163a0c9" alt="Attribute Mappings configuration in Bifrost" width="1639" height="899" data-path="media/user-provisioning/custom-attribute-mapping.png" />
</Frame>

#### Evaluation rules

* **Role mappings**: Ordered, first match wins. If no rule matches, users are not allowed to login into the system.
* **Team and business unit mappings**: All matching rules apply - users can be placed on multiple teams and business units simultaneously.
* **Claim values**: Can be strings, arrays, or nested objects. Bifrost resolves dotted paths (e.g., `realm_access.roles`).

<Note>
  If a user matches multiple role mapping rules, the highest privilege role is assigned. If no mapping matches, the first user to sign in
  receives the **Admin** role, and subsequent users receive the **Viewer** role.
</Note>

5. Click **Save Configuration**

***

## Testing the Integration

1. Open your Bifrost dashboard in a new browser or incognito window
2. You should be redirected to Entra for authentication
3. Log in with an assigned user
4. After successful authentication, you'll be redirected back to Bifrost
5. Verify the user appears in the Bifrost users list with the correct role

***

## Troubleshooting

### User not redirected to Microsoft login

* Verify the SCIM provider is enabled in Bifrost
* Check that the Bifrost server was restarted after configuration
* Ensure the Tenant ID and Client ID are correct

### "AADSTS50011: The reply URL does not match"

* Verify the redirect URI in your app registration exactly matches your Bifrost login URL
* Ensure there are no trailing slashes or protocol mismatches (http vs https)

### "AADSTS7000215: Invalid client secret"

* Regenerate the client secret in Azure
* Ensure you're using the secret **Value**, not the secret ID
* Check for any leading/trailing whitespace when copying

### Token validation errors

* Ensure the Tenant ID matches your Azure directory
* Verify the Client ID is correct
* Check that the app registration is in the same tenant as your users

### `Claim "roles" is not present in the token` on login

This means the user signed in successfully but Entra did not emit a `roles` claim in the ID token. Bifrost rejects the login because none of your role mappings can be evaluated.

Causes and fixes:

* **User isn't assigned to a role at the Enterprise Application level.** Go to **Enterprise applications → Bifrost Enterprise → Users and groups**, edit the assignment, and pick a role (admin/developer/viewer). Adding a user to the app without selecting a role does not emit the `roles` claim.
* **Role assignment is via a group that isn't itself assigned to the app.** The group needs to appear in *Users and groups* with a role selected — Entra does not walk transitive group memberships to populate `roles`.
* **Optional `roles` claim missing from the manifest.** Confirm Step 8 (App Manifest) lists `roles` under `optionalClaims.idToken`.
* **Sign out and back in.** Existing sessions still carry the old token without `roles`.

If you don't want to use app roles at all, switch your Bifrost mappings to use the `groups` attribute (which is already in the token) instead of `roles`. See [Attribute Mappings](#attribute-mappings).

### Bulk user sync assigns Viewer instead of the mapped role

If users come in via **User Provisioning → Import users** and end up on the default role (Viewer) despite having a matching app-role-based mapping configured:

* Confirm the user actually has the app role assigned in Entra (**Enterprise applications → Bifrost Enterprise → Users and groups**).
* Confirm both `Application.Read.All` and `AppRoleAssignment.ReadWrite.All` are granted **with admin consent** in Step 5. Without these, Bifrost cannot read the app role catalog or per-user assignments via Microsoft Graph, so the synthetic `roles` claim used by the importer will be empty.
* Server logs will contain `[ENTRA-ROLES] failed to fetch app role catalog: ... 403` if the permission is missing.

***

## Next Steps

* **[User Provisioning (SCIM)](./user-provisioning)** - Overview of SCIM in Bifrost and alternative identity providers
* **[Advanced Governance](./advanced-governance)** - Learn about user budgets and compliance features
* **[Role-Based Access Control](./advanced-governance#role-hierarchy)** - Understand the Admin, Developer, Viewer hierarchy
* **[Audit Logs](./audit-logs)** - Monitor user authentication and activity
