Skip to content

Applications — OIDC

Overview

OIDC applications are clients that use JustIAM as an OpenID Connect Provider. JustIAM supports the Authorization Code flow with optional PKCE.


Application types

Type Use case
oidc Server-side web application (confidential client, has a secret)
spa Single-page application (public client, PKCE required)

Creating an application

UI: Administration → Applications → + Create Application

API:

POST /api/v1/applications
Authorization: Bearer <token>
Content-Type: application/json

{
  "name": "My App",
  "description": "Internal dashboard",
  "type": "oidc",
  "redirect_uris": ["https://app.example.com/callback"],
  "allowed_scopes": ["openid", "profile", "email", "groups"],
  "grant_types": ["authorization_code", "refresh_token"],
  "token_expiry": 3600,
  "access_restricted": false,
  "show_in_dashboard": true,
  "launch_url": "https://app.example.com",
  "mfa_policy": "inherit"
}

On creation JustIAM generates a client_id and client_secret.


Key fields

Field Description
friendly_name Optional display label shown in the UI instead of name. Falls back to name when empty
client_id Public identifier sent in authorization requests
client_secret Credential for the token endpoint (confidential clients only)
redirect_uris Allowed callback URLs. Supports exact strings or regex: prefixed patterns (e.g. regex:^https://app\.example\.com/auth/callback.*). Patterns are full-string matched.
allowed_scopes Scopes the client may request. Standard: openid, profile, email, groups
grant_types authorization_code and/or refresh_token
is_public Public client (no secret); PKCE becomes mandatory
require_pkce Require PKCE even for confidential clients
token_expiry Access/ID token lifetime in seconds (default 3600)
access_restricted If true, only explicitly granted users/groups can authenticate
show_in_dashboard Show in the end-user My Apps portal
launch_url Launch URL shown in the portal
app_group Visual grouping label in the portal (e.g. "Productivity")
icon_url Application icon shown in the portal
mfa_policy Override global MFA policy for this app (inherit / disabled / any / otp / passkey)
backchannel_logout_uri OIDC Backchannel Logout endpoint; JustIAM POSTs a logout token here when the user logs out
post_logout_uris Allowed redirect URIs for RP-Initiated Logout (post_logout_redirect_uri query parameter). Must be registered to prevent open-redirect attacks

Scopes

Scope Claims included
openid sub, iss, aud, iat, exp
profile name, given_name, family_name, preferred_username
email email
groups groups (array of group names)

Additional claims can be added via Claim Mappings.


Access control

When access_restricted = true, only explicitly granted users and groups can complete an authorization flow for this application. All others see a branded Access Denied page at the /oauth2/authorize step.

The denial happens before an authorization code is issued, so the relying party never receives a code that it cannot exchange. The page includes a "Return to {application}" button that redirects the browser back to the registered redirect_uri with an error=access_denied query parameter per RFC 6749 §4.1.2.1, allowing the application to react to the rejection.

Grant access via the Access tab on the application page, or via the API:

POST /api/v1/applications/{id}/access/groups
{ "group_id": "<uuid>" }

POST /api/v1/applications/{id}/access/users
{ "user_id": "<uuid>" }

Regenerating the client secret

POST /api/v1/applications/{id}/regenerate-secret

Warning

All existing integrations using the old secret will stop working immediately.


Claim mappings

Claim mappings let you add custom claims to the ID token and access token. See Claim Mappings.


MFA policy per application

You can require a specific MFA level for an individual application by setting mfa_policy to a value other than inherit. This overrides the global setting for that application only.

Value Behaviour
inherit Use the global mfa_policy setting
disabled No MFA, even if global policy requires it
any Any enrolled MFA method accepted
otp TOTP required
passkey Passkey required

Token simulator

The token simulator lets you preview the exact access token and ID token claims a user would receive — including claim mappings and claim script patches — without issuing any real credentials or creating a session.

To open it, click the flask icon (🧪) in the Applications table row for any OIDC app.

What it simulates

  • Standard claims (sub, iss, aud, scope, email, name, …)
  • Custom claim mappings configured on the application
  • Output from the claim script (if configured), applied on top of the base claims

API

POST /api/v1/applications/{id}/simulate
Authorization: Bearer <admin-token>
Content-Type: application/json

{
  "user_id": "<user-uuid>",
  "scopes": ["openid", "email", "profile"]
}

Response:

{
  "type": "oidc",
  "has_access": true,
  "access_claims": { "sub": "...", "email": "...", ... },
  "id_claims":     { "sub": "...", "email": "...", ... },
  "script_error": "<only present if the claim script fails>"
}

has_access is false when the application has Access restricted enabled and the user is not in any allowed group or has no explicit grant.