Skip to content

OIDC Configuration

Configure OpenID Connect (OIDC) identity providers for enterprise Single Sign-On.

Mantis uses OIDC 1.0 with Authorization Code flow and PKCE for secure authentication with external identity providers.

Terminal window
curl -X POST \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Okta Production",
"provider_type": "oidc",
"issuer_url": "https://company.okta.com",
"client_id": "0oa1234567890abcdef",
"client_secret": "your-client-secret-here",
"scopes": ["openid", "profile", "email", "groups"],
"auto_create_users": true,
"default_role_id": "019b937d-d9f3-8b6d-a625-c5fa41cd3c10"
}' \
"https://api.mantis.local/api/v1/admin/identity-providers"
FieldRequiredDescription
nameYesUnique display name
provider_typeYesMust be "oidc"
issuer_urlYesOIDC issuer URL
client_idYesOAuth client ID
client_secretYesOAuth client secret
scopesNoOAuth scopes (default: openid, profile, email)
auto_create_usersNoAuto-provision users (default: false)
default_role_idNoDefault role for new users
{
"id": "019b937d-b899-8fa4-a6ce-aa778362a062",
"name": "Okta Production",
"provider_type": "oidc",
"issuer_url": "https://company.okta.com",
"client_id": "0oa1234567890abcdef",
"discovery_url": "https://company.okta.com/.well-known/openid-configuration",
"endpoints": {},
"scopes": ["openid", "profile", "email", "groups"],
"is_enabled": true,
"auto_create_users": true,
"default_role_id": "019b937d-d9f3-8b6d-a625-c5fa41cd3c10",
"default_role_name": "operator",
"user_count": 0,
"created_at": "2024-01-15T10:30:00Z",
"updated_at": null
}

At create time all four endpoint columns are stored as null — discovery runs lazily on the first login, not on create, so the endpoints are populated only after the provider is first used. Each unset endpoint is omitted from the JSON rather than rendered as null, so endpoints comes back empty; treat a missing key as “not discovered yet”.

  1. Create Application in Okta Admin Console:

    • Applications → Create App Integration
    • Sign-in method: OIDC
    • Application type: Web Application
  2. Configure Settings:

    Sign-in redirect URIs: https://your-mantis.com/api/v1/auth/oidc/callback
    Sign-out redirect URIs: https://your-mantis.com
    Controlled access: Limit access to selected groups
  3. Enable PKCE (required):

    • General → Edit
    • Proof Key for Code Exchange (PKCE): Require PKCE
  4. Add Groups Claim:

    • Sign On → Edit OpenID Connect ID Token
    • Groups claim type: Filter
    • Groups claim filter: groups Matches regex .*
Terminal window
# Create Okta provider
curl -X POST \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Okta",
"provider_type": "oidc",
"issuer_url": "https://dev-123456.okta.com",
"client_id": "0oa...",
"client_secret": "...",
"scopes": ["openid", "profile", "email", "groups"],
"auto_create_users": true
}' \
"https://api.mantis.local/api/v1/admin/identity-providers"
  1. Register Application in Azure Portal:

    • App registrations → New registration
    • Supported account types: Single tenant or Multi-tenant
    • Redirect URI: Web → https://your-mantis.com/api/v1/auth/oidc/callback
  2. Configure Authentication:

    • Authentication → Platform configurations → Web
    • Implicit grant: Disable
    • Allow public client flows: No
  3. Create Client Secret:

    • Certificates & secrets → New client secret
    • Note the secret value immediately
  4. API Permissions:

    • API permissions → Add permission → Microsoft Graph
    • Delegated: openid, profile, email, User.Read
  5. Token Configuration (for groups):

    • Token configuration → Add groups claim
    • Select: Security groups / All groups
Terminal window
# Create Azure AD provider
curl -X POST \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Azure AD",
"provider_type": "oidc",
"issuer_url": "https://login.microsoftonline.com/{tenant-id}/v2.0",
"client_id": "your-application-id",
"client_secret": "your-client-secret",
"scopes": ["openid", "profile", "email"],
"auto_create_users": true
}' \
"https://api.mantis.local/api/v1/admin/identity-providers"
  1. Create Client in Keycloak Admin Console:

    • Clients → Create client
    • Client ID: mantis
    • Client Protocol: openid-connect
  2. Configure Client:

    Access Type: confidential
    Standard Flow Enabled: ON
    Direct Access Grants: OFF
    Valid Redirect URIs: https://your-mantis.com/api/v1/auth/oidc/callback
  3. Get Client Secret:

    • Credentials tab → Copy client secret
  4. Configure Mappers (for groups):

    • Mappers → Create
    • Name: groups
    • Mapper Type: Group Membership
    • Token Claim Name: groups
    • Add to ID token: ON
Terminal window
# Create Keycloak provider
curl -X POST \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Keycloak",
"provider_type": "oidc",
"issuer_url": "https://keycloak.example.com/realms/your-realm",
"client_id": "mantis",
"client_secret": "your-client-secret",
"scopes": ["openid", "profile", "email", "groups"],
"auto_create_users": true
}' \
"https://api.mantis.local/api/v1/admin/identity-providers"
  1. Create Application in Auth0 Dashboard:

    • Applications → Create Application
    • Application Type: Regular Web Applications
  2. Configure Settings:

    Allowed Callback URLs: https://your-mantis.com/api/v1/auth/oidc/callback
    Allowed Logout URLs: https://your-mantis.com
    Allowed Web Origins: https://your-mantis.com
  3. Enable Connections:

    • Connections → Enable database/social connections
