OIDC / OAuth2¶
Overview¶
JustIAM is a standards-compliant OpenID Connect 1.0 provider built on OAuth 2.0. It supports the Authorization Code flow with optional PKCE (Proof Key for Code Exchange).
Discovery¶
OIDC discovery metadata is available at:
Key fields:
- issuer — value of OIDC_ISSUER
- authorization_endpoint — /oauth2/authorize
- token_endpoint — /oauth2/token
- userinfo_endpoint — /oauth2/userinfo
- jwks_uri — /.well-known/jwks.json
- end_session_endpoint — /oauth2/logout
Authorization Code Flow¶
1. Client → GET /oauth2/authorize?...
2. User authenticates (and completes MFA if required)
3. JustIAM → redirect to redirect_uri?code=...&state=...
4. Client → POST /oauth2/token (exchange code)
5. JustIAM → { access_token, id_token, refresh_token }
Application access control: If the application has
access_restricted = trueand the user is not granted access, step 3 is replaced by a branded Access Denied HTML page. The page includes a "Return to {app}" button whose URL isredirect_uri?error=access_denied&error_description=...&state=...per RFC 6749 §4.1.2.1. The same behaviour applies when a post-render script denies access.
Step 1 — Authorization request¶
GET /oauth2/authorize
?response_type=code
&client_id=<client_id>
&redirect_uri=https://app.example.com/callback
&scope=openid+profile+email
&state=<random>
&nonce=<random>
Optional PKCE parameters:
Optional:
Step 2 — Token exchange¶
POST /oauth2/token
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code
&code=<auth_code>
&redirect_uri=https://app.example.com/callback
&client_id=<client_id>
&client_secret=<client_secret>
With PKCE (public client):
Response¶
{
"access_token": "<jwt>",
"id_token": "<jwt>",
"refresh_token": "<opaque>",
"token_type": "Bearer",
"expires_in": 3600,
"scope": "openid profile email"
}
Refresh Token¶
POST /oauth2/token
Content-Type: application/x-www-form-urlencoded
grant_type=refresh_token
&refresh_token=<opaque>
&client_id=<client_id>
&client_secret=<client_secret>
Returns a new access token and ID token. The refresh token itself may be rotated.
Refresh token lifetime: oauth_refresh_ttl_days setting (default 30 days).
UserInfo Endpoint¶
Returns claims corresponding to the granted scopes.
Token format¶
Tokens are RS256-signed JWTs. Standard claims:
| Claim | Description |
|---|---|
sub |
User UUID |
iss |
OIDC_ISSUER value |
aud |
Client ID |
iat |
Issued at (Unix timestamp) |
exp |
Expiry (Unix timestamp) |
email |
(if email scope granted) |
name |
(if profile scope granted) |
given_name / family_name |
(if profile scope granted) |
preferred_username |
(if profile scope granted) |
groups |
(if groups scope granted) Array of group names |
| (custom) | Any claim mappings configured for the application |
JWKS¶
Public keys for token verification:
Keys use RS256 (RSA 2048+). The key is generated once on first startup.
Logout¶
RP-Initiated Logout¶
Clears the idp_sid SSO cookie and redirects to the provided URI.
Note
post_logout_redirect_uri must be pre-registered in the application's Post-Logout URIs list. Requests with an unregistered URI or no client_id are accepted (session is cleared) but the redirect is silently dropped to prevent open-redirect attacks.
Backchannel Logout¶
If an application has backchannel_logout_uri configured, JustIAM sends a logout_token JWT (OIDC Backchannel Logout 1.0) to that endpoint whenever the user's session is terminated.
PKCE¶
PKCE (RFC 7636) prevents authorization code interception by binding the code to a secret only the client knows.
- Client generates
code_verifier(43–128 chars, high-entropy) - Client computes
code_challenge = BASE64URL(SHA256(code_verifier)) - Sends
code_challenge+code_challenge_method=S256in the authorization request - Sends
code_verifierin the token request — JustIAM verifies the hash
PKCE is required for public clients (is_public = true) or when require_pkce = true.
SSO¶
If the user already has a valid idp_sid SSO cookie, JustIAM will skip the login page and silently complete the authorization flow. This provides seamless SSO across all applications registered with the same JustIAM instance.
Use prompt=login to force re-authentication, or prompt=none to fail immediately if no valid session exists.