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

# Microsoft

> Authenticate users via Microsoft Entra ID OAuth 2.0. Covers app registration, tenant configuration for personal or work accounts, and the `microsoft` provider.

## Get credentials

<Steps>
  <Step>
    ### Register an application

    Go to the [Azure Portal](https://portal.azure.com/) and navigate to **Microsoft Entra ID > App registrations > New registration**.

    * **Name**: your app name
    * **Supported account types**: choose based on your needs (see below)
    * **Redirect URI**: Web, `https://auth.example.com/auth/oauth/microsoft/callback`
  </Step>

  <Step>
    ### Create a client secret

    Navigate to **Certificates and secrets > New client secret**. Set an expiry and copy the secret value immediately.
  </Step>

  <Step>
    ### Copy the Application ID

    From the app overview, copy the **Application (client) ID** and the **Directory (tenant) ID**.
  </Step>
</Steps>

## Configuration

<Tabs>
  <Tab title="Personal + work accounts">
    ```typescript title="lib/kavach.ts" theme={"system"}
    import { createKavach } from 'kavachos';
    import { oauth } from 'kavachos/auth';

    const kavach = await createKavach({
      database: { provider: 'postgres', url: process.env.DATABASE_URL! },
      secret: process.env.KAVACH_SECRET!,
      baseUrl: 'https://auth.example.com',
      plugins: [
        oauth({
          providers: [
            {
              id: 'microsoft', // [!code highlight]
              clientId: process.env.MICROSOFT_CLIENT_ID!, // [!code highlight]
              clientSecret: process.env.MICROSOFT_CLIENT_SECRET!, // [!code highlight]
              // tenant: 'common' is the default. Accepts personal and work accounts.
            },
          ],
        }),
      ],
    });
    ```
  </Tab>

  <Tab title="Work accounts only (single tenant)">
    ```typescript title="lib/kavach.ts" theme={"system"}
    oauth({
      providers: [
        {
          id: 'microsoft',
          clientId: process.env.MICROSOFT_CLIENT_ID!,
          clientSecret: process.env.MICROSOFT_CLIENT_SECRET!,
          tenant: process.env.MICROSOFT_TENANT_ID!, // Your directory (tenant) ID // [!code highlight]
        },
      ],
    })
    ```
  </Tab>
</Tabs>

```bash theme={"system"}
MICROSOFT_CLIENT_ID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
MICROSOFT_CLIENT_SECRET=...
MICROSOFT_TENANT_ID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx  # only for single-tenant
```

## Account types and tenant

The `tenant` option maps to the Microsoft authority URL:

| Value              | Who can sign in                                      |
| ------------------ | ---------------------------------------------------- |
| `common` (default) | Personal Microsoft accounts and work/school accounts |
| `organizations`    | Work and school accounts only                        |
| `consumers`        | Personal Microsoft accounts only                     |
| Your tenant ID     | Only users in your Azure AD directory                |

## Scopes

Default scopes: `openid email profile User.Read`

| Scope                  | What it unlocks                                 |
| ---------------------- | ----------------------------------------------- |
| `openid email profile` | Standard OIDC identity                          |
| `User.Read`            | Read the signed-in user's profile from MS Graph |
| `Calendars.Read`       | Read calendar events                            |
| `Mail.Read`            | Read email                                      |

## User data returned

| Field   | Source                          | Notes                                 |
| ------- | ------------------------------- | ------------------------------------- |
| `id`    | `oid` claim                     | Stable object ID within the tenant    |
| `email` | `email` or `preferred_username` | Work email or Microsoft account email |
| `name`  | `name` claim                    | Display name                          |
| `image` | MS Graph `/me/photo`            | Fetched separately; may be absent     |

<Info>
  Personal Microsoft account profile photos require an additional Graph API call with `User.Read` scope. Work account photos may be restricted by IT policy.
</Info>
