For the complete documentation index, see llms.txt.
Skip to main content
Version: 8.10 (unreleased)

Connect Camunda to any OIDC provider

This guide shows you how to configure Camunda 8 Self-Managed to authenticate with any OpenID connect (OIDC)-compliant identity provider.

Bitnami subcharts removed in Camunda 8.10

Earlier releases bundled PostgreSQL through Bitnami subcharts (identityPostgresql, webModelerPostgresql). As of Camunda 8.10 (Helm chart 15.x), the bundled Bitnami subcharts are removed: provide PostgreSQL with the CloudNativePG operator or a managed database, as shown in the examples below.

info

Before proceeding, since this is a general guide, refer to External OIDC provider to see the available provider-specific guides, as they include detailed setup instructions tailored to provider's interface.

Prerequisites​

Before you begin, ensure you have:

  • An OIDC-compliant provider already deployed and accessible.
  • Administrative access to create and configure OIDC clients in your provider.
  • Access to your provider's discovery document to obtain endpoint URLs.
  • A Kubernetes cluster with a supported Helm CLI version installed.
  • kubectl configured to access your cluster.
  • When you connect Management Identity to an OIDC provider, you need a database regardless of feature flags. Chart 15.x no longer bundles one, so provision it with the CloudNativePG operator or a managed database and connect it through identity.externalDatabase, as shown in the examples below. See also use external PostgreSQL.

This guide assumes your OIDC provider is already operational. It does not cover provider installation or basic OIDC configuration.

Private or internal CA

If your provider presents a certificate signed by a private or internal certificate authority (common with Entra hybrid setups, Okta on-premises, or an internal Keycloak), Camunda components won't trust it by default. Configure TLS trust to avoid PKIX path building failed errors when components connect to the issuer.

Create OIDC clients​

Create the following OIDC clients in your provider. The exact process varies by provider; consult your provider's documentation for client creation procedures.

Client nameTypePurpose
Management IdentityConfidentialUser login and API authentication
Orchestration ClusterConfidentialUser login and machine-to-machine authentication
OptimizeConfidentialUser login
Web Modeler APIConfidentialProgrammatic API access
Web Modeler UIPublicUser login
ConsolePublicUser login
tip

For each client, record:

  • Client ID
  • Client secret (for confidential clients only)

Assign a unique audience to each component​

Camunda components can trust tokens from the same OIDC issuer while using the aud claim to identify the intended resource. Each component validates this claim against its configured audience and accepts any token that carries it.

Management Identity controls access to Camunda Hub and Optimize. The Orchestration Cluster manages its own roles and authorizations through Admin. Both subsystems can use the same OIDC provider, but their authorization checks remain independent.

Decide a distinct audience for each component before you configure Helm, then configure your provider to issue it.

ComponentHelm valueChart default
Management Identityglobal.identity.auth.identity.audiencecamunda-identity-resource-server
Orchestration Clusterorchestration.security.authentication.oidc.audienceorchestration-api
Optimizeglobal.identity.auth.optimize.audienceoptimize-api
Web Modeler client APIglobal.identity.auth.webModeler.clientApiAudienceweb-modeler-api
Web Modeler public APIglobal.identity.auth.webModeler.publicApiAudienceweb-modeler-public-api
ConnectorsInherits the Orchestration Cluster audienceorchestration-api
warning

If two components accept the same audience, a token intended for one can also pass the other's audience validation. Keep the resource audiences in this table distinct unless a supported integration requires one component to accept another's token.

Do not derive these values by inspecting whatever token your provider returns by default. If several components are registered against one client or API identifier, inspection returns the same aud for all of them, so configuring what you find reproduces the collision instead of revealing it. Decide the values first, then use token inspection to confirm your provider issues them.

The following integrations intentionally cross this audience boundary:

  • Connectors calls the Orchestration Cluster as a client and uses the Orchestration Cluster's audience. See Configure Connectors.
  • Camunda Hub deployments that use BEARER_TOKEN authentication forward the user's Hub token to the Orchestration Cluster. Configure the cluster to accept the Camunda Hub UI audience in addition to its own audience. See connect Admin to an identity provider.

