Providers
Microsoft Provider
Configure Microsoft OAuth with Keyloom using Azure AD. Complete Azure app registration, scopes, tenant configuration, and troubleshooting.
Microsoft Provider
Add Microsoft OAuth to your Keyloom app using Azure Active Directory (Azure AD). This guide covers Azure app registration and configuration.
Prerequisites
- Microsoft account with Azure AD access
- Keyloom app with
@keyloom/providersinstalled - Public app URL for callback configuration
Azure AD app registration
1. Create App Registration
- Go to Azure Portal
- Navigate to Azure Active Directory → App registrations
- Click "New registration"
- Configure:
- Name: Your application name
- Supported account types: Choose based on your needs:
- "Accounts in this organizational directory only" (single tenant)
- "Accounts in any organizational directory" (multi-tenant)
- "Accounts in any organizational directory and personal Microsoft accounts" (most common)
- Redirect URI: Web →
https://yourapp.com/api/auth/oauth/microsoft/callback
2. Configure Authentication
- In your app registration, go to Authentication
- Add additional redirect URIs if needed:
- Development:
http://localhost:3000/api/auth/oauth/microsoft/callback - Production:
https://yourapp.com/api/auth/oauth/microsoft/callback
- Development:
- Under "Implicit grant and hybrid flows":
- Enable "ID tokens" if using OpenID Connect
- Set "Supported account types" as needed
3. Create Client Secret
- Go to Certificates & secrets
- Click "New client secret"
- Configure:
- Description: "Keyloom OAuth Secret"
- Expires: Choose appropriate duration (24 months recommended)
- Copy the Value (not the Secret ID)
4. Configure API Permissions
- Go to API permissions
- Default permissions include:
- Microsoft Graph → User.Read (delegated)
- Add additional permissions if needed:
profile- Basic profile informationemail- Email addressopenid- OpenID Connect sign-in
5. Get Application Details
From the Overview page, note:
- Application (client) ID
- Directory (tenant) ID (if single tenant)
Environment variables
MICROSOFT_CLIENT_ID=12345678-1234-1234-1234-123456789012
MICROSOFT_CLIENT_SECRET=abcdefghijklmnopqrstuvwxyz123456789012345
MICROSOFT_TENANT_ID=87654321-4321-4321-4321-210987654321
NEXT_PUBLIC_APP_URL=https://yourapp.comProvider configuration
Multi-tenant (common)
import { defineKeyloom } from "@keyloom/core";
import { microsoft } from "@keyloom/providers";
export default defineKeyloom({
baseUrl: process.env.NEXT_PUBLIC_APP_URL!,
providers: [
microsoft({
clientId: process.env.MICROSOFT_CLIENT_ID!,
clientSecret: process.env.MICROSOFT_CLIENT_SECRET!,
// Multi-tenant: accepts any Azure AD tenant
tenant: "common",
scopes: ["openid", "profile", "email"],
}),
],
// ... rest of config
});Single tenant
import { defineKeyloom } from "@keyloom/core";
import { microsoft } from "@keyloom/providers";
export default defineKeyloom({
baseUrl: process.env.NEXT_PUBLIC_APP_URL!,
providers: [
microsoft({
clientId: process.env.MICROSOFT_CLIENT_ID!,
clientSecret: process.env.MICROSOFT_CLIENT_SECRET!,
// Single tenant: specific tenant ID
tenant: process.env.MICROSOFT_TENANT_ID!,
scopes: ["openid", "profile", "email"],
}),
],
// ... rest of config
});Recommended scopes
| Scope | Purpose | Required |
|---|---|---|
openid | OpenID Connect authentication | Yes |
profile | Basic profile info (name, picture) | Yes |
email | User's email address | Yes |
User.Read | Read user profile via Microsoft Graph | Optional |
offline_access | Refresh tokens | Optional |
Minimal setup: Use openid, profile, and email for basic authentication.
Sign-in UI example
export function SignInWithMicrosoft() {
return (
<a
href="/api/auth/oauth/microsoft/start?callbackUrl=/dashboard"
className="flex items-center gap-2 px-4 py-2 bg-blue-600 text-white rounded"
>
<MicrosoftIcon />
Continue with Microsoft
</a>
);
}User profile mapping
Microsoft returns this profile data:
{
"sub": "12345678-1234-1234-1234-123456789012",
"name": "John Doe",
"given_name": "John",
"family_name": "Doe",
"email": "john.doe@company.com",
"picture": "https://graph.microsoft.com/v1.0/me/photo/$value"
}Keyloom maps it to:
{
id: profile.sub,
email: profile.email,
name: profile.name,
image: profile.picture,
}Tenant configuration
Common (multi-tenant)
- Accepts users from any Azure AD tenant
- Includes personal Microsoft accounts
- Most flexible option
Organizations (multi-tenant, work/school only)
- Accepts users from any Azure AD tenant
- Excludes personal Microsoft accounts
- Good for B2B applications
Specific tenant ID
- Only accepts users from specific tenant
- Most restrictive but most secure
- Good for internal applications
Error handling
Common Microsoft OAuth errors:
invalid_client: Client ID/secret mismatchinvalid_grant: Authorization code expiredunauthorized_client: App not configured for tenantconsent_required: User needs to consent to permissions
// In your error boundary or callback handler
if (error?.code === "oauth_error" && error?.provider === "microsoft") {
switch (error?.details?.error) {
case "invalid_client":
return "Microsoft configuration error. Check client ID and secret.";
case "unauthorized_client":
return "App not authorized for this tenant. Contact administrator.";
case "consent_required":
return "Additional permissions required. Please try again.";
default:
return "Microsoft sign-in failed. Please try again.";
}
}Security considerations
- Client Secret: Store securely; rotate regularly
- Tenant Configuration: Choose appropriate tenant scope
- Permissions: Request minimal scopes needed
- Conditional Access: May require additional authentication factors
Performance tips
- Microsoft OAuth is generally fast and reliable
- Consider caching user profile data
- Use refresh tokens for long-lived sessions if needed
Troubleshooting
Unauthorized client error
- Verify app is registered in correct tenant
- Check supported account types configuration
- Ensure redirect URI matches exactly
Invalid client credentials
- Verify client ID and secret are correct
- Check if client secret has expired
- Ensure secret value (not ID) is used
Consent issues
- Check API permissions in Azure AD
- Verify scopes requested match configured permissions
- Consider admin consent for organizational apps
Redirect URI mismatch
- Must exactly match Azure AD app registration
- Check protocol, domain, and path
- Verify both development and production URLs are registered
See also
- Providers overview: /docs/providers/overview
- Security: /docs/security/overview
- Installation: /docs/getting-started/installation
Next steps
- Test the complete sign-in flow in development
- Configure appropriate tenant settings for your use case
- Set up conditional access policies if needed
How is this guide?