Runbook: OAuth Broken
Symptoms
- Users are returned to
/loginwith a GitHub sign-in error and support reference. - Hook CLI device-code flow failing —
logincommand errors or hangs. apps/weblogs:auth.callback.state_mismatch,auth.callback.oauth_exchange_failed,auth.callback.unexpected_error, orsession.decode.error.
Observe
Metrics: Grafana — http://localhost:3001 (see on-call.md)
Grafana: http://localhost:3001 (see on-call.md)There are no dedicated OAuth metrics yet. For now rely on web and ingest logs.
Web logs:
docker compose -f docker-compose.app.yml logs -f webSearch these logs for the support reference shown on the login page. It is the callback request ID and correlates directly with the server-side error without exposing OAuth codes, state values, or exception details to the user.
Ingest auth logs:
bun run docker:app:logs | grep 'auth\|token\|identity'Diagnose
-
GitHub OAuth credentials revoked or rotated? — Check
GITHUB_OAUTH_CLIENT_IDandGITHUB_OAUTH_CLIENT_SECRETare still valid. Regenerate via the OAuth App settings if needed. -
JWT keypair missing or rotated? —
JWT_ED25519_PRIVATE_KEYandJWT_ED25519_PUBLIC_KEYmust be present for login and token verification. Generate the production pair withjust prod-keys; if the keypair changes, existing sessions and hook tokens are invalidated. -
Callback URL mismatch? — Set
APP_BASE_URLto the browser-facing HTTPS origin (for example,https://agentometry.brnby.com) and configure the GitHub OAuth App callback as that origin plus/api/auth/callback. Do not use a Docker bind address such as0.0.0.0:3000. Update both when the deployment URL changes. -
Clock skew? — JWT
expvalidation fails if the server clock is >5 min off. Checkdateon the host. -
Device-code flow (hook CLI)? — The hook login command talks to the web app, defaulting to
http://localhost:3000. SetAIOT_APIto the correct web URL and check~/.aiot/identity.jsonafter login.
Mitigate
- Rotate the GitHub OAuth credentials and update env vars, then restart
apps/web. - If the JWT keypair was rotated: existing sessions and hook tokens are invalidated — users must re-login (expected behavior).
- Temporary workaround: if the web UI is inaccessible, direct-API access via curl with a valid token still works.
Escalate
If credentials are suspected compromised (not just misconfigured), escalate to the security team immediately. See on-call.md.