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

# Microsoft

> Configure Microsoft OAuth for your Session application.

This guide walks you through configuring Microsoft as a social login provider for your application.

## Prerequisites

* A [Microsoft Azure](https://portal.azure.com/) account
* Your Microsoft OAuth **Application (client) ID** and **Client Secret**

## Configure Microsoft OAuth

<Steps>
  <Step title="Register an application on Azure">
    1. Go to the [Azure Portal](https://portal.azure.com/)
    2. Navigate to **Microsoft Entra ID** > **App registrations**
    3. Click **New registration**
    4. Enter a name (e.g. "Prelude Session")
    5. Under **Supported account types**, select the option that fits your needs (e.g. "Accounts in any organizational directory and personal Microsoft accounts")
    6. Click **Register**
    7. Copy the **Application (client) ID** — you will need it in the next step
  </Step>

  <Step title="Set the redirect URI">
    1. In your app registration, go to **Manage** > **Authentication**
    2. Click **Add a platform** > **Web**
    3. Enter the following redirect URI:

    ```
    https://${YOUR_CUSTOM_DOMAIN}/v1/session/login/oauth/microsoft/callback
    ```

    Replace `${YOUR_CUSTOM_DOMAIN}` with your [custom domain](/session/documentation/domain-names) (e.g. `session.yourapp.com`).

    4. Click **Configure**

    <Note>
      The redirect URI must match exactly. Make sure there is no trailing slash and that you are using `https`.
    </Note>
  </Step>

  <Step title="Create a client secret">
    1. In your app registration, go to **Certificates & secrets**
    2. Click **New client secret**
    3. Enter a description and select an expiration period
    4. Click **Add**
    5. Copy the **Value** (not the Secret ID) — you will need it in the next step
  </Step>

  <Step title="Enable the xms_edov optional claim (required for account merge)">
    Microsoft does not emit a standard `email_verified` claim and the `email` value in a Microsoft ID token is **not** proof of mailbox ownership — a tenant admin can set any arbitrary email on a user they control. This is the [nOAuth](https://www.descope.com/blog/post/noauth) account-takeover vector.

    Session treats a Microsoft email as verified **only** when the `xms_edov` (Email Domain Owner Verification) optional claim is present and `true`. You must enable this claim in Azure for `allow_email_account_merge` to work with Microsoft; otherwise every Microsoft login is treated as unverified and a new Session user is created on each sign-in instead of merging.

    1. In your app registration, go to **Manage** > **Token configuration**
    2. Click **Add optional claim**
    3. Select **ID** as the token type
    4. Check **email** and **xms\_pdl** (required to trigger `xms_edov` emission), then click **Add**
    5. When prompted, check **Turn on the Microsoft Graph email permission** and confirm
    6. Click **Add optional claim** again, select **ID**, check **xms\_edov**, then click **Add**

    <Note>
      `xms_edov` is issued as `true` when the email's domain is verified by the tenant (enterprise users) or for personal Microsoft accounts where the email was verified at account creation. It is issued as `false` — or omitted entirely — when the email is user-editable or domain ownership cannot be proven.
    </Note>
  </Step>

  <Step title="Create the Microsoft OAuth configuration">
    ```bash theme={null}
    curl -X POST https://api.prelude.dev/v2/session/apps/${APP_ID}/config/login/oauth/microsoft \
      -H "Authorization: Bearer ${MANAGEMENT_API_KEY}" \
      -H "Content-Type: application/json" \
      -d '{
        "client_id": "your-microsoft-client-id",
        "client_secret": "your-microsoft-client-secret",
        "enabled": true,
        "options": {
          "use_email_as_identifier": true,
          "allow_email_account_merge": true
        }
      }'
    ```

    | Field                               | Description                                                                                                                                                                                                                                                                           |
    | ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
    | `client_id`                         | Your Microsoft Application (client) ID.                                                                                                                                                                                                                                               |
    | `client_secret`                     | Your Microsoft client secret value.                                                                                                                                                                                                                                                   |
    | `enabled`                           | Set to `true` to enable Microsoft login.                                                                                                                                                                                                                                              |
    | `options.use_email_as_identifier`   | When `true`, the user's Microsoft email is stored as an email identifier — **only** when the email is verified via `xms_edov`.                                                                                                                                                        |
    | `options.allow_email_account_merge` | When `true`, an incoming Microsoft identity is linked to an existing Session user whose email matches — **only** when the email is verified via `xms_edov`. An unverified email that collides with an existing user is rejected with an `email_in_use` error rather than auto-merged. |
  </Step>
</Steps>

## Security: email verification with Microsoft

Unlike Google and Apple, Microsoft does not guarantee the `email` claim in its ID token is owned by the signed-in user. Any tenant admin can set an arbitrary email on a user in their tenant, and Microsoft does not emit an `email_verified` claim. Session therefore relies on the `xms_edov` optional claim as the sole source of truth for Microsoft email verification:

* `xms_edov` is **present and `true`** → Session treats the Microsoft email as verified. `use_email_as_identifier` and `allow_email_account_merge` apply normally.
* `xms_edov` is `false`, missing, or any other value → Session treats the Microsoft email as **unverified**. No email identifier is stored, no auto-merge happens, and if `allow_email_account_merge` is enabled and the email collides with an existing Session user the flow is rejected with `email_in_use` (protecting against the [nOAuth](https://www.descope.com/blog/post/noauth) takeover vector).

If you skip the `xms_edov` configuration step above, Microsoft sign-in will still work but every Microsoft user will be created as a fresh Session account and email-based account merge will never fire.

### Alternative: verify the email via OTP

When you cannot enable `xms_edov` (e.g. you do not control the Azure app registration), set [`options.verify_email`](/session/documentation/integration-guide/social-login#verify-email-via-otp) to `true` instead. Session will detect the unverified Microsoft email and challenge the user with an email OTP before linking the OAuth identifier — preserving the nOAuth protection while still letting users sign in. This requires `use_email_as_identifier=true` and at least one email OTP login config on the application.

## Update the configuration

To update an existing Microsoft OAuth configuration:

```bash theme={null}
curl -X PUT https://api.prelude.dev/v2/session/apps/${APP_ID}/config/login/oauth/microsoft \
  -H "Authorization: Bearer ${MANAGEMENT_API_KEY}" \
  -H "Content-Type: application/json" \
  -d '{
    "client_id": "your-new-microsoft-client-id",
    "client_secret": "your-new-microsoft-client-secret",
    "enabled": true,
    "options": {
      "use_email_as_identifier": true,
      "allow_email_account_merge": true
    }
  }'
```

## Delete the configuration

To remove Microsoft OAuth from your application:

```bash theme={null}
curl -X DELETE https://api.prelude.dev/v2/session/apps/${APP_ID}/config/login/oauth/microsoft \
  -H "Authorization: Bearer ${MANAGEMENT_API_KEY}"
```

## What's next?

Now that Microsoft OAuth is configured on your backend, integrate the frontend using the [Web Integration](/session/documentation/frontend-sdks/web/social-login) guide.
