Runbook: Authentication / sign-in failure
TL;DR
When sign-in, /api/auth/session, or callbacks fail in production or preview, walk env → host trust → Google redirect URIs → secret rotation in order. Canonical technical detail lives in the app repo docs/utility/authentication.md.
Scope
- Applies to: LumenDev Invoice (Next.js + Auth.js / Google OAuth).
- Out of scope: MongoDB data repair, invoice business logic bugs (unless auth blocks all access).
Preconditions
- Access to deployment environment variables (e.g. Vercel project settings).
- Access to Google Cloud Console OAuth client for this app.
- App repo checkout or
AGENTS.md / docs/utility/authentication.md for variable names.
Procedure
- Confirm mandatory env is set and non-empty (app aborts startup otherwise via
src/env.ts):
MONGODB_URI, AUTH_SECRET (or NEXTAUTH_SECRET), AUTH_URL (or NEXTAUTH_URL), AUTH_GOOGLE_ID, AUTH_GOOGLE_SECRET.
AUTH_URL must match the browser origin users use (scheme + host + port if non-default). Mismatch causes callback/session errors.
- Host trust (Auth.js):
- Set
AUTH_TRUST_HOST=true on serverless/preview hosts when you see UntrustedHost in logs (local development is trusted in auth.config.ts without this).
- Google OAuth client:
- Authorized redirect URIs must include exactly:
{AUTH_URL}/api/auth/callback/google for that environment.
- Authorized JavaScript origins (if required by Google) should include the site origin (no path).
AUTH_SECRET changed? All existing JWT sessions invalidate — users must sign in again. See app doc rotating AUTH_SECRET.
- Google client secret rotated? Update
AUTH_GOOGLE_SECRET in deploy env and redeploy.
- MongoDB unreachable? Adapter cannot persist OAuth users — fix connectivity (
MONGODB_URI, network, Atlas IP allowlist).
Rollback
- Revert last env change (especially
AUTH_SECRET, AUTH_URL, AUTH_GOOGLE_SECRET) in the host dashboard and redeploy.
- If Google client was recreated, restore redirect URIs on the previous client or update env to the active client’s ID/secret.
Validation
- 200 on
GET /api/auth/session when logged in (or sensible unauthenticated response without 500).
- Complete Google sign-in and land on dashboard with APIs returning 200 (not 401) for invoice/settings routes.
Related Incidents
- (Link postmortems here when filed.)
Links
- App repo:
docs/utility/authentication.md, src/auth.config.ts, src/auth.ts, src/middleware.ts
- Hub: [[Projects/lumendev-invoice/lumendev-invoice]]
- Vault: [[Resources/Tech/Auth.js/Auth.js Next.js JWT Google MongoDB adapter pattern|Evergreen Auth.js pattern]], [[Projects/lumendev-invoice/context/authjs-implementation|Lumen file map]]