Zeebe 8.7 + Microsoft Entra ID (Azure AD): supported directly? + Configuration

Camunda version: 8.7 (Zeebe camunda/zeebe:8.7.15)
Deployment: Docker on Linux
Goal: Secure Zeebe gateway with Microsoft Entra ID (formerly Azure AD) without Keycloak

What I tried

I configured the Zeebe gateway to use Identity auth with my Entra tenant:

zeebe: # https://docs.camunda.io/docs/self-managed/platform-deployment/docker/#zeebe
    image: camunda/zeebe:${CAMUNDA_ZEEBE_VERSION}
    container_name: zeebe
    ports:
      - "26500:26500"
      - "9600:9600"
      - "8088:8080"
    environment: # https://docs.camunda.io/docs/self-managed/zeebe-deployment/configuration/environment-variables/
      - ZEEBE_BROKER_GATEWAY_SECURITY_AUTHENTICATION_MODE=${ZEEBE_AUTHENTICATION_MODE}
      - ZEEBE_BROKER_GATEWAY_SECURITY_AUTHENTICATION_IDENTITY_ISSUERBACKENDURL=https://login.microsoftonline.com/<TENANT_ID>/v2.0
      - ZEEBE_BROKER_GATEWAY_SECURITY_AUTHENTICATION_IDENTITY_AUDIENCE=<CLIENT_ID>
      - ZEEBE_BROKER_GATEWAY_SECURITY_AUTHENTICATION_IDENTITY_BASEURL=http://identity:8084
      - ZEEBE_BROKER_GATEWAY_MULTITENANCY_ENABLED=${MULTI_TENANCY_ENABLED}
      - ZEEBE_BROKER_EXPORTERS_ELASTICSEARCH_CLASSNAME=io.camunda.zeebe.exporter.ElasticsearchExporter
      - ZEEBE_BROKER_EXPORTERS_ELASTICSEARCH_ARGS_URL=http://elasticsearch:9200
      - ZEEBE_BROKER_GATEWAY_SECURITY_AUTHENTICATION_IDENTITY_TYPE=AUTH0
      # default is 1000, see here: https://github.com/camunda/zeebe/blob/main/exporters/elasticsearch-exporter/src/main/java/io/camunda/zeebe/exporter/ElasticsearchExporterConfiguration.java#L259
      - ZEEBE_BROKER_EXPORTERS_ELASTICSEARCH_ARGS_BULK_SIZE=1
      # allow running with low disk space
      - ZEEBE_BROKER_DATA_DISKUSAGECOMMANDWATERMARK=0.998
      - ZEEBE_BROKER_DATA_DISKUSAGEREPLICATIONWATERMARK=0.999


      - CAMUNDA_IDENTITY_ISSUERBACKENDURL=https://login.microsoftonline.com/<TENANT_ID_REDACTED>/v2.0
      - CAMUNDA_IDENTITY_TYPE=AUTH0
      - CAMUNDA_IDENTITY_USEBACKENDAUTHURL=true
      - SPRING_PROFILES_ACTIVE=identity-auth
      - "JAVA_TOOL_OPTIONS=-Xms512m -Xmx512m"
      - management.endpoints.web.exposure.include=health,info,metrics,prometheus,configprops
      - MANAGEMENT_ENDPOINT_CONFIGPROPS_SHOW_VALUES=ALWAYS

Error

Zeebe gateway logs show repeated errors when clients call the gateway (e.g., /v1/topology):

java.lang.IllegalStateException: Cannot build provider without domain
  at com.auth0.jwk.JwkProviderBuilder.buildJwkUrl(JwkProviderBuilder.java:65)
  at io.camunda.identity.sdk.impl.auth0.authentication.Auth0Authentication.jwkProvider(Auth0Authentication.java:157)
  ...

And the client receives 401 Unauthorized with detail: "Cannot build provider without domain" (earlier I also saw detail: "JWKS error").

Observation

From /actuator/configprops I can see:

  • identity.type=AUTH0

  • issuerBackendUrl points to the Entra v2.0 endpoint

  • There is no domain value, which the Auth0 provider seems to require.

So it looks like selecting AUTH0 makes the Camunda Identity SDK use the Auth0 Java library, which expects an Auth0 domain (like mytenant.auth0.com) rather than a generic OIDC issuer like Entra’s login.microsoftonline.com/``....

Questions

  1. Is direct Microsoft Entra ID integration supported by Zeebe 8.7 gateway auth?
    Or are the only supported identity.type values truly KEYCLOAK or AUTH0, meaning Entra must be fronted by either:

    • Auth0 (with an Enterprise connection to Entra), or

    • Keycloak (federated to Entra)?

  2. If Entra is supported directly in 8.7, what is the correct set of environment variables?

    • Should I be using issuerBackendUrl alone, and if so, what should identity.type be?
  3. As a sanity check: if I disable gateway auth completely (set ZEEBE_BROKER_GATEWAY_SECURITY_ENABLED=false and ...AUTHENTICATION_MODE=NONE), requests succeed. So the issue is specifically the OIDC wiring.

