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

Set up the Helm chart with an external Microsoft Entra tenant

This guide shows you how to configure the Helm chart to use a Microsoft Entra tenant, with each Camunda component using a dedicated OIDC or OAuth client.

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.

Prerequisites​

Before you begin, ensure you have:

  • Access to a Microsoft Entra tenant with permission to create applications and app registrations
  • The ID of your tenant
  • An understanding of the structure and claims of access tokens in Entra
  • 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.

If your Entra issuer presents a certificate signed by a private or internal certificate authority, Camunda components don't trust certificates signed by that CA by default.

Configure TLS trust to avoid PKIX path building failed errors when components connect to the issuer.

Configuration​

To use Microsoft Entra, complete the following steps:

  1. Ensure Entra prerequisites
  2. Create applications in Entra
  3. Create secrets
  4. Configure components using OIDC
  5. Configure machine-to-machine (M2M) API access

See the full configuration example for the complete setup.

Ensure Entra prerequisites​

For authentication, the Camunda components use the following scopes: email, openid, offline_access, profile, and <CLIENT_UUID>/.default.

Optional scopes

The offline_access scope is optional.

If this scope is included, your OIDC provider issues a refresh token to Camunda components on user login. The components use the refresh token to renew the user's access token when it expires, so that sessions remain active without requiring the user to log in again.

If offline_access is not included, users will be redirected to the OIDC provider for re-authentication whenever their access token expires. For more information, see the OpenID Connect Core specification.

To allow users to successfully authenticate with Entra ID, you must either configure an admin consent workflow or grant consent on behalf of your users using admin consent.

The applications you configure in this guide must support the following grant_type values:

  • To create an M2M token: client_credentials (response contains an access token)
  • To renew a token using a refresh token: refresh_token
  • To create a token via authorization code flow: authorization_code (response contains access and refresh tokens)

These grant types are enabled by default, but they may be restricted by custom policies in your organization.

Disable UserInfo for Entra

Microsoft Entra's /userinfo endpoint is served by Microsoft Graph, which requires the access token to have a Graph audience. The <CLIENT_UUID>/.default scope used in this guide audiences the token to the Camunda client instead, so Entra always rejects the call. Set user-info-enabled: false for this provider to skip it. See troubleshoot OIDC authentication for details.

Create applications in Entra​

Before configuring Camunda, create the following app registrations that map to Camunda components.

Application type Web:

  • Management Identity (<mgmt-identity-app>)
  • Orchestration Cluster (<oc-app>)
  • Optimize (<optimize-app>)
  • Web Modeler API (<web-modeler-api-app>)

Application type Single-page application:

  • Console (<console-app>)
  • Web Modeler UI (<web-modeler-ui-app>)

Register these as six separate applications. Camunda uses each application's client ID as that component's audience, so two components sharing a registration also share an audience, and a token issued for one is accepted by the other. Entra issues the same tenant-scoped iss claim for every application in your tenant, which makes the audience the only value that distinguishes one component from another.

For each of the components above:

  1. In the Entra ID admin center, register the application.

  2. On the application's Overview page, note the Client ID.

  3. In the app registration, configure a platform that matches the component:

    • Web: Management Identity, Orchestration Cluster, Optimize, Web Modeler API
    • Single-page application: Console, Web Modeler UI
  4. Add the component's redirect URI from the table below.

    note

    Redirect URIs are an allowlist. Only the URIs you define are permitted as redirection targets after authentication. This ensures that tokens and authorization codes are only sent to approved destinations.

  5. For app registrations of type Web, create a new client secret, and record the secret value. You do not need the secret ID.

  6. Enable the Entra v2.0 API by opening the application's manifest and setting the requestedAccessTokenVersion property under api to 2:

    api: {
    ...
    "requestedAccessTokenVersion": 2,
    ...
    }
  7. In Token configuration, add the optional claim preferred_username to both the access token and the ID token. Entra labels this claim optional, but Camunda requires it.

    Management Identity reads user claims directly from the access token rather than from a userinfo call. If preferred_username is missing from the access token, Management Identity finds no matching claim and grants no roles. The user authenticates successfully, then immediately sees a 403 unauthorized error, and users appear in Operate and Tasklist with an opaque identifier instead of their name.

    To use a different claim that uniquely identifies your users, see Configure Management Identity. Whichever claim you choose, add it as an optional claim on both token types, since Entra doesn't include it by default.

Redirect URIs per Camunda component​

