feat(api): surface OIDC provider misconfig on /api/health #214

Closed
opened 2026-06-21 16:37:29 +00:00 by james · 0 comments
Owner

Context

ADR-0017 deferred per-instance OIDC health surfacing. Today, an OIDC instance whose discovery doc is unreachable or whose endpoint overrides are malformed drops out of the registry with a warn-level log line, and the corresponding "Sign in with …" button silently disappears from the UI. A self-hoster has no in-app way to see why — they have to inspect container logs.

Source

  • ADR-0017 §Consequences (Negative bullet): "A misconfigured instance fails silently from the user perspective (button missing) — the warning is in container logs. Surfacing status on /api/health is the documented follow-up."
  • apps/api/lib/auth/oidc-providers.ts lines 22-25: "Endpoint resolution that fails (unreachable discovery doc, bad override) drops the instance from the registry and logs at warn level; other providers keep working. The plan and ADR-0017 explicitly defer per-instance health surfacing (e.g. /api/health) to a follow-up."

Scope

  • Extend GET /api/health to include a per-OIDC-instance status block: { providers: [{ id, status: "ok" | "discovery_failed" | "override_invalid" | "disabled", lastError?: string }] }.
  • Stash the registry-build failure reason on each OIDC instance during oidc-providers.ts resolution so /api/health can read it without re-running discovery on the health-check path.
  • Keep /api/health unauthenticated (apps/api/lib/auth/public-routes.ts) — self-hosters need it reachable for container health probes.
  • Update docs/oidc-self-hoster-guide.md with a "Diagnostics" section pointing at /api/health.

Acceptance criteria

  • GET /api/health includes a providers array with one entry per configured OIDC env-var instance.
  • An intentionally bad OIDC_FOO_ISSUER results in status: "discovery_failed" plus a useful lastError.
  • The status field never leaks the issuer URL itself (already public) but does not leak any internal secrets.
  • /api/health stays cheap (no re-discovery on each request).
  • OpenAPI spec includes the extended response shape.
  • docs/oidc-self-hoster-guide.md documents the diagnostic surface.

Composes with

  • ADR-0017 (this resolves the documented follow-up).
  • #85 (parent OIDC ticket, closed).
## Context ADR-0017 deferred per-instance OIDC health surfacing. Today, an OIDC instance whose discovery doc is unreachable or whose endpoint overrides are malformed drops out of the registry with a warn-level log line, and the corresponding "Sign in with …" button silently disappears from the UI. A self-hoster has no in-app way to see why — they have to inspect container logs. ## Source - ADR-0017 §Consequences (Negative bullet): *"A misconfigured instance fails silently from the user perspective (button missing) — the warning is in container logs. Surfacing status on /api/health is the documented follow-up."* - `apps/api/lib/auth/oidc-providers.ts` lines 22-25: *"Endpoint resolution that fails (unreachable discovery doc, bad override) drops the instance from the registry and logs at warn level; other providers keep working. The plan and ADR-0017 explicitly defer per-instance health surfacing (e.g. /api/health) to a follow-up."* ## Scope - Extend `GET /api/health` to include a per-OIDC-instance status block: `{ providers: [{ id, status: "ok" | "discovery_failed" | "override_invalid" | "disabled", lastError?: string }] }`. - Stash the registry-build failure reason on each OIDC instance during `oidc-providers.ts` resolution so `/api/health` can read it without re-running discovery on the health-check path. - Keep `/api/health` unauthenticated (`apps/api/lib/auth/public-routes.ts`) — self-hosters need it reachable for container health probes. - Update `docs/oidc-self-hoster-guide.md` with a "Diagnostics" section pointing at `/api/health`. ## Acceptance criteria - [ ] `GET /api/health` includes a `providers` array with one entry per configured OIDC env-var instance. - [ ] An intentionally bad `OIDC_FOO_ISSUER` results in `status: "discovery_failed"` plus a useful `lastError`. - [ ] The status field never leaks the issuer URL itself (already public) but does not leak any internal secrets. - [ ] `/api/health` stays cheap (no re-discovery on each request). - [ ] OpenAPI spec includes the extended response shape. - [ ] `docs/oidc-self-hoster-guide.md` documents the diagnostic surface. ## Composes with - ADR-0017 (this resolves the documented follow-up). - #85 (parent OIDC ticket, closed).
james closed this issue 2026-06-28 18:46:27 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
james/carol#214
No description provided.