Any guidance or a sample configuration for Zeebe 8.7 + Entra (without Keycloak) would be much appreciated. If the answer is “not supported directly,” I’ll pivot to Auth0-fronted Entra. Thanks!

Hi @tlmouden - I suspect it’s because you have SPRING_PROFILES_ACTIVE=identity-auth and it should be SPRING_PROFILES_ACTIVE=oidc. As far as I know, you don’t need the CAMUNDA_IDENTITY_TYPE variable. Those are the first two things I noticed while comparing to this guide:

Hi @nathan.loding - When we remove the SPRING_PROFILES_ACTIVE=identity-auth and either we add oidc or just remove it, the REST API becomes unsecured, so the only way to secure zeebe is by adding SPRING_PROFILES_ACTIVE=identity-auth.

As far as I know, the real configuration is very different from what’s on the guide. Note that it’s the same behavior for Operate and Tasklist, they both require SPRING_PROFILES_ACTIVE=identity-auth even if it’s not what’s mentionned in the guide. SPRING_PROFILES_ACTIVE=oidc works only for identity and Optimize.

Note that I test the security by calling the endpoint https://HOST:8088/v1/topology I created an application on Entra ID and tried to generate a token using that application’s clien ID and secret, and I use that token to try to connect to Zeebe.

I found out that I had to add CAMUNDA_IDENTITY_ISSUER=https://login.microsoftonline.com/<TENANT_ID>/v2.0 to avoid the "Cannot build provider without domain" error. But I still get “JWKs error".

So currently I’m not sure what’s the right configuration to add in order to link Zeebe with Microsoft Entra ID. If you can provide the full configuration that will be a great help.

@tlmouden - we have integration tests that run against the release that validate these settings, so I suspect something else is mixed up somewhere. A few questions:

  • the /v1/topology endpoint is deprecated, so there’s possibly issues with it (and possibly issues we need to fix!). What if you try the updated v2 topology endpoint?
  • are you only deploying the gateway? Do you have Identity deployed also?
  • you have some environment variables that are not in the guide, specifically ZEEBE_BROKER_GATEWAY_SECURITY_AUTHENTICATION_IDENTITY_TYPE and CAMUNDA_IDENTITY_TYPE - have you tested with only the variables in the guide? When you set the active profile to “oidc” did you remove these variables also? (Of course, settings such as Elasticsearch classes and disk usage don’t matter for this, I’m only looking at the *_SECURITY and *_IDENTITY variables, as well as SPRING_PROFILES_ACTIVE, which does need to be set to “oidc”)

@nathan.loding - First, I’m not only deploying the Gateway, but all Camunda components.
The Identity service is already running successfully and linked with Entra ID.

Second, after using the following configuration:

environment:
  - ZEEBE_BROKER_GATEWAY_SECURITY_AUTHENTICATION_MODE=${ZEEBE_AUTHENTICATION_MODE}
  - ZEEBE_BROKER_GATEWAY_MULTITENANCY_ENABLED=${MULTI_TENANCY_ENABLED}
  - ZEEBE_BROKER_EXPORTERS_ELASTICSEARCH_CLASSNAME=io.camunda.zeebe.exporter.ElasticsearchExporter
  - ZEEBE_BROKER_EXPORTERS_ELASTICSEARCH_ARGS_URL=http://elasticsearch:9200
  # default is 1000, see: https://github.com/camunda/zeebe/blob/main/exporters/elasticsearch-exporter/src/main/java/io/camunda/zeebe/exporter/ElasticsearchExporterConfiguration.java#L259
  - ZEEBE_BROKER_EXPORTERS_ELASTICSEARCH_ARGS_BULK_SIZE=1
  # allow running with low disk space
  - ZEEBE_BROKER_DATA_DISKUSAGECOMMANDWATERMARK=0.998
  - ZEEBE_BROKER_DATA_DISKUSAGEREPLICATIONWATERMARK=0.999
  - "JAVA_TOOL_OPTIONS=-Xms512m -Xmx512m"
  - management.endpoints.web.exposure.include=health,info,metrics,prometheus,configprops
  - MANAGEMENT_ENDPOINT_CONFIGPROPS_SHOW_VALUES=ALWAYS

  - CAMUNDA_IDENTITY_TYPE=MICROSOFT
  - CAMUNDA_IDENTITY_BASE_URL=http://identity:8084
  - CAMUNDA_IDENTITY_ISSUER=https://login.microsoftonline.com/<TENANT_ID>/v2.0
  - CAMUNDA_IDENTITY_ISSUER_BACKEND_URL=https://login.microsoftonline.com/<TENANT_ID>/v2.0
  - CAMUNDA_IDENTITY_CLIENT_ID=<CLIENT_ID>
  - CAMUNDA_IDENTITY_CLIENT_SECRET=<SECRET>
  - CAMUNDA_IDENTITY_AUDIENCE=<CLIENT_ID>
  - IDENTITY_INITIAL_CLAIM_NAME=oid
  - IDENTITY_INITIAL_CLAIM_VALUE=<USER_OBJECT_ID>
  - SPRING_PROFILES_ACTIVE=oidc