Configure redirect URIs​

For each OIDC client you have created, configure the redirect URIs that correspond to where Camunda components will be accessible from users' browsers.

Redirect URI table​

ComponentRedirect URI patternExample (localhost)Example (Ingress)
Management Identity<IDENTITY_URL>/auth/login-callbackhttp://localhost:8084/auth/login-callbackhttps://camunda.example.com/identity/auth/login-callback
Orchestration Cluster<OC_URL>/sso-callbackhttp://localhost:8080/sso-callbackhttps://camunda.example.com/orchestration/sso-callback
Optimize<OPTIMIZE_URL>/api/authentication/callbackhttp://localhost:8083/api/authentication/callbackhttps://camunda.example.com/optimize/api/authentication/callback
Web Modeler UI<WEB_MODELER_URL>/login-callbackhttp://localhost:8070/login-callbackhttps://camunda.example.com/modeler/login-callback
Console<CONSOLE_URL>/http://localhost:8087/https://camunda.example.com/

Replace <*_URL> with the actual base URL where each component will be accessible. Use the localhost examples if testing locally with port forwarding, or the Ingress examples if exposing components via Ingress.

Security note

Redirect URIs are security-critical. Only the URIs you configure in your OIDC provider are permitted as redirection targets after authentication. Ensure these values match the redirectUrl parameters you'll set in the Helm configuration.

Wildcard support

