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/providerslists configured aliases.POST /api/oidc/{alias}/device/startproxies the RFC 8628 start.POST /api/oidc/{alias}/device/pollproxies 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 withRetry-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/callbackfinishes it: the one-time page hands the token towindow.openerviapostMessage(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.