The Zeebe endpoint /v2/topology wasn’t secured — it was accessible without any token or authentication.

However, after switching:

- SPRING_PROFILES_ACTIVE=identity-auth

it started working correctly.
Apparently, the issue was caused by the previous profile (oidc), which interfered with the authentication setup.

Thank you.

@tlmouden - can you share the full Docker config for all components, not just the environment variables for the gateway?

@nathan.loding - Here is the full config file:

# While the Docker images themselves are supported for production usage,
# this docker-compose.yaml is designed to be used by developers to run
# an environment locally. It is not designed to be used in production.
# We recommend to use Kubernetes in production with our Helm Charts:
# https://docs.camunda.io/docs/self-managed/setup/install/
# For local development, we recommend using KIND instead of `docker-compose`:
# https://docs.camunda.io/docs/self-managed/platform-deployment/helm-kubernetes/guides/local-kubernetes-cluster/

# This is a full configuration with Zeebe, Operate, Tasklist, Optimize, Identity, Keycloak, Elasticsearch and Web Modeler.
# See docker-compose-core.yml for a lightweight configuration that does not include Optimize, Identity, and Keycloak.

services:

  zeebe:
    image: camunda/zeebe:${CAMUNDA_ZEEBE_VERSION}
    container_name: zeebe
    ports:
      - "26500:26500"
      - "9600:9600"
      - "8088:8080"
    environment:
      - ZEEBE_BROKER_GATEWAY_SECURITY_AUTHENTICATION_MODE=${ZEEBE_AUTHENTICATION_MODE}
      - ZEEBE_BROKER_GATEWAY_MULTITENANCY_ENABLED=${MULTI_TENANCY_ENABLED}
      - ZEEBE_BROKER_EXPORTERS_ELASTICSEARCH_CLASSNAME=io.camunda.zeebe.exporter.ElasticsearchExporter
      - ZEEBE_BROKER_EXPORTERS_ELASTICSEARCH_ARGS_URL=http://elasticsearch:9200
      - ZEEBE_BROKER_EXPORTERS_ELASTICSEARCH_ARGS_BULK_SIZE=1
      - ZEEBE_BROKER_DATA_DISKUSAGECOMMANDWATERMARK=0.998
      - ZEEBE_BROKER_DATA_DISKUSAGEREPLICATIONWATERMARK=0.999
      - "JAVA_TOOL_OPTIONS=-Xms512m -Xmx512m"
      - management.endpoints.web.exposure.include=health,info,metrics,prometheus,configprops
      - MANAGEMENT_ENDPOINT_CONFIGPROPS_SHOW_VALUES=ALWAYS

      - CAMUNDA_IDENTITY_TYPE=MICROSOFT
      - CAMUNDA_IDENTITY_BASE_URL=http://identity:8084
      - CAMUNDA_IDENTITY_ISSUER=https://login.microsoftonline.com/<TENANT_ID>/v2.0
      - CAMUNDA_IDENTITY_ISSUER_BACKEND_URL=https://login.microsoftonline.com/<TENANT_ID>/v2.0
      - CAMUNDA_IDENTITY_CLIENT_ID=<ZEEBE_CLIENT_ID>
      - CAMUNDA_IDENTITY_CLIENT_SECRET=<ZEEBE_CLIENT_SECRET>
      - CAMUNDA_IDENTITY_AUDIENCE=<ZEEBE_AUDIENCE>
      - IDENTITY_INITIAL_CLAIM_NAME=oid
      - IDENTITY_INITIAL_CLAIM_VALUE=<INITIAL_USER_OBJECT_ID>
      - SPRING_PROFILES_ACTIVE=identity-auth
    env_file:
      - path: .env
        required: true
    restart: always
    healthcheck:
      test: ["CMD-SHELL", "timeout 10s bash -c ':> /dev/tcp/127.0.0.1/9600' || exit 1"]
      interval: 30s
      timeout: 5s
      retries: 5
      start_period: 30s
    volumes:
      - zeebe:/usr/local/zeebe/data
    networks:
      - camunda-platform
    depends_on:
      - elasticsearch
      - identity

  operate:
    image: camunda/operate:${CAMUNDA_OPERATE_VERSION}
    container_name: operate
    ports:
      - "8081:8080"
    environment:
      - CAMUNDA_OPERATE_ZEEBE_GATEWAYADDRESS=zeebe:26500
      - CAMUNDA_OPERATE_ZEEBE_SECURE=false
      - CAMUNDA_OPERATE_ELASTICSEARCH_URL=http://elasticsearch:9200
      - CAMUNDA_OPERATE_ZEEBEELASTICSEARCH_URL=http://elasticsearch:9200
      - CAMUNDA_OPERATE_MULTITENANCY_ENABLED=${MULTI_TENANCY_ENABLED}
      - CAMUNDA_OPERATE_IDENTITY_RESOURCEPERMISSIONSENABLED=${RESOURCE_AUTHORIZATIONS_ENABLED}
      - CAMUNDA_DATABASE_URL=http://elasticsearch:9200
      - management.endpoints.web.exposure.include=health,info,metrics,prometheus,configprops
      - MANAGEMENT_ENDPOINT_CONFIGPROPS_SHOW_VALUES=ALWAYS
      - management.endpoint.health.probes.enabled=true
      - ZEEBE_CLIENT_CONFIG_PATH=/tmp/zeebe_auth_cache
      - SPRING_PROFILES_ACTIVE=identity-auth
      - CAMUNDA_IDENTITY_TYPE=MICROSOFT
      - CAMUNDA_IDENTITY_BASE_URL=http://identity:8084
      - CAMUNDA_IDENTITY_ISSUER=https://login.microsoftonline.com/<TENANT_ID>/v2.0
      - CAMUNDA_IDENTITY_ISSUER_BACKEND_URL=https://login.microsoftonline.com/<TENANT_ID>/v2.0
      - CAMUNDA_IDENTITY_CLIENT_ID=<OPERATE_CLIENT_ID>
      - CAMUNDA_IDENTITY_CLIENT_SECRET=<OPERATE_CLIENT_SECRET>
      - CAMUNDA_IDENTITY_AUDIENCE=<OPERATE_AUDIENCE>
      - CAMUNDA_OPERATE_IDENTITY_REDIRECT_ROOT_URL=https://operate.<host>

      - CAMUNDA_OPERATE_AUDIENCE=<OPERATE_AUDIENCE>

      - ZEEBE_CLIENT_ID=<ZEEBE_OAUTH_CLIENT_ID>
      - ZEEBE_CLIENT_SECRET=<ZEEBE_OAUTH_CLIENT_SECRET>
      - ZEEBE_AUTHORIZATION_SERVER_URL=https://login.microsoftonline.com/<TENANT_ID>/oauth2/v2.0/token
      - ZEEBE_TOKEN_AUDIENCE=<ZEEBE_OAUTH_AUDIENCE>
      - ZEEBE_TOKEN_SCOPE=<ZEEBE_OAUTH_SCOPE>
    healthcheck:
      test: ["CMD-SHELL", "wget -O - -q 'http://localhost:9600/actuator/health/readiness'"]
      interval: 30s
      timeout: 1s
      retries: 5
      start_period: 30s
    volumes:
      - operate_tmp:/tmp
    networks:
      - camunda-platform
    depends_on:
      - zeebe
      - identity
      - elasticsearch

  tasklist:
    image: camunda/tasklist:${CAMUNDA_TASKLIST_VERSION}
    container_name: tasklist
    ports:
      - "8082:8080"
    environment:
      - CAMUNDA_TASKLIST_ZEEBE_GATEWAYADDRESS=zeebe:26500
      - CAMUNDA_TASKLIST_ZEEBE_RESTADDRESS=http://zeebe:8080
      - CAMUNDA_TASKLIST_ELASTICSEARCH_URL=http://elasticsearch:9200
      - CAMUNDA_TASKLIST_ZEEBEELASTICSEARCH_URL=http://elasticsearch:9200
      - CAMUNDA_TASKLIST_IDENTITY_BASEURL=http://identity:8084
      - CAMUNDA_TASKLIST_MULTITENANCY_ENABLED=${MULTI_TENANCY_ENABLED}
      - CAMUNDA_TASKLIST_IDENTITY_RESOURCE_PERMISSIONS_ENABLED=${RESOURCE_AUTHORIZATIONS_ENABLED}
      - CAMUNDA_DATABASE_URL=http://elasticsearch:9200
      - management.endpoints.web.exposure.include=health,info,metrics,prometheus,configprops
      - MANAGEMENT_ENDPOINT_CONFIGPROPS_SHOW_VALUES=ALWAYS
      - management.endpoint.health.probes.enabled=true
      - CAMUNDA_IDENTITY_TYPE=MICROSOFT
      - CAMUNDA_IDENTITY_ISSUER=https://login.microsoftonline.com/<TENANT_ID>/v2.0
      - CAMUNDA_IDENTITY_ISSUER_BACKEND_URL=https://login.microsoftonline.com/<TENANT_ID>/v2.0
      - CAMUNDA_IDENTITY_CLIENT_ID=<TASKLIST_CLIENT_ID>
      - CAMUNDA_IDENTITY_CLIENT_SECRET=<TASKLIST_CLIENT_SECRET>
      - CAMUNDA_IDENTITY_AUDIENCE=<TASKLIST_AUDIENCE>
      - SPRING_PROFILES_ACTIVE=identity-auth
      - CAMUNDA_TASKLIST_IDENTITY_REDIRECT_ROOT_URL=https://tasklist.<host>
      - path: .env
        required: true
    healthcheck:
      test: ["CMD-SHELL", "wget -O - -q 'http://localhost:9600/actuator/health/readiness'"]
      interval: 30s
      timeout: 1s
      retries: 5
      start_period: 30s
    volumes:
      - tasklist_tmp:/tmp
    networks:
      - camunda-platform
    depends_on:
      zeebe:
        condition: service_healthy
      elasticsearch:
        condition: service_healthy
      identity:
        condition: service_healthy

  connectors:
    image: camunda/connectors-bundle:${CAMUNDA_CONNECTORS_VERSION}
    container_name: connectors
    ports:
      - "8085:8080"
    environment:
      - CAMUNDA_CLIENT_MODE=self-managed
      - CAMUNDA_CLIENT_ZEEBE_RESTADDRESS=http://zeebe:8080
      - CAMUNDA_CLIENT_ZEEBE_GRPCADDRESS=http://zeebe:26500
      - CAMUNDA_CLIENT_AUTH_ISSUER=http://keycloak:18080/auth/realms/camunda-platform/protocol/openid-connect/token
      - CAMUNDA_CLIENT_AUTH_CLIENTID=${ZEEBE_CLIENT_ID}
      - CAMUNDA_CLIENT_AUTH_CLIENTSECRET=${ZEEBE_CLIENT_SECRET}
      - CAMUNDA_CLIENT_AUTH_CREDENTIALSCACHEPATH=/tmp/zeebe_auth_cache
      - CAMUNDA_CLIENT_ZEEBE_AUDIENCE=zeebe-api
      - OPERATE_CLIENT_BASEURL=http://operate:8080
      - OPERATE_CLIENT_AUTHURL=http://keycloak:18080/auth/realms/camunda-platform/protocol/openid-connect/token
      - OPERATE_CLIENT_AUDIENCE=operate-api
      - OPERATE_CLIENT_PROFILE=oidc
      - OPERATE_CLIENT_CLIENTID=connectors
      - OPERATE_CLIENT_CLIENTSECRET=<CONNECTORS_CLIENT_SECRET>
      - management.endpoints.web.exposure.include=health,info,metrics,prometheus,configprops
      - MANAGEMENT_ENDPOINT_CONFIGPROPS_SHOW_VALUES=ALWAYS
      - management.endpoint.health.probes.enabled=true
    env_file: connector-secrets.txt
    healthcheck:
      test: ["CMD-SHELL", "curl -f http://localhost:8080/actuator/health/readiness"]
      interval: 30s
      timeout: 1s
      retries: 5
      start_period: 30s
    networks:
      - camunda-platform
    depends_on:
      - zeebe
      - operate
      - identity

  optimize:
    image: camunda/optimize:${CAMUNDA_OPTIMIZE_VERSION}
    container_name: optimize
    ports:
      - "8083:8090"
    environment:
      - OPTIMIZE_ELASTICSEARCH_HOST=elasticsearch
      - OPTIMIZE_ELASTICSEARCH_HTTP_PORT=9200
      - CAMUNDA_OPTIMIZE_ZEEBE_ENABLED=true
      - CAMUNDA_OPTIMIZE_ENTERPRISE=false
      - CAMUNDA_OPTIMIZE_MULTITENANCY_ENABLED=${MULTI_TENANCY_ENABLED}
      - CAMUNDA_OPTIMIZE_SECURITY_AUTH_COOKIE_SAME_SITE_ENABLED=false
      - CAMUNDA_OPTIMIZE_UI_LOGOUT_HIDDEN=true
      - management.endpoints.web.exposure.include=health
      - management.endpoint.health.probes.enabled=true
      - CAMUNDA_IDENTITY_TYPE=MICROSOFT
      - CAMUNDA_IDENTITY_BASE_URL=http://identity:8084
      - CAMUNDA_IDENTITY_ISSUER=https://login.microsoftonline.com/<TENANT_ID>/v2.0
      - CAMUNDA_IDENTITY_ISSUER_BACKEND_URL=https://login.microsoftonline.com/<TENANT_ID>/v2.0
      - CAMUNDA_IDENTITY_CLIENT_ID=<OPTIMIZE_CLIENT_ID>
      - CAMUNDA_IDENTITY_CLIENT_SECRET=<OPTIMIZE_CLIENT_SECRET>
      - CAMUNDA_IDENTITY_AUDIENCE=<OPTIMIZE_AUDIENCE>
      - SPRING_PROFILES_ACTIVE=oidc
      - CAMUNDA_OPTIMIZE_IDENTITY_REDIRECT_ROOT_URL=https://optimize.<host>
    healthcheck:
      test: ["CMD-SHELL", "curl -f http://localhost:8090/api/readyz"]
      interval: 30s
      timeout: 1s
      retries: 5
      start_period: 30s
    volumes:
      - "./.optimize/environment-config.yaml:/optimize/config/environment-config.yaml"
    restart: on-failure
    networks:
      - camunda-platform
    depends_on:
      - identity
      - elasticsearch

  identity:
    container_name: identity
    image: camunda/identity:${CAMUNDA_IDENTITY_VERSION}
    ports:
      - "8084:8084"
    environment:
      SERVER_PORT: 8084
      IDENTITY_RETRY_DELAY_SECONDS: 30
      IDENTITY_URL: https://${IDENTITY_HOST}
      CAMUNDA_IDENTITY_TYPE: MICROSOFT
      CAMUNDA_IDENTITY_BASE_URL: http://identity:8084
      CAMUNDA_IDENTITY_ISSUER: https://login.microsoftonline.com/<TENANT_ID>/v2.0
      CAMUNDA_IDENTITY_ISSUER_BACKEND_URL: https://login.microsoftonline.com/<TENANT_ID>/v2.0
      CAMUNDA_IDENTITY_CLIENT_ID: <IDENTITY_CLIENT_ID>
      CAMUNDA_IDENTITY_CLIENT_SECRET: <IDENTITY_CLIENT_SECRET>
      CAMUNDA_IDENTITY_AUDIENCE: <IDENTITY_AUDIENCE>
      IDENTITY_INITIAL_CLAIM_NAME: oid
      IDENTITY_INITIAL_CLAIM_VALUE: <INITIAL_USER_OBJECT_ID>
      SPRING_PROFILES_ACTIVE: oidc
      SPRING_MVC_CORS_MAPPINGS_0_PATTERN: /api/**
      SPRING_MVC_CORS_MAPPINGS_0_ALLOWED_ORIGINS: https://identity.<host>
      SPRING_MVC_CORS_MAPPINGS_0_ALLOWED_METHODS: GET,POST,PUT,DELETE,PATCH,OPTIONS
      SPRING_MVC_CORS_MAPPINGS_0_ALLOWED_HEADERS: Authorization,Content-Type,Origin,Accept
      SPRING_MVC_CORS_MAPPINGS_0_ALLOW_CREDENTIALS: true
      SPRING_MVC_CORS_MAPPINGS_0_MAX_AGE: 3600
      IDENTITY_DATABASE_HOST: postgres
      IDENTITY_DATABASE_PORT: 5432
      IDENTITY_DATABASE_NAME: bitnami_keycloak
      IDENTITY_DATABASE_USERNAME: bn_keycloak
      IDENTITY_DATABASE_PASSWORD: <POSTGRES_PASSWORD>
      MULTITENANCY_ENABLED: ${MULTI_TENANCY_ENABLED}
      RESOURCE_PERMISSIONS_ENABLED: ${RESOURCE_AUTHORIZATIONS_ENABLED}
      SERVER_FORWARD_HEADERS_STRATEGY: FRAMEWORK
      CAMUNDA_OPERATE_AUDIENCE: <OPERATE_AUDIENCE>
      CAMUNDA_OPTIMIZE_AUDIENCE: <OPTIMIZE_AUDIENCE>
      CAMUNDA_TASKLIST_AUDIENCE: <TASKLIST_AUDIENCE>
      CAMUNDA_WEBMODELER_AUDIENCE: <WEBMODELER_INTERNAL_AUDIENCE>
      CAMUNDA_WEBMODELER_PUBLIC_AUDIENCE: <WEBMODELER_PUBLIC_AUDIENCE>
      CAMUNDA_ZEEBE_AUDIENCE: <ZEEBE_AUDIENCE>
    healthcheck:
      test: ["CMD", "wget", "-q", "--tries=1", "--spider", "http://localhost:8082/actuator/health"]
      interval: 5s
      timeout: 15s
      retries: 30
      start_period: 60s
    restart: on-failure
    volumes:
      - keycloak-theme:/app/keycloak-theme
    networks:
      - camunda-platform
      - identity-network
    depends_on:
      keycloak:
        condition: service_healthy

  postgres:
    container_name: postgres
    image: postgres:${POSTGRES_VERSION}
    environment:
      POSTGRES_DB: bitnami_keycloak
      POSTGRES_USER: bn_keycloak
      POSTGRES_PASSWORD: <POSTGRES_PASSWORD>
    restart: on-failure
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -d $${POSTGRES_DB} -U $${POSTGRES_USER}"]
      interval: 10s
      timeout: 5s
      retries: 5
    volumes:
      - postgres:/var/lib/postgresql/data
    networks:
      - identity-network

  keycloak:
    container_name: keycloak
    image: bitnamilegacy/keycloak:${KEYCLOAK_SERVER_VERSION}
    volumes:
      - keycloak-theme:/opt/bitnami/keycloak/themes/identity
    ports:
      - "18080:18080"
    environment:
      KEYCLOAK_HTTP_PORT: 18080
      KEYCLOAK_HTTP_RELATIVE_PATH: /auth
      KEYCLOAK_DATABASE_HOST: postgres
      KEYCLOAK_DATABASE_PASSWORD: <POSTGRES_PASSWORD>
      KEYCLOAK_ADMIN_USER: admin
      KEYCLOAK_ADMIN_PASSWORD: admin
      KEYCLOAK_PROXY_HEADERS: xforwarded
    restart: on-failure
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:18080/auth"]
      interval: 30s
      timeout: 15s
      retries: 5
      start_period: 30s
    networks:
      - camunda-platform
      - identity-network
    depends_on:
      - postgres

  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:${ELASTIC_VERSION}
    container_name: elasticsearch
    ports:
      - "9200:9200"
      - "9300:9300"
    environment:
      - bootstrap.memory_lock=true
      - discovery.type=single-node
      - xpack.security.enabled=false
      - cluster.routing.allocation.disk.threshold_enabled=false
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
    ulimits:
      memlock:
        soft: -1
        hard: -1
    restart: always
    healthcheck:
      test: ["CMD-SHELL", "curl -f http://localhost:9200/_cat/health | grep -q green"]
      interval: 30s
      timeout: 5s
      retries: 3
    volumes:
      - elastic:/usr/share/elasticsearch/data
    networks:
      - camunda-platform

  web-modeler-db:
    container_name: web-modeler-db
    image: postgres:${POSTGRES_VERSION}
    healthcheck:
      test: pg_isready -d web-modeler-db -U web-modeler-db-user
      interval: 5s
      timeout: 15s
      retries: 30
    environment:
      POSTGRES_DB: web-modeler-db
      POSTGRES_USER: web-modeler-db-user
      POSTGRES_PASSWORD: <WEB_MODELER_DB_PASSWORD>
    networks:
      - web-modeler
    volumes:
      - postgres-web:/var/lib/postgresql/data

  mailpit:
    container_name: mailpit
    image: axllent/mailpit:${MAILPIT_VERSION}
    ports:
      - "1025:1025"
      - "8075:8025"
    healthcheck:
      test: /usr/bin/nc -v localhost 1025
      interval: 30s
    networks:
      - web-modeler

  web-modeler-restapi:
    container_name: web-modeler-restapi
    image: camunda/web-modeler-restapi:${CAMUNDA_WEB_MODELER_VERSION}
    depends_on:
      web-modeler-db:
        condition: service_healthy
      mailpit:
        condition: service_started
      identity:
        condition: service_healthy
    healthcheck:
      test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:8091/health/readiness"]
      interval: 5s
      timeout: 15s
      retries: 30
    environment:
      JAVA_OPTIONS: -Xmx512m
      LOGGING_LEVEL_IO_CAMUNDA_MODELER: DEBUG
      CAMUNDA_IDENTITY_BASEURL: http://identity:8084
      SPRING_DATASOURCE_URL: jdbc:postgresql://web-modeler-db:5432/web-modeler-db
      SPRING_DATASOURCE_USERNAME: web-modeler-db-user
      SPRING_DATASOURCE_PASSWORD: <WEB_MODELER_DB_PASSWORD>
      SPRING_PROFILES_INCLUDE: default-logging
      RESTAPI_PUSHER_HOST: web-modeler-websockets
      RESTAPI_PUSHER_PORT: "8060"
      RESTAPI_PUSHER_APP_ID: web-modeler-app
      RESTAPI_PUSHER_KEY: web-modeler-app-key
      RESTAPI_PUSHER_SECRET: web-modeler-app-secret
      RESTAPI_SERVER_URL: https://${WEB_MODELER_HOST}
      RESTAPI_MAIL_HOST: mailpit
      RESTAPI_MAIL_PORT: 1025
      RESTAPI_MAIL_ENABLE_TLS: "false"
      RESTAPI_MAIL_FROM_ADDRESS: "noreply@example.com"
      CAMUNDA_MODELER_CLUSTERS_0_ID: "local-zeebe"
      CAMUNDA_MODELER_CLUSTERS_0_NAME: "Local Zeebe instance"
      CAMUNDA_MODELER_CLUSTERS_0_VERSION: ${CAMUNDA_ZEEBE_VERSION}
      CAMUNDA_MODELER_CLUSTERS_0_URL_ZEEBE_GRPC: grpc://zeebe:26500
      CAMUNDA_MODELER_CLUSTERS_0_URL_ZEEBE_REST: http://zeebe:8080
      CAMUNDA_MODELER_CLUSTERS_0_URL_OPERATE: http://operate:8080
      CAMUNDA_MODELER_CLUSTERS_0_URL_TASKLIST: http://tasklist:8080
      CAMUNDA_MODELER_CLUSTERS_0_AUTHENTICATION: CLIENT_CREDENTIALS
      CAMUNDA_MODELER_CLUSTERS_0_OAUTH_URL: https://login.microsoftonline.com/<TENANT_ID>/oauth2/v2.0/token
      CAMUNDA_MODELER_CLUSTERS_0_OAUTH_SCOPE: <ZEEBE_OAUTH_SCOPE>
      CAMUNDA_MODELER_CLUSTERS_0_OAUTH_AUDIENCE_ZEEBE: <ZEEBE_OAUTH_AUDIENCE>
      CAMUNDA_MODELER_CLUSTERS_0_CLIENT_ID: <WEB_MODELER_INTERNAL_CLIENT_ID>
      CAMUNDA_MODELER_CLUSTERS_0_CLIENT_SECRET: <WEB_MODELER_INTERNAL_CLIENT_SECRET>

      CAMUNDA_IDENTITY_TYPE: MICROSOFT
      CAMUNDA_MODELER_SECURITY_JWT_AUDIENCE_INTERNAL_API: <WEBMODELER_INTERNAL_AUDIENCE>
      CAMUNDA_MODELER_SECURITY_JWT_AUDIENCE_PUBLIC_API: <WEBMODELER_PUBLIC_AUDIENCE>
      SPRING_SECURITY_OAUTH2_RESOURCESERVER_JWT_ISSUER_URI: https://login.microsoftonline.com/<TENANT_ID>/v2.0

      CAMUNDA_IDENTITY_ISSUER_URL: https://login.microsoftonline.com/<TENANT_ID>/v2.0

      RESTAPI_OAUTH2_TOKEN_ISSUER: https://login.microsoftonline.com/<TENANT_ID>/v2.0
      RESTAPI_OAUTH2_TOKEN_ISSUER_BACKEND_URL: https://login.microsoftonline.com/<TENANT_ID>/v2.0

      LOGGING_LEVEL_IO_GRPC: TRACE

      ZEEBE_AUTHENTICATION_MODE: identity
      ZEEBE_CLIENT_ID: <ZEEBE_OAUTH_CLIENT_ID>
      ZEEBE_CLIENT_SECRET: <ZEEBE_OAUTH_CLIENT_SECRET>

    env_file: ./.web-modeler/cluster-config-authentication-mode-${ZEEBE_AUTHENTICATION_MODE}.env
    networks:
      - web-modeler
      - camunda-platform

  web-modeler-webapp:
    container_name: web-modeler-webapp
    image: camunda/web-modeler-webapp:${CAMUNDA_WEB_MODELER_VERSION}
    ports:
      - "8070:8070"
    depends_on:
      web-modeler-restapi:
        condition: service_healthy
    healthcheck:
      test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:8071/health/readiness"]
      interval: 5s
      timeout

Note that with this config, everything works fine, and connected with Entra ID, except for Tasklist that fails to start for some reason.

Thanks @tlmouden - I’ll test this as soon as I can and see what I find.

1 Like

@nathan.loding - Note that with this configuration, Tasklist fails to start, showing the error “unable to fetch partitions from Zeebe.”
This issue existed even before enabling Zeebe security. It started when the security mode was set to NONE, and the solution back then was to remove the ZEEBE_CLIENT_ID and ZEEBE_CLIENT_SECRET from the .env file.
The problem appeared as soon as Entra ID was enabled on Identity, and it is still occurring.

Hi @tlmouden - wanted to provide a quick update. I’m meeting with an engineer later this week to learn more about the internals, but I got EntraID mostly working with a test tenant with Docker. I followed the guide, and Optimize is failing on an Elasticsearch dependency and the Connectors runtime isn’t working. I did have to change the EntraID URL, however, from https://login.microsoftonline.com/<TENANT_ID>/v2.0 to https://login.microsoftonline.com/<TENANT_ID>/oauth2/v2.0 … these are the questions I’m waiting for info from our engineers on.

Otherwise, I added:

      - CAMUNDA_IDENTITY_BASE_URL=http://identity:8084
      - CAMUNDA_IDENTITY_ISSUER=https://login.microsoftonline.com/xxx/oauth2/v2.0/token
      - CAMUNDA_IDENTITY_ISSUER_BACKEND_URL=https://login.microsoftonline.com/xxxoauth2/v2.0
      - CAMUNDA_IDENTITY_CLIENT_ID=xxx
      - CAMUNDA_IDENTITY_CLIENT_SECRET=xxx
      - CAMUNDA_IDENTITY_AUDIENCE=xxx
      - SPRING_PROFILES_ACTIVE=oidc

to each component, and removed any reference to Keycloak.

1 Like

Hello @nathan.loding , it’s great to know that, thank you for your support! Don’t hesitate to keep me updated.