Some OIDC providers support wildcard redirect URIs (e.g., https://camunda.example.com/*). Check your provider's documentation to see if this can simplify your configuration.

Discover provider configuration​

Since OIDC providers vary in their implementation details, you need to obtain the specific values from your provider.

Find OIDC endpoints​

Most OIDC providers expose a discovery document at:

https://your-provider.example.com/.well-known/openid-configuration

Access this URL (replacing your-provider.example.com with your provider's domain) to retrieve a JSON document containing endpoint URLs.

Example discovery document​

{
"issuer": "https://your-provider.example.com",
"authorization_endpoint": "https://your-provider.example.com/oauth/authorize",
"token_endpoint": "https://your-provider.example.com/oauth/token",
"jwks_uri": "https://your-provider.example.com/.well-known/jwks.json",
...
}

Record these values for Helm configuration​

  • issuer → Used for: publicIssuerUrl
  • authorization_endpoint → Used for: authUrl
  • token_endpoint → Used for: tokenUrl
  • jwks_uri → Used for: jwksUrl

Identify token claims​

Camunda needs to know which claims in access tokens identify users and clients. Claim names vary by provider.

You need to identify:

  • User identification claim (usernameClaim): Identifies users during web login (for example, email, preferred_username).
  • Client identification claim (clientIdClaim): Identifies calling applications for M2M authentication (for example, client_id, azp).
  • Audience claim (audience): The expected aud value in tokens.

For detailed instructions on obtaining and decoding tokens to identify these claims, see JWT token claims reference.

Scopes requested by Camunda​

Camunda components request OIDC scopes when authenticating users. The default scopes vary by component:

ScopeDescriptionManagement Identity, Optimize, Web Modeler, ConsoleOrchestration Cluster applications (Identity, Operate, Tasklist)
openidRequired for OIDC authentication.✔✔
profileAccess to user profile information.✔✔
emailAccess to user email address.✔
offline_accessEnables refresh token issuance.✔
info

If your provider supports the offline_access scope, components will receive refresh tokens. This allows sessions to remain active longer without requiring users to re-authenticate.

If offline_access is not available or not granted, users will be redirected to your OIDC provider for re-authentication when their access token expires.

For more information, see OpenID Connect Core specification.

Handle separate access token and ID token signing keys​

Most OIDC providers sign access tokens and ID tokens with the same key, published at the single jwks_uri in the discovery document. Some enterprise identity provider deployments sign access tokens with a different key than ID tokens. Camunda validates access tokens on every API request and ID tokens only during the login callback, so if you configure only the discovery document's jwksUrl, access token validation fails even though login succeeds.

To check whether this applies to your provider, compare the jwks_uri in the discovery document against the JWKS endpoint listed for access tokens (or API and runtime tokens) in your provider's admin console. If both are the same URL, skip this section.

If the URLs differ, configure both endpoints:

  • Set global.identity.auth.jwksUrl to the access token JWKS endpoint. Management Identity validates access tokens using this single URL only, and doesn't call the userinfo endpoint or fall back to any other source.

  • Add the same URL as an additional JWKS source for the Orchestration Cluster, which otherwise fetches only the primary JWKS from the discovery document:

    orchestration:
    env:
    - name: CAMUNDA_SECURITY_AUTHENTICATION_OIDC_ADDITIONALJWKSETURIS_0_
    value: "<access-token-jwks-url>"

    This setting has no dedicated Helm value. It maps to the Spring Boot list property camunda.security.authentication.oidc.additionalJwkSetUris, set through orchestration.env using Spring's relaxed-binding convention for list properties: one environment variable per index, with the index surrounded by underscores (..._0_, ..._1_, and so on).

The Orchestration Cluster merges keys from the primary JWKS endpoint and all additional endpoints, then selects whichever key matches the kid in the incoming token. Both ID tokens and access tokens then validate correctly, regardless of which key set signed them.

Create secrets​

Create a secret in your Kubernetes namespace that contains all OIDC client secrets:

kubectl create secret generic oidc-credentials \
--from-literal=identity-client-secret="<identity-client-secret>" \
--from-literal=orchestration-client-secret="<orchestration-client-secret>" \
--from-literal=optimize-client-secret="<optimize-client-secret>" \
--from-literal=webmodeler-api-client-secret="<web-modeler-api-client-secret>"
info

The secret key webmodeler-api-client-secret is not used elsewhere in this guide. This client is intended for your own use if you want to access the Web Modeler API programmatically.

The PostgreSQL credentials for Management Identity and Camunda Hub are no longer created here. They are provided by the operator (or managed database) that hosts each database, such as the pg-identity-secret and pg-hub-secret created by the CloudNativePG operator.

Alternative secret management

For production deployments, consider using external secret management solutions. See External Kubernetes secrets for more options.

Configure Camunda components​

Configure Camunda components to use your OIDC provider through Helm values.

Global OIDC configuration​

Start with the global configuration that applies to all components:

global:
security:
authentication:
method: oidc

identity:
auth:
enabled: true
type: "GENERIC"

publicIssuerUrl: <issuer-url>
issuerBackendUrl: <issuer-url>
authUrl: <authorization-endpoint-url>
tokenUrl: <token-endpoint-url>
jwksUrl: <jwks-endpoint-url>

Parameter descriptions​

ParameterDescriptionExample
publicIssuerUrlIssuer URL accessible from users' browsershttps://login.example.com
issuerBackendUrlIssuer URL accessible from Kubernetes podshttps://login.example.com or http://oidc-internal.svc.cluster.local
authUrlAuthorization endpoint (must be accessible from browsers)https://login.example.com/oauth/authorize
tokenUrlToken endpoint (must be accessible from pods)https://login.example.com/oauth/token
jwksUrlJWKS endpoint for token signature verificationhttps://login.example.com/.well-known/jwks.json
Network accessibility

For generic OIDC providers, the Issuer URL must be accessible from both:

  1. Users' browsers: To redirect users to the login page.
  2. Camunda components (backend): To fetch the provider's configuration and validate tokens.

Split-horizon DNS setups (where the provider has different URLs for internal and external access) are not supported for generic OIDC providers. Ensure your OIDC provider is exposed via a URL that is resolvable and reachable from both locations.

Configure Management Identity​

Add configuration for Management Identity:

global:
identity:
auth:
identity:
clientId: <identity-client-id>
audience: <identity-audience>
secret:
existingSecret: oidc-credentials
existingSecretKey: identity-client-secret
initialClaimName: <user-claim-name>
initialClaimValue: <admin-user-claim-value>

identity:
fullURL: <identity-base-url>
enabled: true
externalDatabase:
enabled: true
host: pg-identity-rw
port: 5432
database: identity
username: identity
secret:
existingSecret: pg-identity-secret
existingSecretKey: password

Management Identity requires an externally managed PostgreSQL database. Provision the database before you deploy, and adapt the connection values and secret references to your setup. For the full parameter list, see Use external PostgreSQL.

Identity-specific parameters​

ParameterDescriptionHow to Determine
clientIdClient ID from your OIDC providerFrom your Identity client configuration
audienceExpected audience in access tokensThe unique value you assigned in Assign a unique audience to each component
initialClaimNameClaim that identifies the initial admin useremail, sub, or another user claim from token inspection
initialClaimValueValue granting initial admin accessYour admin user's value for the specified claim (e.g., admin@example.com)
Initial claim cannot be changed

The initialClaimName and initialClaimValue parameters are used only during the first startup to grant initial admin access. Once Management Identity has started, these values are stored in the database and cannot be changed via Helm values.

Configure Orchestration Cluster​

Add configuration for the Orchestration Cluster (Zeebe, Operate, Tasklist, Identity):

orchestration:
enabled: true

security:
authentication:
method: oidc
oidc:
clientId: <orchestration-client-id>
audience: <orchestration-audience>
redirectUrl: <orchestration-base-url>
secret:
existingSecret: oidc-credentials
existingSecretKey: orchestration-client-secret
# Claim mapping - uncomment and adjust if your provider doesn't use defaults
# usernameClaim: <user-claim-name> # Default: preferred_username
# clientIdClaim: <client-claim-name> # Default: client_id

authorizations:
enabled: true

initialization:
defaultRoles:
admin:
users:
- <admin-user-claim-value>
connectors:
clients:
- <orchestration-client-id>

Orchestration-specific parameters​

ParameterDescriptionValue
clientIdOrchestration client IDFrom your provider
audienceExpected audience in tokensThe unique value you assigned in Assign a unique audience to each component
redirectUrlFull URL for Orchestration Clusterhttp://localhost:8080 (local) or https://your-domain.com/orchestration (Ingress)
usernameClaimClaim identifying usersDefault: preferred_username. Override if your provider uses email, sub, or another claim
clientIdClaimClaim identifying clientsDefault: client_id. Override if your provider uses azp or another claim
Username display in Web Modeler (Helm)

In Helm deployments, the default OIDC username claim is preferred_username, which often maps to an email address.

If you want Web Modeler to display usernames based on a different claim (for example name), set CAMUNDA_IDENTITY_USERNAMECLAIM=name for the Web Modeler restapi environment.

For available Web Modeler environment variables, see Identity/Keycloak configuration.

Default roles​

  • admin.users: List of user claim values that should have admin access.
  • connectors.clients: List of client IDs that should have Connectors role (typically the orchestration client ID itself).
note

The admin user specified in defaultRoles.admin.users should match the value used for initialClaimValue in Management Identity configuration, so that the same user has admin access to both Management Identity and the Orchestration Cluster.

Configure Connectors​

Add configuration for Connectors:

connectors:
enabled: true
security:
authentication:
method: oidc
oidc:
clientId: <orchestration-client-id>
audience: <orchestration-audience>
secret:
existingSecret: oidc-credentials
existingSecretKey: orchestration-client-secret
Connectors shares credentials

Connectors calls the Orchestration Cluster as a client, so it deliberately reuses the Orchestration Cluster's OIDC client and audience. This is a scoped exception to the unique audience guidance. If you prefer a separate OIDC client for Connectors, you must also configure the Orchestration Cluster to accept that client's audience.

Configure Optimize​

Add configuration for Optimize:

global:
identity:
auth:
optimize:
clientId: <optimize-client-id>
audience: <optimize-audience>
redirectUrl: <optimize-base-url>
secret:
existingSecret: oidc-credentials
existingSecretKey: optimize-client-secret

optimize:
enabled: true

Optimize parameters​

ParameterValue
clientIdOptimize client ID from your provider
audienceThe unique value you assigned in Assign a unique audience to each component
redirectUrlhttp://localhost:8083 (local) or https://your-domain.com/optimize (Ingress)

Configure Web Modeler​

Web Modeler requires two OIDC clients: one for the UI (public) and one for the API (confidential).

note

If your IdP provides user-friendly names in the name claim, and you want Web Modeler to use that claim, configure the Web Modeler restapi environment variable CAMUNDA_IDENTITY_USERNAMECLAIM=name. Without this override, Helm defaults typically resolve usernames from preferred_username.

global:
identity:
auth:
webModeler:
clientId: <web-modeler-ui-client-id>
redirectUrl: <web-modeler-base-url>
clientApiAudience: <web-modeler-ui-audience>
publicApiAudience: <web-modeler-api-audience>

camundaHub:
enabled: true # Deploys both Console and Web Modeler
restapi:
mail:
fromAddress: noreply@example.com # Update with your email address
# Additional SMTP configuration may be required - see Web Modeler docs
externalDatabase:
host: pg-hub-rw
port: 5432
database: hub
username: hub
secret:
existingSecret: pg-hub-secret
existingSecretKey: password

Web Modeler parameters​

ParameterDescriptionValue
clientIdWeb Modeler UI client ID (public client)From your provider
redirectUrlFull URL for Web Modelerhttp://localhost:8070 (local) or https://your-domain.com/modeler (Ingress)
clientApiAudienceAudience for UI-to-API communicationA unique value for the Web Modeler client API. Must differ from every other component's audience.
publicApiAudienceAudience for external API accessThe API client ID or custom audience

Email configuration​

Web Modeler requires email configuration for notifications. Update restapi.mail.fromAddress with an appropriate sender address.

For full SMTP configuration, see Web Modeler configuration.

Configure Console​

Add configuration for Console:

global:
identity:
auth:
console:
clientId: <console-client-id>
audience: <console-audience>
redirectUrl: <console-base-url>

Console is deployed as part of Camunda Hub, which you enable with camundaHub.enabled: true in the Web Modeler step. Replace <console-base-url> with the base URL where Console will be accessible. For local deployment, use http://localhost:8087.

Complete configuration example​

Below is a complete Helm values file with all components configured:

global:
security:
authentication:
method: oidc

identity:
auth:
enabled: true
type: "GENERIC"

# OIDC Provider Endpoints
publicIssuerUrl: <issuer-url>
issuerBackendUrl: <issuer-url>
authUrl: <authorization-endpoint-url>
tokenUrl: <token-endpoint-url>
jwksUrl: <jwks-endpoint-url>

# Management Identity
identity:
clientId: <identity-client-id>
audience: <identity-audience>
secret:
existingSecret: oidc-credentials
existingSecretKey: identity-client-secret
initialClaimName: <user-claim-name>
initialClaimValue: <admin-user-claim-value>

# Optimize
optimize:
clientId: <optimize-client-id>
audience: <optimize-audience>
redirectUrl: <optimize-url>
secret:
existingSecret: oidc-credentials
existingSecretKey: optimize-client-secret

# Web Modeler
webModeler:
clientId: <web-modeler-ui-client-id>
redirectUrl: <web-modeler-url>
clientApiAudience: <web-modeler-ui-audience>
publicApiAudience: <web-modeler-api-audience>

# Console
console:
clientId: <console-client-id>
audience: <console-audience>
redirectUrl: <console-url>

# Orchestration Cluster
orchestration:
enabled: true
security:
authentication:
method: oidc
oidc:
clientId: <orchestration-client-id>
audience: <orchestration-audience>
redirectUrl: <orchestration-url>
secret:
existingSecret: oidc-credentials
existingSecretKey: orchestration-client-secret
# The following claim mappings use Camunda defaults and usually don't need to be changed.
# Only uncomment if your decoded access token uses different claim names:
# usernameClaim: email # Use if tokens identify users with 'email' instead of 'preferred_username'
# clientIdClaim: azp # Use if tokens identify clients with 'azp' instead of 'client_id'
authorizations:
enabled: true
initialization:
defaultRoles:
admin:
users:
- <admin-user-claim-value>
connectors:
clients:
- <orchestration-client-id>

# Connectors
connectors:
enabled: true
security:
authentication:
method: oidc
oidc:
clientId: <orchestration-client-id>
audience: <orchestration-audience>
secret:
existingSecret: oidc-credentials
existingSecretKey: orchestration-client-secret

# Management Identity
identity:
fullURL: <identity-base-url>
enabled: true
externalDatabase:
enabled: true
host: pg-identity-rw
port: 5432
database: identity
username: identity
secret:
existingSecret: pg-identity-secret
existingSecretKey: password
# Optimize
optimize:
enabled: true

# Console and Web Modeler (Camunda Hub)
camundaHub:
enabled: true # Deploys both Console and Web Modeler
restapi:
mail:
fromAddress: <your-email-address>
externalDatabase:
host: pg-hub-rw
port: 5432
database: hub
username: hub
secret:
existingSecret: pg-hub-secret
existingSecretKey: password

Placeholders to replace:

PlaceholderReplace with
https://your-provider.example.comYour OIDC provider's issuer URL
identity, orchestration, optimize, etc.Your actual client IDs
identity, orchestration, optimize (audience values)The unique audience you assigned to each component
admin@example.comYour admin user's claim value

Verify before deploying​

  • All <placeholders> replaced with actual values.
  • All client secrets stored in the oidc-credentials secret.
  • Database credentials provided by the operator-managed database secrets (for example, pg-identity-secret and pg-hub-secret).
  • Redirect URIs in OIDC provider match redirectUrl values.
  • Each component has a distinct resource audience by default. Any cross-component audience acceptance supports a documented integration.
  • Verify tokens contain preferred_username and client_id claims, or uncomment and configure alternative claim names.

Connect to the cluster​

After deploying Camunda with this configuration, use the following kubectl port-forward commands to access the APIs and UIs:

# Management Identity
kubectl port-forward svc/camunda-identity 8084:80

# Orchestration Cluster (Operate/Tasklist)
kubectl port-forward svc/camunda-zeebe-gateway 8080:8080

# Zeebe Gateway (gRPC for clients)
kubectl port-forward svc/camunda-zeebe-gateway 26500:26500

# Optimize
kubectl port-forward svc/camunda-optimize 8083:80

# Web Modeler
kubectl port-forward svc/camunda-web-modeler-restapi 8070:80
kubectl port-forward svc/camunda-web-modeler-websockets 8085:80

# Console
kubectl port-forward svc/camunda-console 8087:80

Once port forwarding is active, access each component through http://localhost:<port>. For example, Management Identity at http://localhost:8084 or the Orchestration Cluster at http://localhost:8080 (which redirects to your OIDC provider for login).

Redirect URI configuration

Ensure your redirect URIs in your OIDC provider match how you're accessing Camunda. If you configured redirect URIs for localhost testing (e.g., http://localhost:8080/sso-callback), the port-forward commands above will work. If you configured redirect URIs for Ingress (e.g., https://camunda.example.com/orchestration/sso-callback), you'll need to access via Ingress instead.

For production deployments, configure Ingress to expose components. See Ingress configuration for more details.

Grant access to components​

After deployment, you must configure access for the following components.

To grant a user access to the Web Modeler UI:

To grant a client access to the Web Modeler API:

To grant a user access to Optimize:

info

When using an OIDC provider, the following Optimize features are not currently available:

  • The User permissions tab in collections.
  • The Alerts tab in collections.
  • Digests.
  • Accessible user names for resource owners (the value of the sub claim is displayed instead).