OpenID Connect 1.0 Federation
Cognethics acts as an OpenID Connect Relying Party (RP) against your IdP. We support the authorization-code flow with PKCE (RFC 7636 S256), validate ID tokens against the IdP's JWKS, and provision users automatically from configurable claim mappings.
Quick Reference
| Property | Value |
|---|---|
| Redirect URI (RP) | https://{tenant}.cognethics.com/api/auth/oidc/callback/ |
| Login endpoint | https://{tenant}.cognethics.com/api/auth/oidc/login/?idp={slug} |
| Discovery probe | https://{tenant}.cognethics.com/api/auth/oidc/discover/?email={addr} |
| RP metadata | https://{tenant}.cognethics.com/api/auth/oidc/metadata/ |
| Supported flow | response_type=code + PKCE-S256 |
| Supported scopes | openid, profile, email (extensible) |
| ID token algorithms | RS256 (default), ES256, PS256 |
| Client auth methods | client_secret_basic, none (public PKCE-only clients) |
RP Metadata
Fetch the RP metadata to discover the redirect URI and the list of configured IdPs for your tenant:
curl https://{tenant}.cognethics.com/api/auth/oidc/metadata/
Sample response:
{
"tenant_id": "...",
"tenant_name": "Acme Corp",
"redirect_uri": "https://acme.cognethics.com/api/auth/oidc/callback/",
"login_url_template": "https://acme.cognethics.com/api/auth/oidc/login/?idp={slug}",
"discover_url": "https://acme.cognethics.com/api/auth/oidc/discover/",
"supported_response_types": ["code"],
"supported_grant_types": ["authorization_code", "refresh_token"],
"supported_scopes": ["openid", "profile", "email"],
"pkce_required": true,
"token_endpoint_auth_methods_supported": ["client_secret_basic", "none"],
"configured_idps": [
{
"id": "...",
"slug": "corporate-okta",
"name": "Corporate Okta",
"is_default": true,
"issuer": "https://acme.okta.com"
}
]
}
Configuration
Each OIDC IdP is configured per-tenant with:
| Field | Required | Description |
|---|---|---|
name | Yes | Display name (e.g. "Corporate Okta") |
slug | Yes | URL-safe identifier used in ?idp={slug} |
discovery_url | Yes | IdP's .well-known/openid-configuration URL |
client_id | Yes | OAuth client ID from your IdP application |
client_secret | No | OAuth client secret (encrypted at rest). Omit for public PKCE-only clients. |
scopes | No | OAuth scopes (default ["openid","profile","email"]) |
claim_mapping | No | OIDC claim → Cognethics user field map |
is_active | No | Whether this IdP accepts logins (default false) |
is_default | No | Default IdP when no ?idp= is supplied |
The discovery document is fetched automatically; the authorization_endpoint, token_endpoint, userinfo_endpoint, jwks_uri, and issuer fields are populated from it. Configuration is also exposed via the Cognethics MCP entity_crud/core/oidc_identity_provider/{list,read,create,update,delete} operations, so AI clients can drive setup end-to-end.
Claim Mapping
By default Cognethics maps standard OIDC claims:
| OIDC claim | Cognethics field |
|---|---|
email | |
given_name | First name |
family_name | Last name |
Customize per-IdP for non-standard claims. Example:
{
"email": "email",
"preferred_username": "username",
"https://acme.com/claims/department": "department",
"https://acme.com/claims/employee_id": "external_id"
}
Authorization Flow
- User visits
https://{tenant}.cognethics.com/api/auth/oidc/login/?idp={slug}&next=/welcome - Cognethics generates a PKCE
code_verifier,code_challenge, OAuthstate, and OIDCnonce— stored short-lived (10 min) and bound to the attempt - Browser redirected to the IdP's
authorization_endpointwithresponse_type=code,code_challenge_method=S256, andscope=openid profile email - User authenticates at the IdP
- IdP redirects back to
/api/auth/oidc/callback/?code=...&state=... - Cognethics looks up the state row, validates not-expired and not-consumed, marks it consumed
- Cognethics POSTs the authorization code to the IdP's
token_endpointwithcode_verifier(andclient_secretif applicable) - IdP returns
id_token(a JWT),access_token, and optionallyrefresh_token - Cognethics validates the ID token signature against the IdP's JWKS, checks
iss,aud,exp,nbf, andnonce - Optionally fetches the UserInfo endpoint for richer claims (if
require_userinfo=true) - Resolves the Cognethics user by mapped
emailclaim; creates ifauto_create_users=true - Issues Cognethics JWTs via a one-time server-to-server handoff code — tokens never appear in URLs
ID Token Validation
Every ID token is validated against:
- Signature: JWS algorithm matches
id_token_signed_response_alg(default RS256); signed by a key from the IdP'sjwks_uri. JWKS is cached for one hour with automatic rotation on signature failure. iss: Matches the IdP's configuredissuerexactly.aud: Includes the configuredclient_id.exp: Token has not expired (120-second clock skew tolerance).nbf: Not-before time has passed (with skew).nonce: Matches the nonce Cognethics sent in the authorization request — guards against replay.sub: Required; used as the IdP-stable subject identifier in audit and session tables.
Multi-Domain SSO Routing
Configure email-domain-based IdP selection so users with different email domains land on different IdPs automatically:
@engineering.acme.com→ Okta (Engineering team)@marketing.acme.com→ Azure AD (Marketing team)@acme.com(fallback) → default IdP
Use the discovery probe to check which IdP an email would route to without redirecting:
curl 'https://{tenant}.cognethics.com/api/auth/oidc/discover/[email protected]'
Single Logout (RP-Initiated)
If your IdP publishes an end_session_endpoint in its discovery document, Cognethics initiates RP-initiated logout per OpenID Connect RP-Initiated Logout 1.0. Users logging out of Cognethics are also signed out at the IdP, with post_logout_redirect_uri support for landing-page customization.
Audit Logging
Every OIDC event is captured with full context:
| Event | Details |
|---|---|
| sso_initiate | Authorization request sent to IdP (with state correlation ID) |
| sso_callback | Authorization code received from IdP |
| sso_success | Tokens exchanged, ID token validated, session created |
| sso_failure | Validation failure (with error code, claim mismatch, signature failure) |
| discovery | IdP discovery document refreshed |
| jwks_refresh | IdP JWKS document refreshed |
| user_created | New user auto-provisioned from claims |
| user_updated | Existing user attributes updated from claims |
| slo_initiate | RP-initiated logout sent to IdP |
Common IdP Configurations
Okta (OIDC)
- Okta Admin → Applications → Create App Integration → OIDC — Web Application
- Set:
- Sign-in redirect URI:
https://{tenant}.cognethics.com/api/auth/oidc/callback/ - Sign-out redirect URI:
https://{tenant}.cognethics.com/ - Grant types: Authorization Code (with PKCE)
- Sign-in redirect URI:
- Note the Client ID and Client Secret
- Register the IdP in Cognethics with
discovery_url=https://{your-okta-domain}/.well-known/openid-configuration
Azure AD / Microsoft Entra ID
- Entra Admin → App registrations → New registration
- Set:
- Redirect URI (Web):
https://{tenant}.cognethics.com/api/auth/oidc/callback/ - Front-channel logout URL:
https://{tenant}.cognethics.com/logout
- Redirect URI (Web):
- Certificates & secrets → New client secret
- API permissions → Microsoft Graph →
openid,profile,email - Register the IdP in Cognethics with
discovery_url=https://login.microsoftonline.com/{tenant-id}/v2.0/.well-known/openid-configuration
Auth0
- Auth0 Dashboard → Applications → Create Application → Regular Web Application
- Allowed Callback URLs:
https://{tenant}.cognethics.com/api/auth/oidc/callback/ - Advanced Settings → Grant Types: Authorization Code, Refresh Token
- Note the Domain, Client ID, Client Secret
- Register in Cognethics with
discovery_url=https://{your-auth0-domain}/.well-known/openid-configuration
Google Workspace
- Google Cloud Console → APIs & Services → Credentials → Create OAuth client ID
- Application type: Web application
- Authorized redirect URIs:
https://{tenant}.cognethics.com/api/auth/oidc/callback/ - Register in Cognethics with
discovery_url=https://accounts.google.com/.well-known/openid-configuration
Security Properties
- PKCE on every flow — RFC 7636 S256 code challenge for every authorization-code exchange; replay-resistant even if the redirect URI leaks
stateparameter — Random per-attempt token, single-use, expires in 10 minutes; binds the callback to the original login attempt and prevents CSRFnonceparameter — Random per-attempt token returned in the ID token'snonceclaim; prevents ID-token replay across login attempts- JWKS rotation — JWKS cached one hour by default; on signature failure the JWKS is re-fetched once to recover from key rotation transparently
- Client secrets encrypted at rest — Fernet symmetric encryption
- Server-to-server token handoff — Cognethics JWT pair is delivered via a one-time exchange code; the access/refresh tokens never appear in URLs, Referer headers, or browser history
- Audit log — Every authorization request, callback, validation failure, user creation, and SLO is recorded with correlation IDs
MCP Integration
OIDC IdPs are first-class MCP entities. AI clients with the right permissions can:
| Operation | MCP path |
|---|---|
| List IdPs | entity_crud/core/oidc_identity_provider/list |
| Read IdP details | entity_crud/core/oidc_identity_provider/read |
| Create IdP (auto-fetches discovery) | entity_crud/core/oidc_identity_provider/create |
| Update IdP | entity_crud/core/oidc_identity_provider/update |
| Delete IdP | entity_crud/core/oidc_identity_provider/delete |
Create example:
{
"tool": "entity_crud",
"app": "core",
"entity": "oidc_identity_provider",
"operation": "create",
"data": {
"name": "Corporate Okta",
"slug": "corporate-okta",
"discovery_url": "https://acme.okta.com/.well-known/openid-configuration",
"client_id": "0oa1...",
"client_secret": "...",
"is_active": true,
"is_default": true
}
}
Troubleshooting
"ID token signature validation failed":
- Verify the IdP's JWKS endpoint is reachable from Cognethics
- Trigger a
refresh_discoveryaction to re-fetch the JWKS - Confirm the configured
id_token_signed_response_algmatches the IdP's signing algorithm
"ID token issuer mismatch":
- The
issclaim must exactly match the IdP's configuredissuer. Common cause: trailing slash differences. Refresh discovery to align.
"ID token nonce mismatch":
- The callback received an ID token whose
noncedoesn't match the in-flight state. Most often this means the user opened two login windows. Have them retry from a single tab.
"State already consumed" / "State expired":
- The authorization callback was re-played or arrived after the 10-minute window. Have the user retry.
"User {email} not found and auto-creation is disabled":
- Either enable
auto_create_usersfor the IdP, or pre-create the user with the matching email.
Standards
- OpenID Connect Core 1.0
- OpenID Connect Discovery 1.0
- OpenID Connect RP-Initiated Logout 1.0
- OAuth 2.0 (RFC 6749)
- PKCE (RFC 7636)
Back to Enterprise Authentication · See also SAML 2.0 SSO · SCIM 2.0 Provisioning