Skip to content

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:

GET /.well-known/openid-configuration

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 = true and 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 is redirect_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:

  &code_challenge=<S256_hash>
  &code_challenge_method=S256

Optional:

  &prompt=none    # fail if no session (no interactive login)
  &prompt=login   # force re-authentication

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):

&code_verifier=<plain_verifier>

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

GET /oauth2/userinfo
Authorization: Bearer <access_token>

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:

GET /.well-known/jwks.json

Keys use RS256 (RSA 2048+). The key is generated once on first startup.


Logout

RP-Initiated Logout

GET /oauth2/logout?client_id=<client_id>&post_logout_redirect_uri=https://app.example.com

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.

  1. Client generates code_verifier (43–128 chars, high-entropy)
  2. Client computes code_challenge = BASE64URL(SHA256(code_verifier))
  3. Sends code_challenge + code_challenge_method=S256 in the authorization request
  4. Sends code_verifier in 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.


Example: Configuring with a generic OIDC library

Issuer:                 https://justiam.example.com
Client ID:              <from application settings>
Client Secret:          <from application settings>
Scopes:                 openid profile email groups
Redirect URI:           https://app.example.com/callback
Discovery URL:          https://justiam.example.com/.well-known/openid-configuration