mirror of
https://github.com/coder/coder.git
synced 2026-06-03 13:08:25 +00:00
c1474c7ee2
## Issue context On `dev.coder.com`, users could successfully log in, briefly see the web UI, and then get redirected back to `/login`. We traced the most reliable repro to viewing Tracy's workspaces on the `/workspaces` page. That page eagerly issues authenticated per-row requests such as: - `POST /api/v2/authcheck` - `GET /api/v2/workspacebuilds/:workspacebuild/parameters` One confirmed failing request was for Tracy's workspace `nav-scroll-fix-1f6b`: - route: `GET /api/v2/workspacebuilds/f2104ae6-7d53-457c-a8df-de831bee76db/parameters` - build owner/workspace: `tracy/nav-scroll-fix-1f6b` The failing response body was: - message: `An internal error occurred. Please try again or contact the system administrator.` - detail: `Internal error fetching API key by id. fetch object: pq: password authentication failed for user "coder"` That showed the request was not actually unauthorized. The server hit an internal database/authentication problem while resolving the session API key. The underlying issue was that DB password rotation had been enabled, it has since been disabled. However, the logout cascade happened because: 1. `APIKeyFromRequest()` returned `ok=false` for both genuine auth failures and internal backend failures. 2. `ValidateAPIKey()` wrapped every `!ok` result as `401 Unauthorized`. 3. `RequireAuth.tsx` signs the user out on any `401` response. So a transient backend/database failure was being misreported as an auth failure, which made the client forcibly log the user out. A useful extra clue was that the installed PWA did not repro. The PWA starts on `/agents`, which avoids the `/workspaces` request fan-out. That helped narrow the problem to the eager authenticated requests on the workspace list rather than to cookies or the login flow itself. ## What changed This PR now fixes the bug without changing the exported `APIKeyFromRequest()` surface: - `ValidateAPIKey()` now uses a new internal helper that returns a typed `ValidateAPIKeyError` - the exported `APIKeyFromRequest()` helper remains compatible for existing callers like `userauth.go` - internal API-key lookup failures are classified as `500 Internal Server Error` plus `Hard: true` - internal `UserRBACSubject()` failures now return `500 Internal Server Error` instead of `401 Unauthorized` - a focused regression test verifies that an internal `GetAPIKeyByID` failure surfaces as `500` This removes the brittle message-based classification and makes the internal-auth-failure path robust for all API-key lookup failures handled by auth middleware.