Skip to Content
Get startedQuickstart

Integration quickstart

You need an active tenant, a registered OAuth client and the exact issuer assigned to that tenant.

1. Discover the issuer

issuer='https://TENANT.identity.example.com' curl --fail --silent "$issuer/.well-known/openid-configuration" | jq

Read protocol endpoints from discovery instead of assembling them from remembered paths. Reject discovery documents whose issuer is not byte-for-byte equal to the configured issuer.

2. Start authorization

Generate a high-entropy state, nonce and PKCE verifier. Derive its S256 challenge and redirect the browser to the discovered authorization endpoint with:

response_type=code client_id=YOUR_CLIENT_ID redirect_uri=YOUR_EXACT_CALLBACK scope=openid email state=RANDOM_STATE nonce=RANDOM_NONCE code_challenge=BASE64URL_SHA256_VERIFIER code_challenge_method=S256

Add resource=YOUR_API_AUDIENCE when the client needs an access token for an API. Request offline_access explicitly when the client needs a refresh token.

3. Validate the callback

Require the exact callback path, compare state in constant time and reject an unexpected iss. Exchange the one-use code at the discovered token endpoint with the same redirect URI and the original PKCE verifier.

4. Establish application state

For a browser application, keep access and refresh tokens in the server-side BFF session. Send only an HttpOnly application-session cookie to the browser. For an API, bind product state to the exact (iss, sub) after validating the token as described in Resource servers.

Never bind an existing product account by matching email alone.