OIDC Quickstart¶
Log a user in with standards-based OpenID Connect — authorization code + PKCE — in a few HTTP calls.
What it is¶
Every realm in Helix IAM is its own OpenID Connect issuer at https://<host>/realms/<realm>. Point any compliant OIDC client at the realm's discovery document and you get login, single sign-on, token issuance, and logout out of the box.
The discovery document advertises every endpoint you need under the realm:
| Endpoint | Purpose |
|---|---|
/oauth2/authorize |
Start the login (authorization) request |
/oauth2/token |
Exchange the code, refresh tokens |
/userinfo |
Read the signed-in user's claims |
/oauth2/jwks |
Public keys to verify token signatures |
/connect/logout |
RP-initiated single logout |
Before you start¶
Register an application and add an OIDC client to it. Note the client_id, the allowed redirect URI, and — for a confidential client — the client secret.
Public vs confidential clients
Browser SPAs and mobile apps are public clients: they cannot keep a secret, so they protect the code exchange with PKCE. Server-side apps are confidential clients and authenticate with a client secret (PKCE is still recommended).
Quickstart¶
1. Build the authorize URL¶
Generate a PKCE verifier and its S256 challenge, then redirect the user's browser to:
GET /realms/acme/oauth2/authorize
?response_type=code
&client_id=acme-web
&redirect_uri=https://app.example.com/callback
&scope=openid profile email
&state=ehV9...random
&code_challenge=YS3v...base64url
&code_challenge_method=S256
After the user authenticates, Helix redirects back to your redirect_uri with ?code=...&state=.... Verify state matches the value you sent.
2. Exchange the code for tokens¶
curl -X POST https://auth.example.com/realms/acme/oauth2/token \
-d grant_type=authorization_code \
-d client_id=acme-web \
-d code=$AUTH_CODE \
-d redirect_uri=https://app.example.com/callback \
-d code_verifier=$PKCE_VERIFIER
A confidential client adds -d client_secret=$SECRET (or HTTP Basic auth) instead of, or alongside, the verifier. You receive an access_token, an id_token, and a refresh_token.
3. Read the user's claims¶
4. Refresh the access token¶
curl -X POST https://auth.example.com/realms/acme/oauth2/token \
-d grant_type=refresh_token \
-d client_id=acme-web \
-d refresh_token=$REFRESH_TOKEN
5. Log the user out (RP-initiated)¶
GET /realms/acme/connect/logout
?id_token_hint=$ID_TOKEN
&post_logout_redirect_uri=https://app.example.com/
Verify tokens¶
Always validate the id_token signature against the realm's /oauth2/jwks, and check iss equals the realm issuer, aud contains your client_id, and the token has not expired. The TypeScript SDK handles discovery, PKCE, and token verification for you.