Skip to main content
Purpose: Complete guide for setting up Microsoft Entra ID/Office 365 integration for PF-63. Status: ✅ Setup Complete (2026-01-28)

Quick Start (5 Minutes)

Prerequisites

  • Azure CLI installed (az --version works)
  • Azure account with Global Administrator or Application Administrator role
  • Supabase project linked (npx supabase link --project-ref anuwknikgsijbameytzr)
  • Supabase CLI available (via npx supabase)

Automated Setup

Windows:
Linux/macOS:
Or use npm script:
The script will:
  1. Create app registration
  2. Add API permissions
  3. Generate client secret (save it when shown!)
  4. Store secrets in Supabase
  5. Generate admin consent URL
  6. Create setup log

Manual Setup Steps

Step 1: Login to Azure

Verify:
Save the tenant ID - you’ll need it.

Step 2: Create App Registration

Capture the appId (Client ID) from the output.

Step 3: Add API Permissions

Permissions:
  • df021288-bdef-4463-88db-98f22de89214 = User.ReadWrite.All (Application) — also covers license assignment per Microsoft Graph (assignLicense accepts User.ReadWrite.All as higher-privileged alternative)
Multi-tenant SaaS: Use AzureADMultipleOrgs for the shared Encore app. Grant admin consent per customer tenant via tenant=organizations (see Step 6). The full 18-scope catalog lives in src/platform/integrations/entra-permissions.ts and REQUIRED_GRAPH_SCOPES in supabase/functions/_shared/entra-client.ts.

Step 4: Create Client Secret

⚠️ CRITICAL: Capture the password value immediately - it’s only shown once!

Step 5: Store Secrets in Supabase

Generate the admin consent URL:
Visit the URL and grant admin consent. You’ll be redirected to the callback handler which will display a success message.
v2 admin consent (current): Encore now uses the Microsoft identity platform v2 endpoint with scope=https://graph.microsoft.com/.default:
For guided setup when the tenant ID is unknown, use tenant=organizations so a Microsoft administrator signs in and grants consent for their directory. The callback verifies consent by acquiring a Graph token (authoritative tid claim) and caches verified domains.


Tenant admin workflow (in Encore — no Supabase access)

Organization admins complete Microsoft integration entirely in the app:
  1. Settings → Integrations → Microsoft Entra ID → Guided setup
  2. Choose Encore shared app (recommended) or bring your own app registration
  3. Enter primary email domain
  4. Consent as Microsoft administrator (organization-wide admin consent)
  5. Run connection test — verifies Graph token, caches verified domains, and pins the client secret to your organization vault (shared app)
  6. Optionally enable Microsoft sign-in in the wizard or under Settings → Single Sign-On
Permission counts in the UI reflect live token roles (N of 18 granted), not a static catalog. If fewer than 18 appear, the shared Entra app registration may need additional application permissions (platform operator task).

Platform operator workflow (Encore / Supabase — not shown to tenants)

Performed once per Supabase project by Encore platform operators: Tenant admins never see Supabase Dashboard steps. The in-app SSO toggle is enabled when the tenant is connected, verified domains are cached, and ENTRA_SSO_PLATFORM_READY is set.

Supabase Azure Provider Checklist (PF-112 Login SSO — platform operators only)

Staff Microsoft sign-in uses Supabase Auth signInWithOAuth({ provider: 'azure' }) against the same Entra app. In addition to application permissions (Graph provisioning), configure:

1. Redirect URI on the Entra app registration

Register the Supabase Auth callback (not the edge-function consent callback):
Example (dev2): https://anuwknikgsijbameytzr.supabase.co/auth/v1/callback Configure this in Supabase Dashboard → Authentication → Providers → Azure and on the Entra app Authentication → Redirect URIs.

2. Optional claims in the app manifest

Required for the OIDC verified-email gate (pf_sso_match_current_user rejects identities without xms_edov):

3. Delegated sign-in scopes (admin-consented)

Add and admin-consent these delegated Microsoft Graph permissions on the app registration so user sign-in works in tenants that disable user consent: Application permissions alone (client-credentials) do not cover user OAuth sign-in.

4. Supabase Auth Azure provider tenant (multi-tenant)

Set Tenant URL to organizations (not a single tenant GUID). This allows staff from any customer tenant that has admin-consented the shared app to complete OIDC login; pf_sso_match_current_user() still binds each session to the correct org via tid + verified domain.

5. Encore-side prerequisites

6. Gate audit markers (server-side)

Failed OIDC logins are audited without exposing details to the user:

Current Configuration (NorthSight dev2 — 2026-06-18)

Retired: production project anuwknikgsijbameytzr redirect URIs remain on the Entra app for legacy reference but are superseded by dev2 URLs above.

Historical Configuration (retired dev project)


Verification Checklist

Before starting implementation, verify:
  • Azure CLI installed and working
  • Logged in to Azure CLI
  • App registration created successfully
  • API permissions added (User.ReadWrite.All — 18-scope catalog on shared app)
  • Client secret created and captured
  • Secrets stored in Supabase
  • Admin consent URL generated
  • Callback handler deployed (entra-oauth edge function)
  • Public access configured (verify_jwt = false in config.toml)
  • Admin consent granted

Troubleshooting

”Insufficient privileges”

  • Solution: Ensure user has Global Administrator or Application Administrator role

”App registration not found”

  • Solution: Verify APP_ID is correct, check with az ad app list --display-name "Encore OS*"

”Permission not found”

  • Solution: Verify permission IDs are correct, check Microsoft Graph API permission reference

”Client secret not shown”

  • Solution: Secret is only shown once. If lost, create new secret with az ad app credential reset

”Missing authorization header” (401 error)

  • Solution: Ensure verify_jwt = false is set in supabase/config.toml for entra-oauth function

Security Notes

  1. Client Secret: Only shown once during creation - save immediately
  2. Storage: For testing, use Supabase secrets. For production, will use per-organization Vault storage
  3. Documentation: Never commit client secrets to git
  4. Rotation: Client secrets expire in 2 years - plan rotation before expiration

  • Gap Analysis: archived at docs/archive/integrations/ENTRA_ID_GAP_ANALYSIS.md (superseded by PF-63 implementation)
  • Research Findings: ENTRA_ID_RESEARCH_FINDINGS.md
  • Overview: ENTRA_ID_OVERVIEW.md
  • Specification: specs/pf/specs/PF-63-entra-id-integration.md
  • Implementation Plan: specs/pf/plans/PF-63-entra-id-integration-PLAN.md
  • Tasks: specs/pf/tasks/PF-63-TASKS.md

Last Updated: 2026-06-18
Status: ✅ NorthSight dev2 end-to-end verified (provisioning + SSO config; interactive Microsoft login hand-tested separately)