Choose an auth mode (unsecured, magic-link, OIDC, Microsoft Entra) and layer on authorization gates — tenant lock, email-domain allowlist, invite-only, and Entra group/role to admin mapping. Everything is an environment variable.
Authentication is how someone signs in; authorization is whether they're allowed in and what they can do. Both are driven entirely by environment variables, so the same image runs from open local dev to a tenant-locked, Entra-governed production deployment.
AUTH_PROVIDER| Value | Use it for |
|---|---|
unsecured | Local dev only. Auto-signs in a fixed dev user, no email or IdP. Requires ALLOW_UNSECURED_AUTH=true when NODE_ENV=production (the shipped image), or it refuses to start. |
magic-link | Email magic links. Needs an email provider (see EMAIL_PROVIDER). |
oidc | Any standard OpenID Connect provider. |
microsoft-entra | Microsoft Entra ID (Azure AD). The primary enterprise option. |
The unsecured backstop matters: a real deployment can never silently become
open, because unsecured only runs in production when you explicitly set
ALLOW_UNSECURED_AUTH=true.
Every gate below is off when its variable is unset — so the default is open access, and you opt into each restriction. They compose: a sign-in must clear all configured gates.
| Variable | Effect |
|---|---|
AUTH_ALLOWED_TENANTS | CSV of Entra tenant GUIDs. Reject any token whose tid isn't listed. The core "only our company" gate. |
AUTH_ALLOWED_EMAIL_DOMAINS | CSV of email domains. Reject sign-ins outside them. |
AUTH_ACCESS_MODE | open (default) or invite. invite = deny everyone except existing users, org-invited emails, and AUTH_ALLOWED_EMAILS. |
AUTH_ALLOWED_EMAILS | CSV explicit allowlist used by invite mode. |
AUTH_ADMIN_GROUPS / AUTH_ADMIN_ROLES / AUTH_ADMIN_EMAILS | Map an Entra group object-id / app-role / email to the marketplace global-admin role. |
When any admin-mapping variable is set, the marketplace reconciles
global-admin on every login — granted when the claim matches, revoked when it
stops matching. Denied sign-ins land on /login?error=AccessDenied.
https://<your-host>/api/auth/callback/microsoft-entra-id
(one per environment; must match NEXTAUTH_URL).AZURE_AD_CLIENT_SECRET.
Copy Application (client) ID → AZURE_AD_CLIENT_ID and Directory
(tenant) ID → AZURE_AD_TENANT_ID.AUTH_ALLOWED_TENANTS=<tenant-id> so tokens from any other tenant are
rejected.Pick one:
Marketplace.Admin, assign it, set
AUTH_ADMIN_ROLES=Marketplace.Admin. Arrives in the token's roles claim.AUTH_ADMIN_GROUPS=<group-object-id>. Note: users in >200 groups trigger a
groups overage (claim omitted) — prefer app roles then.AUTH_ADMIN_EMAILS=it@customer.com — simplest, no app-reg change.The marketplace reads
tid,groupsandrolesfrom the token, so configure the matching optional claims / app roles on the app registration.
For local testing, skip all of this — run with AUTH_PROVIDER=unsecured and
ALLOW_UNSECURED_AUTH=true (see Quickstart).