OAuth 2.1 & OpenID Connect
A standards-true authorization server for every app
Each application gets its own OAuth 2.0 and OpenID Connect provider, built to OAuth 2.1 practice: authorization code with PKCE, rotating refresh tokens, client credentials for services, and discovery your libraries already understand.
Why it matters
Use the client library you already trust, without the usual footguns
How it works
The authorization code flow, as we run it
- 1Your appSend the person to /authorizeresponse_type=code, a PKCE S256 challenge, state and an optional nonce.
- 2PersonSign in and consentThe sign-in you designed, then a consent screen that names each scope.
- 3Identity StudioIssue a one-time codeValid 120 seconds, stored only as a SHA-256 hash, redirect URI matched exactly.
- 4Your appExchange it at /tokenWith the PKCE verifier. A replayed code revokes every grant minted from it.
- 5Identity StudioReturn tokensA 30-minute access token, an RS256 id_token and a refresh token that rotates.
- 6Your APIVerify, introspect, revokeOffline against the JWKS, or at /introspect. /revoke ends consent and grants.
Standards we implement
Exactly what the provider speaks
| Standard | What we support | Status |
|---|---|---|
| RFC 6749 · OAuth 2.0 | authorization_code, refresh_token and client_credentials grants. Implicit and password grants are not offered. | Live |
| RFC 7636 · PKCE | S256 only; plain is refused. Required for public clients and every self-registered client; a per-client switch requires it for confidential clients too. | Live |
| OAuth 2.1 practice | Exact redirect matching, hashed single-use codes, refresh rotation with reuse detection. | Live |
| OpenID Connect Core | id_token signed RS256 with iss, sub, aud, iat, exp, auth_time and nonce. Profile and email claims at /userinfo, filtered by scope. | Live |
| Pairwise subjects | The only subject type: an HMAC of the person within the owning organization, stable across its apps. | Live |
| RFC 8414 · OIDC Discovery | One document at /.well-known/openid-configuration and /.well-known/oauth-authorization-server. | Live |
| RFC 7517 · JWKS | Per-application RSA keys at /app/{key}/.well-known/jwks.json. A retiring key stays published for the longest token lifetime plus the cache window. | Live |
| RFC 7662 · Introspection | Confidential clients only. A dead or foreign token answers just {"active": false}. | Live |
| RFC 7009 · Revocation | Revokes the token, the consent, this client's grants for the person and the session family. Always 200. | Live |
| RFC 7591 · Dynamic registration | Public PKCE clients for applications that host a protected resource; loopback or app-scheme redirects; unconsented clients purged after 7 days. | Live |
| RFC 8707 · Resource indicators | One resource per request; the token's audience is that resource, so every other API refuses it. | Live |
| RFC 9728 · Protected resource metadata | Published for MCP resources so agents can discover the authorization server. | Live |
Not offered today: device authorization grant (RFC 8628), token exchange (RFC 8693), PAR, JAR, DPoP, mTLS-bound tokens, private_key_jwt, RP-initiated or back-channel logout.
Configuration
What an app admin sets per client
Token lifetimes are set for the whole deployment: access 30 minutes, code 120 seconds, refresh 30 days, machine 30 minutes.
| Option | Values | Default |
|---|---|---|
| client_name | Text shown on the consent screen | required |
| redirect_uris | https, or http on localhost only; matched exactly | none |
| allowed_scopes | openid, profile, email, api.read, api.write and your own machine scopes | openid |
| token_endpoint_auth_method | none, client_secret_basic, client_secret_post | none |
| grant_types | authorization_code, refresh_token, client_credentials | code + refresh |
| pkce_required | Require PKCE for a confidential client too | off |
| application_tenant_id | Bind a service client to one customer tenancy | none |
| rotate-secret overlap | 0 to 7 days of overlap for the old secret | 0 |
| Machine scopes | Up to 50 dotted names your API defines | none |
Under the hood
What protects it
From the code
Security notes
- Authorization codes and refresh tokens are stored only as SHA-256 hashes.
- Refresh reuse revokes the rotation chain and the session family, and writes a REFRESH_TOKEN_REUSE_DETECTED event.
- Remembered consent never auto-approves a request bound to a resource; the person is asked each time.
- Client credentials are rate limited per client (60 a minute) and never get a refresh token.
- Production refuses to start unless application tokens are signed RS256.
Works with
Part of one platform
AI agents & MCP Resource-bound tokens for agents.API security Keys, scopes and webhooks.SDKs Verify tokens offline in one line.SAML single sign-on For customers on SAML.
Which plans include it, and the limits that apply, are on the plans page.See plans →
Explore the platform
One platform, every piece of sign-in and access
Give every app a real authorization server
Register a client, point your library at the discovery address and sign someone in today.