Skip to content

Endpoints ​

All URLs are relative to the configured issuer.

EndpointMethodSpec
/.well-known/openid-configurationGETOpenID Connect Discovery 1.0, RFC 8414
/.well-known/jwks.jsonGETRFC 7517
/connect/tokenPOSTRFC 6749 §3.2

The authorization, userinfo, revocation, introspection, and end session endpoints arrive in later releases. Discovery only advertises what is implemented.

Pages ​

Server-rendered pages for people, not clients. They work without JavaScript, and forms are protected with anti-forgery tokens.

PageDescription
/setupFirst-run setup wizard. Only available while no user exists; returns 404 afterwards. See First run.
/account/loginSign in with a username or email address and password. Accepts a local returnUrl; other URLs are ignored.
/account/logoutAsks for confirmation, then ends the session.
/accountShows who is signed in.

Every response carries these headers:

HeaderValue
Content-Security-Policydefault-src 'none'; style-src 'self'; img-src 'self' data:; frame-ancestors 'none'; base-uri 'none'
X-Frame-OptionsDENY
X-Content-Type-Optionsnosniff
Referrer-Policyno-referrer

Strict-Transport-Security is added to HTTPS responses outside the Development environment.

Discovery ​

Returns the issuer, jwks_uri, token_endpoint, grant_types_supported (client_credentials), and token_endpoint_auth_methods_supported (client_secret_basic, client_secret_post).

JWKS ​

Returns the public RSA keys (kty, use, alg, kid, n, e). This includes keys that are not used yet and retired keys whose tokens may still be valid. See Signing key rotation.

Token endpoint ​

Requests must be POST with application/x-www-form-urlencoded parameters. Parameters must not be repeated. Responses are JSON with Cache-Control: no-store.

Client authentication ​

Confidential clients authenticate with one of:

  • client_secret_basic: HTTP Basic, with the client id and secret each form-urlencoded first (RFC 6749 §2.3.1).
  • client_secret_post: client_id and client_secret form parameters.

Using both in the same request is rejected.

client_credentials grant ​

ParameterRequiredDescription
grant_typeyesclient_credentials
scopenoSpace-separated API scopes. If omitted, all API scopes the client may use are granted.
sh
curl -u billing:$SECRET https://id.example.com/connect/token \
  -d grant_type=client_credentials -d scope=orders.read
json
{
  "access_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6...",
  "token_type": "Bearer",
  "expires_in": 1800,
  "scope": "orders.read"
}

The access token is a JWT following RFC 9068:

ClaimValue
header typat+jwt
issThe issuer
audThe API resources that own the granted scopes
sub, client_idThe client id
scopeThe granted scopes
iat, nbf, exp, jtiIssue time, not-before, expiry, unique id

Access tokens can't be revoked before they expire; keep their lifetime short.

Errors ​

Errors follow RFC 6749 §5.2:

ErrorStatusCause
invalid_request400Wrong content type, repeated or missing parameters, or two authentication methods
invalid_client401Client authentication failed (unknown or disabled client, wrong or expired secret)
unauthorized_client400The client may not use this grant type
unsupported_grant_type400The grant type isn't supported
invalid_scope400A scope is malformed, unknown, disabled, an identity scope, or not allowed for the client

Requests over the rate limit get 429 Too Many Requests with a Retry-After header.

All client authentication failures return the same response, so callers can't tell which clients exist.

Released under the MIT License.