runbook-auth-failure

activetype/runbook

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

  1. 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.
  2. AUTH_URL must match the browser origin users use (scheme + host + port if non-default). Mismatch causes callback/session errors.
  3. 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).
  4. 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).
  5. AUTH_SECRET changed? All existing JWT sessions invalidate — users must sign in again. See app doc rotating AUTH_SECRET.
  6. Google client secret rotated? Update AUTH_GOOGLE_SECRET in deploy env and redeploy.
  7. 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]]