Skip to main content

Module api_oidc

Module api_oidc 

Expand description

Cross-surface OIDC enrollment API.

Design: docs/security/oidc-browser-pkce-design-8289.md. These routes are unauthenticated by necessity (enrollment precedes authentication), rate limited, and grant nothing: they relay what the IdP grants after the user approves. The gateway holds the [oidc.<alias>] client credentials so browsers and zerocode need none.

  • GET /api/oidc/providers lists configured aliases.
  • POST /api/oidc/{alias}/device/start proxies the RFC 8628 start.
  • POST /api/oidc/{alias}/device/poll proxies one token poll. Its statuses are a contract a polling client reads: 403 is the authorization server’s refusal and ends the flow, while 429 and 503 (both with Retry-After) and 502 are “not now” and are retryable for as long as the device code lives.
  • GET /oidc/login/{alias} starts Authorization Code + PKCE (302).
  • GET /oidc/callback finishes it: the one-time page hands the token to window.opener via postMessage (gateway origin only) with a manual copy fallback. No cookies, no session: clients keep authenticating per request with the route-layer headers.

Because nothing here is authenticated, every route is bounded before it can cause outbound work, by four independent limits held in OidcEnrollmentState: an attempt limiter refuses clients that are already locked out, a per-client sliding-window budget caps relay requests per minute, a process-wide semaphore caps how many IdP round trips can be in flight at once, and the pending-flow store bounds both its own size and how much of it one client can hold. Every response from these routes is Cache-Control: no-store: each one carries, or is one step from, a device code or an access token.

The attempt limiter is this surface’s own, not the gateway-wide auth_limiter that POST /pair and webhook auth share. Those two count only failures, so billing enrollment traffic to the same counter would let a browser sign-in loop lock a client out of pairing, and a wrong pairing code shorten the enrollment budget. Both limiters are built from the same thresholds and share the loopback exemption.

Functions§

routes