POST /api/v1/auth/oidc/start
OpenID Connect sign-in, step 1: name the page key and a redemption challenge; receive a flow.
Starts an OpenID Connect Authorization Code + PKCE (S256) sign-in for one browser page through one operator-configured binding (an application origin, a provider, a key server). Open: the page holds no session yet. Every later step is bound to what this request names -- the page's public key (its RFC 7638 thumbprint) and the SHA-256 of a redemption secret only the page holds.
The request's Origin (or, absent, the origin of Referer) must equal the binding's
application origin. The page generates its key NON-EXTRACTABLE (crypto.subtle.generateKey
ECDSA P-256) and keeps the secret in memory; neither leaves it except as the public JWK and
the hash sent here.
Open launchUrl in a sign-in window (a top-level navigation). Every response of the five
OIDC operations is Cache-Control: no-store and Referrer-Policy: no-referrer.
Authentication
No session required. This operation is reachable without an Authorization header. See Authenticating.
Request
| Field | Type | Required | Description |
|---|---|---|---|
providerId | string | yes | The configured provider the binding names. |
bindingId | string | yes | The operator-configured binding. |
signingJwk | object | yes | The PUBLIC half of the page's EC P-256 key, as a JWK. A JWK carrying private members is refused. The session is bound to this key, and the mint proof and every DPoP proof are signed with it. |
redemptionChallenge | string | yes | base64url(SHA-256(redemption secret)), 43 characters, unpadded. |
objects | array of string | no | Optional canonical base64 object identifiers the session is scoped to, where the binding's object-scope policy admits them; refused where it does not. |
Example
{
"providerId": "...",
"bindingId": "...",
"signingJwk": {},
"redemptionChallenge": "...",
"objects": [
"..."
]
}
Responses
200
A login transaction.
| Field | Type | Required | Description |
|---|---|---|---|
flowId | string | yes | The flow's id. Not a secret by itself; never put it in a log. |
launchUrl | string | yes | The Gateway's own launch route under its public origin, carrying the flow and a single-use launch token. |
expiresAt | string | yes |
Example
{
"flowId": "...",
"launchUrl": "...",
"expiresAt": "..."
}
400
OIDC_REQUEST_MALFORMED -- a field is missing or malformed (detail names it).
403
ORIGIN_REJECTED -- the request's origin is not the binding's application origin. BINDING_NOT_AVAILABLE -- the binding is unknown, disabled, or not on that provider.
413
PAYLOAD_TOO_LARGE (retryable: false) -- the request body is larger than this
deployment accepts. It was refused before it was parsed, and the connection is closed.
Nothing was sent to the key server.
429
RATE_LIMITED (retryable: true, Retry-After) -- the allowance this request is charged
to is spent: the login allowance of its network source (before authentication), or the
allowance, the concurrency ceiling or the live-session ceiling of the identity it was
verified as -- shared by every session that identity holds, including every delegated
and scoped credential a service minted. It carries no scope. Nothing was sent to the
key server; on a login refused after authentication, the session it created has been
closed. See "Rate and capacity limits" above.
503
LOGIN_CAPACITY_EXHAUSTED (Retry-After) -- the Gateway holds its configured maximum of pending sign-ins. OIDC_NOT_CONFIGURED (Retry-After) -- this Gateway has no OpenID Connect configuration. Or CAPACITY_UNAVAILABLE (see "Rate and capacity limits").
Error handling
Every failure answers JSON carrying at least code and detail. Match on code — detail is written for a human debugging the call and its wording is not part of the contract. See the error model.
| Status | Meaning |
|---|---|
400 | OIDC_REQUEST_MALFORMED -- a field is missing or malformed (detail names it). |
403 | ORIGIN_REJECTED -- the request's origin is not the binding's application origin. BINDING_NOT_AVAILABLE -- the binding is unknown, disabled, or not on that provider. |
413 | PAYLOAD_TOO_LARGE (retryable: false) -- the request body is larger than this deployment accepts. It was refused before it was parsed, and the connection is closed. Nothing was sent to the key server. |
429 | RATE_LIMITED (retryable: true, Retry-After) -- the allowance this request is charged to is spent: the login allowance of its network source (before authentication), or the allowance, the concurrency ceiling or the live-session ceiling of the identity it was verified as -- shared by every session that identity holds, including every delegated and scoped credential a service minted. It carries no scope. Nothing was sent to the key server; on a login refused after authentication, the session it created has been closed. See "Rate and capacity limits" above. |
503 | LOGIN_CAPACITY_EXHAUSTED (Retry-After) -- the Gateway holds its configured maximum of pending sign-ins. OIDC_NOT_CONFIGURED (Retry-After) -- this Gateway has no OpenID Connect configuration. Or CAPACITY_UNAVAILABLE (see "Rate and capacity limits"). |