---
title: "LibreChat OpenID / Azure AD Auth Internals"
aliases: [librechat-auth, librechat-openid, librechat-oauth]
tags: [librechat, azure-ad, oauth, openid, debugging]
sources:
  - "daily/2026-04-15.md"
created: 2026-04-15
updated: 2026-04-15
---

# LibreChat OpenID / Azure AD Auth Internals

LibreChat v0.8.4 has specific requirements for OpenID/OAuth users that are not obvious from configuration alone. The interaction between `ALLOW_SOCIAL_REGISTRATION`, MongoDB user records, and session cookies creates multiple silent failure points.

## Key Points

- `ALLOW_SOCIAL_REGISTRATION=false` means LibreChat checks for an existing user with `openidId` populated — a manually inserted MongoDB record without `openidId` is not recognized
- `Unknown OAuth error` in LibreChat logs means `req.session?.messages` is empty — the real error happened earlier in the session/state layer, before the verify callback
- OAuth state mismatch can occur client-side if the session cookie from a previous attempt is stale after a server restart
- The Network tab flow for a failing auth: `302 → /oauth/openid → Microsoft OK → /oauth/callback → /oauth/error`
- Always get a screenshot or Network tab capture from the user first — it identifies whether Microsoft auth succeeds before investing time in server logs

## Details

### ALLOW_SOCIAL_REGISTRATION and openidId

When `ALLOW_SOCIAL_REGISTRATION=false`, LibreChat requires the user to already exist in MongoDB **with** the `openidId` field populated. Adding a user document manually (e.g., copying another user's record) does not work unless the `openidId` field contains the correct Azure AD object ID. The check order is: look up by `openidId` → if not found, registration is blocked → auth fails.

Setting `ALLOW_SOCIAL_REGISTRATION=true` temporarily lets the user complete the flow and have `openidId` saved automatically. After the user registers, set it back to `false` and the user will be recognized on subsequent logins.

### OAuth State Mismatch

`Unknown OAuth error` in LibreChat server logs maps to the passport.js behavior where `req.session?.messages` is empty — this means state validation failed before the verify callback even ran. The likely causes:

1. **Stale session cookie** — if the server restarted between when the user clicked "Login" and when Microsoft redirected back, the session store no longer has the original OAuth state. The callback `state` parameter doesn't match anything in the session → validation fails.
2. **Browser privacy settings or proxies** — if the session cookie is not sent on the callback request (third-party cookie blocking, network proxy stripping cookies), the session lookup fails silently.

The diagnosis path: confirm Microsoft authentication *succeeds* (user sees Microsoft login page and approves) → check if redirect goes to `/oauth/callback` or directly to `/oauth/error`. If it goes to `/oauth/error`, the issue is in LibreChat's session layer, not in Azure AD.

### Diagnosis Order

1. Ask user for a Network tab screenshot first — identifies where the 302 chain breaks
2. Check server logs for `Unknown OAuth error` vs a specific passport error message
3. Check MongoDB for the user document and whether `openidId` is present
4. Try from a different browser / private window to rule out stale cookies

## Related Concepts

- [[wiki/tech-patterns/azure-ad-msal-auth]] — Azure AD app registration and PKCE configuration
- [[wiki/concepts/msal-vanilla-js-pkce]] — SPA-specific Azure AD OAuth patterns
- [[wiki/concepts/oauth-state-mismatch-debugging]] — broader OAuth state debugging patterns

## Sources

- [[daily/2026-04-15.md]] — LibreChat debugging session for user `santhosha.nayak@brandtech.plus` on `chat-sandbox.oliver.solutions`