Terminal window
# Create Auth0 provider
curl -X POST \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Auth0",
"provider_type": "oidc",
"issuer_url": "https://your-tenant.auth0.com",
"client_id": "your-client-id",
"client_secret": "your-client-secret",
"scopes": ["openid", "profile", "email"],
"auto_create_users": true
}' \
"https://api.mantis.local/api/v1/admin/identity-providers"
  1. Create OAuth Client in Google Cloud Console:

    • APIs & Services → Credentials → Create Credentials → OAuth client ID
    • Application type: Web application
  2. Configure Redirect URIs:

    Authorized redirect URIs: https://your-mantis.com/api/v1/auth/oidc/callback
Terminal window
# Create Google provider
curl -X POST \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Google Workspace",
"provider_type": "oidc",
"issuer_url": "https://accounts.google.com",
"client_id": "123456789.apps.googleusercontent.com",
"client_secret": "your-client-secret",
"scopes": ["openid", "profile", "email"],
"auto_create_users": true
}' \
"https://api.mantis.local/api/v1/admin/identity-providers"
ProviderGroupsUsernameEmail
Oktagroupspreferred_usernameemail
Azure ADgroupspreferred_usernameemail
Keycloakgroupspreferred_usernameemail
Auth0https://your-app/rolesnicknameemail
GoogleN/Aemailemail

ID token with groups:

{
"iss": "https://company.okta.com",
"sub": "00u1234567890",
"aud": "0oa1234567890abcdef",
"iat": 1704067200,
"exp": 1704070800,
"nonce": "abc123",
"preferred_username": "alice@company.com",
"email": "alice@company.com",
"groups": ["Everyone", "Developers", "Mantis-Admins"]
}

Mantis automatically discovers OIDC endpoints from the issuer URL:

Terminal window
# Discover endpoints before creating provider
curl -X POST \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"discovery_url": "https://company.okta.com"
}' \
"https://api.mantis.local/api/v1/admin/identity-providers/discover"

Response:

{
"success": true,
"endpoints": {
"authorization_endpoint": "https://company.okta.com/oauth2/v1/authorize",
"token_endpoint": "https://company.okta.com/oauth2/v1/token",
"userinfo_endpoint": "https://company.okta.com/oauth2/v1/userinfo",
"jwks_uri": "https://company.okta.com/oauth2/v1/keys"
},
"error": null
}

Verify the provider configuration is correct:

Terminal window
curl -X POST \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{}' \
"https://api.mantis.local/api/v1/admin/identity-providers/$IDP_ID/test"

Response:

{
"success": true,
"message": "Connection successful - all endpoints discovered",
"details": {
"discovery_reachable": true,
"authorization_reachable": true,
"token_reachable": true,
"jwks_reachable": true,
"response_time_ms": 125
}
}

After configuration, test the login flow:

  1. Navigate to Lens UI login page
  2. Click the SSO provider button
  3. Authenticate with IdP
  4. Verify redirect back to Mantis
Terminal window
curl -X PUT \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Okta Production (Updated)",
"client_secret": "new-client-secret",
"auto_create_users": false
}' \
"https://api.mantis.local/api/v1/admin/identity-providers/$IDP_ID"
Terminal window
# Disable provider
curl -X PUT \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"is_enabled": false}' \
"https://api.mantis.local/api/v1/admin/identity-providers/$IDP_ID"
  1. Generate new secret in IdP admin console
  2. Update Mantis with new secret:
    Terminal window
    curl -X PUT \
    -H "Authorization: Bearer $TOKEN" \
    -H "Content-Type: application/json" \
    -d '{"client_secret": "new-rotated-secret"}' \
    "https://api.mantis.local/api/v1/admin/identity-providers/$IDP_ID"
  3. Test connection to verify
  4. Delete old secret in IdP admin console
  • Rotate secrets at least annually
  • Use automated rotation where supported
  • Monitor for authentication failures after rotation

Before deletion:

  • Unlink all users from the provider
  • Or migrate users to another provider
Terminal window
# Check linked users
curl -H "Authorization: Bearer $TOKEN" \
"https://api.mantis.local/api/v1/admin/identity-providers/$IDP_ID"
# Check user_count field
# Delete provider (fails if users linked)
curl -X DELETE \
-H "Authorization: Bearer $TOKEN" \
"https://api.mantis.local/api/v1/admin/identity-providers/$IDP_ID"
Error: Failed to fetch OIDC discovery
  1. Verify issuer URL is correct
  2. Check network connectivity to IdP
  3. Verify TLS certificates are valid
Error: Token exchange failed: invalid_client
  1. Verify client ID matches IdP configuration
  2. Verify client secret is correct
  3. Check token endpoint auth method
Error: The redirect_uri does not match
  1. Verify callback URL in IdP matches exactly:
    https://your-mantis.com/api/v1/auth/oidc/callback
  2. Check for trailing slashes
  3. Verify protocol (http vs https)
Error: ID token missing email claim
  1. Check IdP configuration for claim mapping
  2. Verify requested scopes include email
  3. Set the claim mapping on the provider if your IdP names the claims differently. POST/PUT /api/v1/admin/identity-providers take a mapping object with username_claim, email_claim, groups_claim, role_sync_mode, token_endpoint_auth_method and provisioning_mode.