OIDC Authentication Configuration
Self-Hosted Deployments Only
This guide is for self-hosted deployments where you manage your own Kubernetes infrastructure. If your Qualytics instance is a managed deployment (hosted and operated by Qualytics), see the SSO Setup Guide instead. Your account manager handles authentication configuration for you.
This guide explains how to configure OpenID Connect (OIDC) authentication for a self-hosted Qualytics deployment. OIDC is the recommended authentication method for self-hosted deployments because it integrates directly with your enterprise Identity Provider (IdP) and supports environments without internet egress.
Overview
When configured for OIDC, Qualytics authenticates users directly against your organization's Identity Provider using the OpenID Connect protocol. This means:
- No external authentication dependency: Authentication is handled entirely within your network.
- Your IdP governs access: User login requirements, MFA, and password policies are enforced by your IdP.
- Air-gapped support: Authentication does not require egress to external services.
sequenceDiagram
participant User
participant Qualytics
participant IdP as Your Identity Provider
User->>Qualytics: Access Qualytics UI
Qualytics->>IdP: Redirect to IdP login
IdP->>User: Prompt for credentials
User->>IdP: Authenticate
IdP->>Qualytics: Return authorization code
Qualytics->>IdP: Exchange code for tokens
Qualytics->>IdP: Fetch user info
Qualytics->>User: Set session cookies & redirect to UI
Supported Identity Providers
Any OIDC-compliant Identity Provider is supported, including:
- Microsoft Entra ID (Azure Active Directory)
- Okta / Okta Workforce Identity
- Google Workspace
- Keycloak
- OneLogin
- PingFederate
- ForgeRock
- Active Directory Federation Services (ADFS)
Step 1: Register Qualytics in Your IdP
Before configuring Qualytics, you need to register it as an application in your Identity Provider.
Application Registration Settings
| Setting | Value |
|---|---|
| Application type | Web application |
| Grant type | Authorization Code |
| Redirect URI | https://<your-qualytics-domain>/api/callback |
| Scopes | openid, email, profile (at minimum openid) |
| Token endpoint auth method | Client secret POST or Basic, as required by your IdP |
| Back-channel logout URL (optional) | https://<your-qualytics-domain>/api/backchannel-logout |
After registration, your IdP will provide:
- A Client ID
- A Client Secret
- A Discovery URL (typically
https://<your-idp-domain>/.well-known/openid-configuration)
Back-Channel Logout
When your IdP sends a supported back-channel logout notification, Qualytics deactivates that user account.
Step 2: Configure Qualytics
Set global.authType to OIDC in your Helm values.yaml file and provide the OIDC configuration under secrets.oidc.
Every installation must also keep its Qualytics-provided deployment identifier under secrets.deployment.identifier. The identifier is separate from your OIDC credentials, image registry token, and platform license. See the Self-Hosted Deployment Guide for secure handling requirements.
Discovery URL (Recommended)
The simplest way to configure OIDC is to provide a Discovery URL. Qualytics will automatically fetch your IdP's .well-known/openid-configuration document and populate the authorization, token, userinfo, JWKS, and issuer endpoints for you.
For OIDC authentication, a discovery URL reduces the required configuration to four values. Other installation requirements, including the deployment identifier, still apply.
| Helm Value | Description | Example |
|---|---|---|
secrets.oidc.oidc_discovery_url |
IdP's OpenID Connect discovery endpoint | https://your-org.okta.com/.well-known/openid-configuration |
secrets.oidc.oidc_client_id |
OAuth2 client ID from your IdP | 0oabc123def456 |
secrets.oidc.oidc_client_secret |
OAuth2 client secret from your IdP | (secret value) |
secrets.auth.jwt_signing_secret |
Secret for signing JWTs (minimum 32 characters) | (generate with openssl rand -base64 32) |
Set global.authType: "OIDC" in your values.yaml. Scopes, claim mappings, and endpoints have defaults that work with most IdPs.
Common Discovery URLs
| Identity Provider | Discovery URL |
|---|---|
| Okta | https://{your-domain}.okta.com/.well-known/openid-configuration |
| Microsoft Entra ID | https://login.microsoftonline.com/{tenant-id}/v2.0/.well-known/openid-configuration |
| Google Workspace | https://accounts.google.com/.well-known/openid-configuration |
| Keycloak | https://{host}/realms/{realm}/.well-known/openid-configuration |
Discovery URL auto-discovers 5 endpoints
When oidc_discovery_url is set, the following fields are fetched automatically at startup and do not need to be configured:
oidc_authorization_endpointoidc_token_endpointoidc_userinfo_endpoint- JWKS URI (for back-channel logout token verification)
- Issuer (for back-channel logout token validation)
These fields default to empty strings ("") and are not injected into the deployment when left empty. If you set both a discovery URL and individual endpoints, the individually configured values take precedence as fallbacks.
Manual Endpoint Configuration (Fallback)
If your IdP does not support a standard discovery URL, or if the discovery endpoint is not reachable from your cluster, you can configure endpoints individually instead:
| Helm Value | Description | Example |
|---|---|---|
global.authType |
Authentication mode; must be OIDC |
OIDC |
secrets.oidc.oidc_client_id |
OAuth2 client ID from your IdP | 0oabc123def456 |
secrets.oidc.oidc_client_secret |
OAuth2 client secret from your IdP | (secret value) |
secrets.oidc.oidc_authorization_endpoint |
IdP's authorization URL | https://login.example.com/oauth2/authorize |
secrets.oidc.oidc_token_endpoint |
IdP's token exchange URL | https://login.example.com/oauth2/token |
secrets.oidc.oidc_userinfo_endpoint |
IdP's user info URL | https://login.example.com/oauth2/userinfo |
secrets.auth.jwt_signing_secret |
Secret for signing JWTs (minimum 32 characters) | (generate with openssl rand -base64 32) |
JWT Signing Secret
The jwt_signing_secret must be at minimum 32 characters long. Changing this value will invalidate all active user sessions.
Redirect URL
The OAuth2 callback URL is automatically set to https://<global.dnsRecord>/api/callback. Ensure this matches the redirect URI registered in your IdP.
Optional Settings
OIDC Scopes and Behavior
| Helm Value | Default | Description |
|---|---|---|
secrets.oidc.oidc_scopes |
openid,email,profile |
Comma-separated OAuth2 scopes |
secrets.oidc.oidc_token_auth_method |
Auto-detected | Token endpoint authentication method; set client_secret_basic or client_secret_post only when required by your IdP |
secrets.oidc.oidc_jwt_ttl_minutes |
Platform default | Session lifetime in minutes; omit this value unless you need an explicit override |
secrets.oidc.oidc_allow_insecure_transport |
false |
Allow HTTP for IdP endpoints; use only in development |
secrets.oidc.oidc_signer_pem_url |
"" |
URL to a custom CA certificate PEM for IdP token validation |
Claims Mapping
All claim keys default to standard OIDC claim names and work out of the box with most IdPs. You only need to override these if your IdP uses non-standard claim names:
| Helm Value | Default | Qualytics Field |
|---|---|---|
secrets.oidc.oidc_user_id_key |
sub |
User ID |
secrets.oidc.oidc_user_email_key |
email |
Email address |
secrets.oidc.oidc_user_name_key |
name |
Display name |
secrets.oidc.oidc_user_fname_key |
given_name |
First name |
secrets.oidc.oidc_user_lname_key |
family_name |
Last name |
secrets.oidc.oidc_user_picture_key |
picture |
Profile picture URL |
secrets.oidc.oidc_user_provider_key |
iss |
Identity provider name |
secrets.oidc.oidc_user_groups_key |
groups |
IdP group names used for optional Team mapping |
Optional IdP Group Mapping to Teams
Self-hosted deployments can add users to existing Qualytics Teams based on an IdP group claim. This feature is disabled by default because Team membership can grant access to data.
Before enabling it, confirm the exact claim name and values emitted by your IdP. Some providers require an additional scope before they include groups in the token or user information response.
Group mapping follows these rules:
- Group names are matched case-insensitively against existing Team names.
- Unmatched groups are ignored. This feature does not create Teams.
- Membership is add-only. Removing a user from an IdP group does not remove them from the matching Team.
- Administrators must remove obsolete Team memberships in Qualytics when access should be revoked.
Review the Team Best Practices before enabling automated membership.
Environment Variable Reference
The Helm values on this page are the supported configuration interface. Do not add authentication environment variables directly to the application workloads, because their internal mapping can change between chart versions. For advanced troubleshooting, provide your approved chart version and a redacted copy of the relevant Helm values to Qualytics Support.
Example values.yaml: Discovery URL (Recommended)
This example uses the default scopes, claim mappings, and endpoints:
global:
dnsRecord: "qualytics.example.com"
authType: "OIDC"
secrets:
deployment:
identifier: "<provided by Qualytics>"
oidc:
oidc_discovery_url: "https://your-org.okta.com/.well-known/openid-configuration"
oidc_client_id: "your-client-id"
oidc_client_secret: "your-client-secret"
auth:
jwt_signing_secret: "your-secure-random-string-min-32-chars"
postgres:
secrets_passphrase: "your-secure-passphrase"
rabbitmq:
rabbitmq_password: "your-secure-password"
Example values.yaml: Manual Endpoints (Fallback)
Use this approach only if your IdP's discovery endpoint is not reachable from your cluster:
global:
dnsRecord: "qualytics.example.com"
authType: "OIDC"
secrets:
deployment:
identifier: "<provided by Qualytics>"
oidc:
oidc_client_id: "your-client-id"
oidc_client_secret: "your-client-secret"
oidc_scopes: "openid,email,profile"
oidc_authorization_endpoint: "https://login.example.com/oauth2/authorize"
oidc_token_endpoint: "https://login.example.com/oauth2/token"
oidc_userinfo_endpoint: "https://login.example.com/oauth2/userinfo"
auth:
jwt_signing_secret: "your-secure-random-string-min-32-chars"
postgres:
secrets_passphrase: "your-secure-passphrase"
rabbitmq:
rabbitmq_password: "your-secure-password"
Step 3: Deploy or Restart
If this is a new deployment, follow the Self-Hosted Deployment Guide to deploy Qualytics.
If you are updating an existing deployment's authentication configuration, apply the changes:
CHART_VERSION="<version provided by Qualytics>"
helm upgrade qualytics qualytics/qualytics \
--namespace qualytics \
--version "$CHART_VERSION" \
-f values.yaml \
--wait \
--timeout=20m
Use the complete protected values.yaml file that contains the installation's existing deployment identifier. Do not pass the identifier with --set, because command arguments can be stored in shell history and process logs.
Step 4: Verify Authentication
- Navigate to your Qualytics instance in a browser (e.g.,
https://qualytics.example.com) - You should be redirected to your IdP's login page
- Authenticate with your IdP credentials
- After successful authentication, you should be redirected back to the Qualytics UI
Security Architecture
Qualytics implements a three-tier security model for OIDC authentication:
Tier 1: HttpOnly Cookies + CSRF Protection
- Session JWTs are stored in HttpOnly cookies (not accessible to JavaScript)
- CSRF protection uses a double-submit cookie pattern
- SameSite=Lax cookie attribute prevents cross-site request forgery
Tier 2: Token Fingerprinting
- A random fingerprint is embedded in the JWT and stored in a separate HttpOnly cookie
- Prevents stolen JWT replay because an attacker needs both the JWT and the fingerprint cookie
- Session lifetime can be set with
secrets.oidc.oidc_jwt_ttl_minutes; automatic session refresh is supported
Tier 3: DPoP (Demonstration of Proof-of-Possession)
- The browser generates a non-extractable ECDSA key pair
- The JWT is cryptographically bound to the key pair
- Each API request includes a signed proof, so a stolen JWT is useless without the private key
CLI Authentication
When using OIDC authentication, the Qualytics CLI authenticates via manual token paste:
- Generate an API token in the Qualytics UI
- Provide the token to the CLI when prompted
Note
Browser-based CLI authentication (PKCE flow) is only available when using Auth0. See the Auth0 Setup Guide for details.
Troubleshooting
| Symptom | Likely Cause | Solution |
|---|---|---|
| 401 error after IdP login | Redirect URI mismatch | Ensure the redirect URI registered in your IdP exactly matches https://<global.dnsRecord>/api/callback |
| CORS errors in browser console | Missing frontend origin | Contact your Qualytics account manager; CORS origins are derived from your deployment configuration |
| CSRF token mismatch | Frontend not sending CSRF header | Verify the frontend reads the csrf_token cookie and sends it as the X-CSRF-Token header |
| Sessions expire too quickly | Configured session lifetime is too short | Set secrets.oidc.oidc_jwt_ttl_minutes to the required number of minutes, then apply the updated values |
| User deactivated after IdP logout | Back-channel logout working correctly | This is expected behavior; contact Qualytics Support if the deactivation was unintended |
| User is not added to a Team | Group claim or Team name does not match | Confirm the configured group claim is present and that its value matches an existing Team name; matching is case-insensitive |
| SSL certificate errors | Self-signed or private CA certificates | Set secrets.oidc.oidc_signer_pem_url to your CA certificate URL in your values.yaml |
Need Help?
Contact your Qualytics account manager for assistance with OIDC configuration.