ComponentRedirect URI for the Entra app registrationRedirect URI for local deployment
Management Identity<IDENTITY_URL>/auth/login-callbackhttp://localhost:8084/auth/login-callback
Orchestration Cluster<OC_URL>/sso-callbackhttp://localhost:8080/sso-callback
Optimize<OPTIMIZE_URL>/api/authentication/callbackhttp://localhost:8083/api/authentication/callback
Web Modeler UI<WEB_MODELER_URL>/login-callbackhttp://localhost:8070/login-callback
Console<CONSOLE_URL>/http://localhost:8087/

Replace each *_URL placeholder with the base URL (in the format <protocol>://<host/ip>:<port>/<context-path>) that will be accessible from your users’ browsers. If you plan to expose the services only on localhost (as described later in this guide), you can use the URIs in the local deployment column directly.

Create secrets​

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

kubectl create secret generic entra-credentials \
--from-literal=identity-client-secret="<mgmt-identity-app-secret>" \
--from-literal=orchestration-cluster-client-secret="<oc-app-secret>" \
--from-literal=optimize-client-secret="<optimize-application-secret>" \
--from-literal=webmodeler-api-client-secret="<web-modeler-api-app-secret>"
info

In Microsoft Entra, the term application secret is used. In Camunda configuration, this value is referred to as a client secret to align with OIDC/OAuth standards.

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.

For additional options on how to create and reference Kubernetes secrets (for example using YAML manifests or consolidated secrets), see External Kubernetes secrets.

Configure components using OIDC​

With the OIDC clients and cluster secrets in place, configure OAuth and OIDC for the components. You can skip components you don’t plan to run. Keep in mind that the Orchestration Cluster and Connectors are enabled by default, so you must explicitly disable them if not needed.

Global configuration​

Start with the following global configuration, which provides defaults for all components:

global:
identity:
auth:
enabled: true
issuer: https://login.microsoftonline.com/<tenant id>/v2.0
issuerBackendUrl: https://login.microsoftonline.com/<tenant id>/v2.0
authUrl: https://login.microsoftonline.com/<tenant id>/oauth2/v2.0/authorize
tokenUrl: https://login.microsoftonline.com/<tenant id>/oauth2/v2.0/token
jwksUrl: https://login.microsoftonline.com/<tenant id>/discovery/v2.0/keys
type: "MICROSOFT"
security:
authentication:
method: oidc

Replace <tenant id> with your Microsoft Entra tenant ID. You’ll use this convention throughout the rest of this guide.

Configure Orchestration Cluster​

Add the following configuration for the Orchestration Cluster:

orchestration:
security:
authentication:
oidc:
clientId: "<oc-app-id>"
audience: "<oc-app-id>"
usernameClaim: preferred_username
clientIdClaim: azp
preferUsernameClaim: true
redirectUrl: "<OC_URL>"
scope:
- openid
- profile
- offline_access
- "<oc-app-id>/.default"
secret:
existingSecret: "entra-credentials"
existingSecretKey: "orchestration-cluster-client-secret"
initialization:
defaultRoles:
admin:
users:
- "<the email address of your initial admin user>"
connectors:
clients:
- "<oc-app-id>"
env:
- name: CAMUNDA_SECURITY_AUTHENTICATION_OIDC_USER_INFO_ENABLED
value: "false"
- name: SERVER_MAX_HTTP_REQUEST_HEADER_SIZE
value: "65536"

Replace <OC_URL> with the base URL of the Orchestration Cluster as it will be reachable from your users’ browsers. For local deployment, this is http://localhost:8080.

The two environment variables above are both required with Entra. Neither has a dedicated Helm value, so both are passed through orchestration.env as Spring Boot properties (camunda.security.authentication.oidc.user-info-enabled and server.max-http-request-header-size).

CAMUNDA_SECURITY_AUTHENTICATION_OIDC_USER_INFO_ENABLED must be false. By default, the Orchestration Cluster calls the OIDC userinfo endpoint after authentication to augment token claims. Entra hosts its userinfo endpoint on Microsoft Graph (graph.microsoft.com/oidc/userinfo) rather than on the authorization server, and it requires a Graph API access token instead of the OIDC access token Camunda holds, so the call fails. Setting this variable to false tells the Orchestration Cluster to rely on the claims already present in the token. This is also Microsoft's recommendation, since the ID token is a superset of what userinfo returns.

SERVER_MAX_HTTP_REQUEST_HEADER_SIZE raises the maximum header size to 64 KB. Microsoft's authorization codes are longer than those issued by most other providers. Combined with session cookies from an existing session, the total HTTP header size can exceed Tomcat's 8 KB default, which causes a plain Tomcat HTTP 400 error page before Spring Security processes the request. See Request header is too large if you hit this after deploying.

usernameClaim defines which claim in the access token identifies the user. clientIdClaim defines which claim identifies the calling client. By default:

  • preferred_username carries the user’s email address.
  • azp carries the client ID in Entra.

You can adjust these values if your organization uses different claim mappings. For more information, see the Orchestration Cluster OIDC configuration guide.

Username display in Web Modeler (Helm)

With Helm defaults, usernames are typically resolved from preferred_username. If you want Web Modeler to use the name claim instead (for example, to show display names), set CAMUNDA_IDENTITY_USERNAMECLAIM=name for the Web Modeler restapi environment.

See Identity/Keycloak configuration.

Configure Connectors​

Add the following configuration for Connectors:

connectors:
security:
authentication:
oidc:
clientId: "<oc-app-id>"
audience: "<oc-app-id>"
tokenScope: "<oc-app-id>/.default"
secret:
existingSecret: "entra-credentials"
existingSecretKey: "orchestration-cluster-client-secret"

Configure Management Identity​

Add the following configuration for Management Identity:

global:
identity:
auth:
identity:
clientId: "<mgmt-identity-app-id>"
audience: "<mgmt-identity-app-id>"
initialClaimName: preferred_username
initialClaimValue: "<the email address of your initial admin user>"
secret:
existingSecret: "entra-credentials"
existingSecretKey: "identity-client-secret"

identity:
enabled: true
externalDatabase:
enabled: true
host: pg-identity-rw
port: 5432
database: identity
username: identity
secret:
existingSecret: pg-identity-secret
existingSecretKey: password

Replace <IDENTITY_URL> with the base URL of Management Identity as it will be reachable from your users' browser. For local deployment, use http://localhost:8084.

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

  • initialClaimName defines which claim in the access token identifies the initial administrative user.
  • initialClaimValue defines the value of that claim that grants administrative access to Management Identity.

Choose the claim based on whether you value readability or stability:

ClaimTrade-off
preferred_usernameThe user's UPN. Readable and self-documenting, which makes it easy to work with during initial setup. Requires the optional claim to be added.
oidThe user's Entra Object ID. Always present without optional claim configuration, and unchanged if the user's email address changes.

Because initialClaimValue is applied only on first startup and can't be updated through Helm afterward, oid is the more stable choice for production.

danger

Once configured, the initial claim name and value cannot be changed using environment variables or Helm values. To update them, modify the Identity PostgreSQL database directly.

tip

If Optimize is not enabled, add the following environment variable to ensure Management Identity starts successfully:

identity:
env:
- name: CAMUNDA_IDENTITY_AUDIENCE
value: "<mgmt-identity-app-id>"

Configure Optimize​

Add the following configuration for Optimize:

global:
identity:
auth:
optimize:
clientId: "<optimize-app-id>"
audience: "<optimize-app-id>"
redirectUrl: "<OPTIMIZE_URL>"
secret:
existingSecret: "entra-credentials"
existingSecretKey: "optimize-client-secret"

optimize:
enabled: true

Replace <OPTIMIZE_URL> with the base URL of Optimize as it will be reachable from your users' browser. For local deployment, use http://localhost:8083.

Configure Web Modeler​

Add the following configuration for Web Modeler:

note

If you want Web Modeler to resolve usernames from the name claim instead of preferred_username, add CAMUNDA_IDENTITY_USERNAMECLAIM=name to the Web Modeler restapi environment configuration.

global:
identity:
auth:
webModeler:
clientId: "<web-modeler-ui-app-id>"
clientApiAudience: "<web-modeler-ui-app-id>"
publicApiAudience: "<web-modeler-api-app-id>"
redirectUrl: "<WEB_MODELER_URL>"

camundaHub:
enabled: true # Deploys both Console and Web Modeler
restapi:
mail:
fromAddress: noreply@example.com
externalDatabase:
host: pg-hub-rw
port: 5432
database: hub
username: hub
secret:
existingSecret: pg-hub-secret
existingSecretKey: password

Replace <WEB_MODELER_URL> with the base URL of Web Modeler as it will be reachable from your users' browser. For local deployment, use http://localhost:8070.

Web Modeler requires an externally managed PostgreSQL database, configured under camundaHub.restapi.externalDatabase. Provision the database before deploying. For the full parameter list, see Use external PostgreSQL.

You can update camundaHub.restapi.mail.fromAddress with an address suitable for your environment. This address appears as the sender in emails sent by Web Modeler. For more details on configuring email delivery, see the Camunda Hub section in Enable additional Camunda components.

Configure Console​

Add the following configuration for Console:

global:
identity:
auth:
console:
clientId: "<console-app-id>"
audience: "<console-app-id>"
redirectUrl: "http://localhost:8087"

Console is deployed by Camunda Hub, which you enabled in the Configure Web Modeler step; the configuration above only defines its OIDC client.

Full configuration example​

The following example shows a full configuration to enable Microsoft Entra with an externally managed Elasticsearch cluster. Replace <elasticsearch-host> with the hostname of your cluster.

global:
identity:
auth:
enabled: true
issuer: https://login.microsoftonline.com/<tenant id>/v2.0
issuerBackendUrl: https://login.microsoftonline.com/<tenant id>/v2.0
authUrl: https://login.microsoftonline.com/<tenant id>/oauth2/v2.0/authorize
tokenUrl: https://login.microsoftonline.com/<tenant id>/oauth2/v2.0/token
jwksUrl: https://login.microsoftonline.com/<tenant id>/discovery/v2.0/keys
type: "MICROSOFT"
identity:
clientId: "<mgmt-identity-app-id>"
audience: "<mgmt-identity-app-id>"
initialClaimName: preferred_username
initialClaimValue: "<the email address of your initial admin user>"
secret:
existingSecret: "entra-credentials"
existingSecretKey: "identity-client-secret"
optimize:
clientId: "<optimize-app-id>"
audience: "<optimize-app-id>"
redirectUrl: "<OPTIMIZE_URL>"
secret:
existingSecret: "entra-credentials"
existingSecretKey: "optimize-client-secret"
webModeler:
clientId: "<web-modeler-ui-app-id>"
clientApiAudience: "<web-modeler-ui-app-id>"
publicApiAudience: "<web-modeler-api-app-id>"
redirectUrl: "<WEB_MODELER_URL>"
console:
clientId: "<console-app-id>"
audience: "<console-app-id>"
redirectUrl: "http://localhost:8087"
security:
authentication:
method: oidc

orchestration:
data:
secondaryStorage:
type: elasticsearch
elasticsearch:
url: "https://<elasticsearch-host>:9200"
security:
authentication:
oidc:
clientId: "<oc-app-id>"
audience: "<oc-app-id>"
usernameClaim: preferred_username
clientIdClaim: azp
preferUsernameClaim: true
redirectUrl: "<OC_URL>"
scope:
- openid
- profile
- offline_access
- "<oc-app-id>/.default"
secret:
existingSecret: "entra-credentials"
existingSecretKey: "orchestration-cluster-client-secret"
initialization:
defaultRoles:
admin:
users:
- "<the email address of your initial admin user>"
connectors:
clients:
- "<oc-app-id>"
env:
- name: CAMUNDA_SECURITY_AUTHENTICATION_OIDC_USER_INFO_ENABLED
value: "false"
- name: SERVER_MAX_HTTP_REQUEST_HEADER_SIZE
value: "65536"

connectors:
security:
authentication:
oidc:
clientId: "<oc-app-id>"
audience: "<oc-app-id>"
tokenScope: "<oc-app-id>/.default"
secret:
existingSecret: "entra-credentials"
existingSecretKey: "orchestration-cluster-client-secret"

identity:
enabled: true
externalDatabase:
enabled: true
host: pg-identity-rw
port: 5432
database: identity
username: identity
secret:
existingSecret: pg-identity-secret
existingSecretKey: password
optimize:
enabled: true
database:
elasticsearch:
enabled: true
external: true
url:
protocol: https
host: "<elasticsearch-host>"
port: 9200

camundaHub:
enabled: true # Deploys both Console and Web Modeler
restapi:
mail:
fromAddress: noreply@example.com
externalDatabase:
host: pg-hub-rw
port: 5432
database: hub
username: hub
secret:
existingSecret: pg-hub-secret
existingSecretKey: password

Connect to the cluster​

After applying this configuration, use the following kubectl port-forward commands to access the APIs and UIs from your localhost:

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

# Orchestration Cluster
kubectl port-forward svc/camunda-zeebe-gateway 8080:8080
kubectl port-forward svc/camunda-zeebe-gateway 26500:26500

# Connectors
kubectl port-forward svc/camunda-connectors 8086:8080

# 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:

  • Orchestration Cluster: http://localhost:8080 (redirects you to Entra for login)
  • Management Identity: http://localhost:8084
  • Console: http://localhost:8087

Configure machine-to-machine (M2M) API access​

Job workers, Connectors, and other applications that call the Orchestration Cluster REST or gRPC API without a user present use the OAuth client credentials grant instead of interactive login.

In this section, you register a dedicated Entra application for M2M access and configure a Camunda client to use it.

For the general, provider-agnostic explanation of this flow, see machine-to-machine (M2M) API access.

Register an M2M application in Entra​

  1. In the Entra ID admin center, register a new application for your job worker or Connector. You do not need to configure a redirect URI or a platform type, since this application never redirects a user's browser.
  2. On the application's Overview page, note the Client ID. This value is your M2M client's clientId.
  3. Create a new client secret and record the secret value.
  4. Confirm the application supports the client_credentials grant type. This is enabled by default; see Ensure Entra prerequisites.
  5. Grant the application access to the Orchestration Cluster API. Reuse the <oc-app-id>/.default scope from the Orchestration Cluster app registration, or expose an API permission specific to your M2M client and grant admin consent for it.

Configure the Camunda client​

Configure your job worker, Connector runtime, or custom application to request tokens from Entra using client credentials. Camunda clients (the Java client, the Spring Boot starter, and the Connector runtime) read these settings from CAMUNDA_CLIENT_AUTH_* environment variables or the equivalent camunda.client.auth.* properties:

CAMUNDA_CLIENT_AUTH_METHOD=oidc
CAMUNDA_CLIENT_AUTH_CLIENTID=<m2m-app-id>
CAMUNDA_CLIENT_AUTH_CLIENTSECRET=<m2m-app-secret>
CAMUNDA_CLIENT_AUTH_TOKENURL=https://login.microsoftonline.com/<tenant id>/oauth2/v2.0/token
CAMUNDA_CLIENT_AUTH_AUDIENCE=<oc-app-id>
CAMUNDA_CLIENT_AUTH_SCOPE=<oc-app-id>/.default
camunda:
client:
auth:
method: oidc
client-id: <m2m-app-id>
client-secret: <m2m-app-secret>
token-url: https://login.microsoftonline.com/<tenant id>/oauth2/v2.0/token
audience: <oc-app-id>
scope: <oc-app-id>/.default

Replace <oc-app-id> with the Orchestration Cluster application's client ID from Create applications in Entra, and <tenant id> with your Microsoft Entra tenant ID.

note

For the client credentials flow, request the <oc-app-id>/.default scope. This tells Entra to issue a token for the statically configured application permissions on the API rather than the delegated permissions used during interactive login.

The Orchestration Cluster identifies this client using the azp claim, configured as clientIdClaim: azp in Configure Orchestration Cluster. By default, requests from this client can only retrieve the cluster topology. To grant it access to other APIs, configure authorizations for its client ID.

Troubleshooting​

For issues common to any OIDC provider (invalid redirect URI, audience mismatch, missing claims, pods not starting), see Troubleshoot OIDC authentication. The following are specific to Microsoft Entra:

AADSTS700016: Application not found in the directory The clientId in your Helm values doesn't match a registered application in your tenant. Verify each clientId exactly matches the Application (client) ID on the app registration's Overview page, and that the app is registered in the tenant identified by your <tenant id>.

AADSTS50011: Redirect URI mismatch The redirect URI Camunda sent doesn't match any URI registered for that app. Verify redirectUrl in your Helm configuration exactly matches the redirect URI configured in Entra, including the path suffix, for example /auth/login-callback or /sso-callback.

401 with jwt issuer invalid or "The iss claim is not valid" The app registration is issuing v1.0 tokens (issuer https://sts.windows.net/...) instead of v2.0 tokens (issuer https://login.microsoftonline.com/.../v2.0). Confirm api.requestedAccessTokenVersion is set to 2 in the app's manifest (see Create applications in Entra). This applies to all app registrations, including single-page applications.

Service-to-service 401 with clientId claim could not be found If Connectors or another machine-to-machine caller gets this error, verify clientIdClaim: azp is set for the Orchestration Cluster. The bare-GUID scope format (<oc-app-id>/.default) causes Entra to issue v2.0 tokens, which carry the calling client's ID in azp rather than the appid claim used by v1.0 tokens.

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).