obsidian/wiki/tech-patterns/azure-ad-msal-auth.md
2026-04-17 17:32:48 +01:00

4 KiB

title aliases tags sources created updated
Azure AD / MSAL Authentication
azure-ad
msal
sso
pkce
azure-ad
msal
auth
sso
pkce
security
01 Projects/gmal-scope-builder
01 Projects/enterprise-ai-hub-nexus
01 Projects/cinema-studio-pro
01 Projects/modcomms
01 Projects/baic_dashboard
01 Projects/sandbox-notebookllamalm-nextjs
daily/2026-04-15.md
2026-04-15 2026-04-15

Azure AD / MSAL Authentication

Oliver Agency standard SSO. MSAL handles token acquisition; backend validates via Azure AD JWT.

Key Takeaways

  • All Oliver-internal tools requiring login use Azure AD (MSAL)
  • MSAL v5 introduced breaking changes — clearCache() for logout, NOT logout()
  • Send ID token to backend, NOT the Graph access token
  • Use DEV_AUTH_BYPASS=true env var for local dev to skip auth
  • Backend validates via JWTValidator.php (PHP) or Azure AD middleware (Python)
  • PKCE flow is used for SPAs (Enterprise Nexus); standard OAuth2 for server-side

When to Use

Any Oliver internal tool that needs to know who the user is. Skip for pure tools/utilities.

Key Details

Frontend Config

// authConfig.js / authConfig.ts
{
  auth: {
    clientId: process.env.AZURE_CLIENT_ID,
    authority: `https://login.microsoftonline.com/${TENANT_ID}`,
    redirectUri: window.location.origin
  },
  cache: { cacheLocation: "sessionStorage" }
}

Required Env Vars

AZURE_TENANT_ID=
AZURE_CLIENT_ID=
AZURE_CLIENT_SECRET=   # server-side only
DEV_AUTH_BYPASS=true   # local dev only

Scopes

  • M365 integration requires delegated scopes + offline_access (Enterprise Nexus)
  • Graph API access requires explicit scope grants in Azure App Registration

MSAL v5 Breaking Changes

// Old (MSAL v4):
instance.logout()
// New (MSAL v5):
instance.clearCache()

Token Validation (Backend)

  • PHP: JWTValidator.php + AuthMiddleware.php (Cinema Studio Pro)
  • Python: Azure AD middleware checks Bearer token against tenant

Projects Using This Pattern

Gotchas & Lessons

  • MSAL v5 clearCache() not logout() — fix was needed in GMAL (2026-03-30)
  • Send ID token to backend, not Graph access token — GMAL bug fix (2026-03-30)
  • needs_reconsent flag: if Graph token refresh fails, prompt user to re-login (Enterprise Nexus)
  • Azure App Registration must have the delegated scopes explicitly added for M365 features
  • offline_access scope required for refresh token to work (Enterprise Nexus M365)
  • Proactive token refresh needed for long-running Celery jobs (Enterprise Nexus SharePoint sync)
  • SPA platform type is required for PKCE — Azure Portal → Authentication → Platform configurations must be set to "Single-page application", NOT "Web". "Web" expects a client secret; PKCE SPAs don't have one → silent auth failure (2026-04-15)
  • OAuth state mismatch after server restart: session cookie from previous attempt doesn't match new state — always ask user to try different browser before deep-diving Azure config (2026-04-15)