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

Upgrade Camunda components from 8.9 to 8.10

Review component-level actions that may be required when upgrading a Camunda 8 Self-Managed deployment from 8.9.x to 8.10.x.

About​

Use this page with the deployment upgrade guide for your environment. Start with the Upgrade Camunda 8 overview, then apply any component-specific steps that match your setup.

Camunda Hub​

In 8.10, Camunda Hub replaces Console and Web Modeler. To support this change:

  • Console-specific configurations have been removed.
  • Cluster configurations have been updated.

Additionally, when you upgrade, your data is migrated to the new file structure.

If you use a custom configuration, review this section and make applicable changes. Otherwise, the configuration updates mentioned here will not be relevant. Skip ahead to the data migration.

Rolling upgrades​

There is no rolling upgrade path from Web Modeler 8.9 to Camunda Hub 8.10. Shut down all Web Modeler instances so the database has no more writers, take a database backup, then start one or more Camunda Hub 8.10 instances. Starting Camunda Hub triggers the database migration; once it completes, Hub resumes serving traffic. See version upgrade for the underlying principles.

If you deploy with Helm, this procedure is already handled for you via the camundaHub.upgrade.phase values. See migrate Camunda Hub for the Helm-specific steps. You do not need to perform the manual steps above.

Console configuration​

If you use a custom configuration, review this section and the following ones, and make applicable changes. Otherwise, they are not applicable to your setup.

Console no longer exists in 8.10. Therefore, if you've configured Console with custom settings, remove those settings:

  • If using application properties, remove the top-level camunda.console object.
  • If using environment variables, remove the following variables:
    • CAMUNDA_CONSOLE_CONTEXT_PATH
    • CAMUNDA_CONSOLE_CUSTOMERID
    • CAMUNDA_CONSOLE_DISABLE_AUTH
    • CAMUNDA_CONSOLE_EXPERIMENTAL_DISCOVERY_MODE
    • CAMUNDA_CONSOLE_INSTALLATIONID
    • CAMUNDA_CONSOLE_REDIRECT_TRAILING_SLASH
    • CAMUNDA_CONSOLE_REDIRECT_URL
    • CAMUNDA_CONSOLE_TELEMETRY

The application fails on startup if any of these are configured, whether as an application property or as one of the environment variables above.

Management Identity roles and permissions​

Management Identity only adds roles, applications, and permissions on startup; it never removes them. As a result:

  • If you hold the Console role, you automatically gain management access to Hub's cluster pages through a new admin:clusters permission after upgrading. No manual role reassignment is required. DevOps is the forward-looking name for the same access.
  • If you hold the Web Modeler Admin role, you also automatically gain full access to Hub's cluster pages after upgrading — a broader grant than the Console role's management-only access, since admin:* also carries modeler-admin capabilities. In 8.9, this role's admin:* permission only covered Web Modeler super-user mode and publishing connector templates; in 8.10, the same permission additionally reaches Hub's cluster pages. No manual role reassignment is required. Hub Admin is the forward-looking name for the same access.
  • After upgrading, your Keycloak also gains roles named Hub and Hub Admin, provisioned alongside your existing Web Modeler and Web Modeler Admin roles (which are kept for backward compatibility and keep working unchanged). This applies to every installation, not just new ones, so you may see both name pairs after upgrading. Both name pairs grant identical permissions; assign whichever name makes sense for your users.
  • The standalone Keycloak Console application and console-api audience are no longer provisioned by Management Identity. Console's cluster-management pages are now part of the Hub UI application, so a separate OIDC application/client for Console is no longer needed. Your existing console client and its role mappings are not deleted automatically. If you no longer need them, remove them manually from Keycloak (or your OIDC provider).

If you rely on least-privilege access to cluster management, review who holds the Console and Web Modeler Admin / Hub Admin roles before upgrading. See the 8.10 release announcements for a summary of this and other Hub role changes in 8.10.

For the full list of default roles, applications, and permissions in 8.10, see manage roles and manage access and permissions.

Modeler settings​

All camunda.modeler.* settings are replaced by camunda.hub.* settings.

For an exhaustive list, reference the Camunda Hub properties.

File download concurrency configuration​

The file download endpoints used by Web Modeler features in Camunda Hub no longer use a bounded executor. Downloads now stream synchronously on the request thread, with concurrent downloads limited by a semaphore. As a result, the following executor tuning properties have been removed:

  • camunda.modeler.file-download.executor.core-pool-size
  • camunda.modeler.file-download.executor.max-pool-size
  • camunda.modeler.file-download.executor.queue-capacity

These properties have been replaced by a single property:

  • camunda.hub.file-download.max-concurrent-downloads — default 15, matching the 8.9 defaults of max-pool-size: 5 plus queue-capacity: 10.
warning

If any of the removed properties are still set, for example as environment variables, Camunda Hub fails to start. Spring would otherwise ignore these unknown properties, so the fail-fast behavior prevents existing download tuning from being silently dropped.

Before upgrading, remove the executor properties. If you need to tune download concurrency, set camunda.hub.file-download.max-concurrent-downloads instead.

With the 8.9 defaults, at most five downloads ran concurrently with up to 10 queued. In 8.10, up to 15 downloads stream concurrently. If you customized the 8.9 executor settings, the previous limits differed from these defaults.

Cluster configuration​

The following settings have been ported from the Console configuration in 8.9 to Camunda Hub in 8.10:

8.98.10
camunda.console.managed.releases[0].tagscamunda.hub.clusters[0].tags
camunda.console.managed.releases[0].custom-propertiescamunda.hub.clusters[0].custom-properties
camunda.console.managed.releases[0].componentscamunda.hub.clusters[0].components
camunda.console.managed.releases[0].components[0].idcamunda.hub.clusters[0].components[0].type
camunda.console.managed.releases[0].components[0].urlcamunda.hub.clusters[0].components[0].urls.<webapp|rest|grpc>
camunda.console.managed.releases[0].components[0].readinesscamunda.hub.clusters[0].components[0].urls.readiness
camunda.console.managed.releases[0].components[0].metricsRemoved.

Cluster configuration example​

Console 8.9 configuration:

camunda:
console:
managed:
releases:
- name: camunda-platform
namespace: qa-camunda-platform
version: 8.9.0
tags:
- dev
custom-properties:
- description: "Monitoring"
links:
- name: "Grafana"
url: "http://localhost:3000"
- name: "Prometheus"
url: "http://localhost:9090"
- description: "Documentation"
links:
- name: "Wiki"
url: "http://localhost:8090/wiki"
components:
- name: camunda-platform
namespace: camunda-platform-namespace
version: 9.1.2
components:
- name: Console
id: console
version: 8.9-SNAPSHOT
url: https://qa.ci.distro.ultrawombat.com/
readiness: http://camunda-platform-console.qa-camunda-platform:9100/health/readiness
metrics: http://camunda-platform-console.qa-camunda-platform:9100/prometheus
- name: Keycloak
id: keycloak
url: https://qa.ci.distro.ultrawombat.com/auth/
- name: Identity
id: identity
version: SNAPSHOT
url: https://qa.ci.distro.ultrawombat.com/identity
readiness: http://camunda-platform-identity.qa-camunda-platform:82/actuator/health
metrics: http://camunda-platform-identity.qa-camunda-platform:82/actuator/prometheus
- name: WebModeler
id: webModelerWebApp
version: SNAPSHOT
url: https://qa.ci.distro.ultrawombat.com/modeler
readiness: http://camunda-platform-web-modeler-restapi.qa-camunda-platform:8091/modeler/health/readiness
metrics: http://camunda-platform-web-modeler-restapi.qa-camunda-platform:8091/modeler/metrics
- name: Optimize
id: optimize
version: 8.9-SNAPSHOT
url: https://qa.ci.distro.ultrawombat.com/optimize
readiness: http://camunda-platform-optimize.qa-camunda-platform:80/optimize/api/readyz
metrics: http://camunda-platform-optimize.qa-camunda-platform:8092/actuator/prometheus
- name: Connectors
id: connectors
version: 8.9-SNAPSHOT
url: http://camunda-platform-connectors.qa-camunda-platform:8080/connectors
readiness: http://camunda-platform-connectors.qa-camunda-platform:8080/connectors/actuator/health/readiness
metrics: http://camunda-platform-connectors.qa-camunda-platform:8080/connectors/actuator/prometheus
- name: Operate
id: operate
version: 8.9-SNAPSHOT
url: https://qa.ci.distro.ultrawombat.com/core/operate
readiness: http://camunda-platform-zeebe.qa-camunda-platform:9600/core/actuator/health/readiness
metrics: http://camunda-platform-zeebe.qa-camunda-platform:9600/core/actuator/prometheus
- name: Tasklist
id: tasklist
version: 8.9-SNAPSHOT
url: https://qa.ci.distro.ultrawombat.com/core/tasklist
readiness: http://camunda-platform-zeebe.qa-camunda-platform:9600/core/actuator/health/readiness
metrics: http://camunda-platform-zeebe.qa-camunda-platform:9600/core/actuator/prometheus
- name: Orchestration Admin
id: orchestrationIdentity
version: 8.9-SNAPSHOT
url: https://qa.ci.distro.ultrawombat.com/core/admin
readiness: http://camunda-platform-zeebe.qa-camunda-platform:9600/core/actuator/health/readiness
metrics: http://camunda-platform-zeebe.qa-camunda-platform:9600/core/actuator/prometheus
- name: Orchestration Cluster
id: orchestration
version: 8.9-SNAPSHOT
urls:
grpc: https://grpc-qa.ci.distro.ultrawombat.com
http: https://qa.ci.distro.ultrawombat.com/core
readiness: http://camunda-platform-zeebe.qa-camunda-platform:9600/core/actuator/health/readiness
metrics: http://camunda-platform-zeebe.qa-camunda-platform:9600/core/actuator/prometheus

Camunda Hub 8.10 configuration:

camunda:
hub:
clusters:
- id: "camunda-platform"
name: "camunda-platform"
namespace: "qa-camunda-platform"
version: "8.10.0"
authentication: BEARER_TOKEN
authorizations:
enabled: true
tags:
- "dev"
custom-properties:
- description: "Monitoring"
links:
- name: "Grafana"
url: "http://localhost:3000"
- name: "Prometheus"
url: "http://localhost:9090"
- description: "Documentation"
links:
- name: "Wiki"
url: "http://localhost:8090/wiki"
components:
- name: "Identity"
type: "identity"
version: "8.10-SNAPSHOT"
urls:
webapp: "https://qa.ci.distro.ultrawombat.com/identity"
readiness: "http://camunda-platform-identity.qa-camunda-platform:82/actuator/health"
- name: "Camunda Hub"
type: "hub"
version: "8.10-SNAPSHOT"
urls:
webapp: "https://qa.ci.distro.ultrawombat.com/modeler"
readiness: "http://camunda-platform-web-modeler-restapi.qa-camunda-platform:8091/modeler/health/readiness"
- name: "Optimize"
type: "optimize"
version: "8.10-SNAPSHOT"
urls:
webapp: "https://qa.ci.distro.ultrawombat.com/optimize"
readiness: "http://camunda-platform-optimize.qa-camunda-platform:80/optimize/api/readyz"
- name: "Connectors"
type: "connectors"
version: "8.10.0"
urls:
rest: "http://camunda-platform-connectors.qa-camunda-platform:8080/connectors"
readiness: "http://camunda-platform-connectors.qa-camunda-platform:8080/connectors/actuator/health/readiness"
- name: "Operate"
type: "operate"
version: "8.10-SNAPSHOT"
urls:
webapp: "https://qa.ci.distro.ultrawombat.com/core/operate"
readiness: "http://camunda-platform-zeebe.qa-camunda-platform:9600/core/actuator/health/readiness"
- name: "Tasklist"
type: "tasklist"
version: "8.10-SNAPSHOT"
urls:
webapp: "https://qa.ci.distro.ultrawombat.com/core/tasklist"
readiness: "http://camunda-platform-zeebe.qa-camunda-platform:9600/core/actuator/health/readiness"
- name: "Orchestration Admin"
type: "admin"
version: "8.10-SNAPSHOT"
urls:
webapp: "https://qa.ci.distro.ultrawombat.com/core/admin"
readiness: "http://camunda-platform-zeebe.qa-camunda-platform:9600/core/actuator/health/readiness"
- name: "Orchestration Cluster"
type: "orchestration"
version: "8.10-SNAPSHOT"
urls:
grpc: "https://grpc-qa.ci.distro.ultrawombat.com"
rest: "https://qa.ci.distro.ultrawombat.com/core"
readiness: "http://camunda-platform-zeebe.qa-camunda-platform:9600/core/actuator/health/readiness"

Authentication configuration​

No action is required to upgrade to 8.10. Camunda Hub continues to authenticate with its own properties, documented under Identity / Keycloak, not with the Orchestration Cluster's camunda.security.authentication.oidc.* settings. For the one exception, the username claim, see Identity / Keycloak.

Note the following:

  • Cross-origin resource sharing (CORS) settings are unchanged. Hub continues to use its own CORS configuration.
  • User, group, role, tenant, and permission management is unchanged in 8.10, and is still handled by Management Identity.

For the full Hub authentication configuration, see Camunda Hub authentication.

Component types​

console and keycloak are no longer valid component types. The application will fail on startup if you've configured a console or keycloak component.

Additionally, the following component types have been renamed:

  • webModelerWebApp → hub
  • orchestrationIdentity → admin

The old values are still accepted for backward compatibility, but you should update your configuration to use the new values.

camunda:
hub:
clusters:
- id: camunda-platform
# other fields...
components:
- name: "Console"
type: "console" # type cannot be "console" or "keycloak"
version: "8.10-SNAPSHOT"
urls:
webapp: "https://qa.ci.distro.ultrawombat.com/"
readiness: "http://camunda-platform-console.qa-camunda-platform:9100/health/readiness"

Dynamic cluster management​

In Camunda 8.8 and 8.9, you could use CAMUNDA_CONSOLE_EXPERIMENTAL_DISCOVERY_MODE to expose the discovery API, which allowed clusters to send license information and register themselves with Console. This experimental feature is now replaced by a new feature flag in the Camunda Hub configuration: DYNAMIC_CLUSTER_MANAGEMENT_ENABLED.

With dynamic cluster management, clusters can regularly send license information to a discovery endpoint:

POST /api/v2/clusters

With that information, Camunda Hub registers the cluster with minimal data and no management functionality in the user interface. This behavior is similar to CAMUNDA_CONSOLE_EXPERIMENTAL_DISCOVERY_MODE.

However, unlike in Console, where cluster records were cleaned up on restart, Camunda Hub cluster registrations persist through restarts. So you'll need to remove them yourself using the remove cluster registration endpoint:

DELETE /api/v2/clusters/{clusterId}

Read more about dynamic cluster management in the Camunda Hub properties reference.

Environments​

In 8.10, teams deploy to environments instead of the clusters connected to a project.

What happens when you upgrade:

  • Camunda Hub creates environments from the clusters in your camunda.hub.clusters configuration. On a cluster at version 8.10 or later, each cluster has an environment for the default Physical Tenant, plus one for each Physical Tenant you declare. See physical tenants.
  • During the data migration, Camunda Hub assigns to each workspace an environment for every cluster that its projects used at any deployment stage, and for every cluster that its IDP projects used. If several projects share a workspace, the workspace gets all their clusters, and each one is assigned once. Existing projects can continue to deploy to the clusters they used before. For a cluster at version 8.10 or later, the environment is backed by the default Physical Tenant and keeps its workspace assignments.
  • Projects no longer have their own deployment stages or connected clusters. A project can deploy to every environment assigned to its workspace.
  • Workspaces you create after the upgrade start without environments. An organization admin must assign environments to the workspace.
  • A cluster or Physical Tenant that is no longer in the configuration, for example because its ID changed, stays in Camunda Hub with the status Not reported while a workspace uses it. Reassign the workspace to another environment, or remove the assignment, when you no longer need it.

Before you upgrade, review the following:

TaskWhy
(Optional) Tag a cluster with prodDo this only if you want Camunda Hub to treat the environments of a cluster as production environments. Camunda Hub identifies them by the prod tag in camunda.hub.clusters[].tags, and the project deployment policy applies to them. Without the tag, no production restriction applies.
Add a readiness address to componentsCamunda Hub determines the status of an environment from the urls.readiness address of its components. Without it, the status is Unknown.

Camunda Hub reads the cluster configuration at startup. After you change it, perform a rolling restart.

Deployments to production environments​

In earlier versions, only administrators could deploy to the production stage of a project by default. In 8.10, this default no longer applies to environments. Any workspace admin or editor with deployment privileges in the cluster can deploy to an environment tagged prod. Access to production is controlled by which environments are assigned to the workspace and by the deployment permissions in the cluster.

To require an approved project snapshot for production deployments, turn on Require approval of project snapshots to deploy to production environments in the project deployment settings.

Data migration​

When you upgrade to Camunda 8.10, your data is automatically migrated to the new organizational structure.

Camunda recommends you create a backup before the migration to ensure your data is recoverable in its original state if anything goes wrong. If you notice anything unexpected after the migration, contact support.

note

Because you're upgrading to 8.10, you may not yet be familiar with the new Camunda Hub terminology. This sections uses Web Modeler terminology, including projects and process applications, to explain the data migration. However, before using the Camunda Hub UI, you should familiarize yourself with the new terminology, including workspaces and projects.

During the migration:

  • Any process application nested inside a folder is moved to the top level of its project.
  • Any files or folders located directly in a project, not inside a process application, is automatically grouped in a new process application, named YOUR PROJECT NAME - General. You can rename this application, move content out of it, or otherwise reorganize it as with any other process application.
  • Git sync and cluster settings on existing process applications migrate unchanged along with your data.

During the migration, Web Modeler is briefly unavailable. Clusters and running processes are unaffected and continued executing normally.

The migration does not affect the following resources:

AreaImpact
Running process instancesOrchestration Clusters, engines, and running process instances are unaffected. Web Modeler and Camunda Hub remain independent of the runtime path.
RedeploymentExisting deployments remain on their clusters and continue running. The migration does not require redeployment.
Clusters and configurationCluster and deployment settings attached to existing process applications migrate with the data and remain unchanged.
Files, folders, and version historyAll files, folders, versions, and history are preserved. Only their location within the project changes.
Git-synced projectsThe migration does not modify process applications or their contents. Files connected through Git sync remain in the same repository with the same history.
Desktop ModelerDesktop Modeler is unaffected because it has no direct connection to Web Modeler. Content shared through Git sync is also unaffected.

If you automate against the Web Modeler API, the migration may affect automation that relies on file or folder locations. Web Modeler API v1 returns files and folders from their new locations. Requests that create an item at a project's root are redirected to the new YOUR PROJECT NAME - General process application, and the response reflects the new location.

Review any automation that relies on file or folder locations. A small number of folder API integrations were affected more directly. If you use the folder API with process applications, contact support to confirm whether your integration needs updates.

Organize the "General" process application​

During the migration, any files or folders located directly in a project, not inside a process application, were automatically grouped in a new process application, named "YOUR PROJECT NAME - General". This process application is a temporary container for loose files and folders. Camunda recommends organizing these resources into process applications that reflect their purpose for better long-term discoverability and maintainability.

To move files from the "General" process application, first create a new process application:

  1. Open your project.
  2. At the top right of the project view, click Create new > Process application.
  3. Enter a name and select a development cluster.
  4. Click Create.

Next, move the files from the "General" process application to the new one:

  1. Open your "General" process application.
  2. On the left side of the file list, select all the files you want to move.
  3. At the top of the file list, click Move.
  4. Select your new process application.
  5. Click Move.

Physical Tenants​

Camunda 8.10 introduces Physical Tenants, strongly isolated execution units within a single Orchestration Cluster. Upgrading a single-tenant 8.9 cluster requires no action. Adopting Physical Tenants is opt-in, and the upgrade is backward compatible by design.

What happens automatically​

  • Your existing root-level configuration becomes the configuration of the default Physical Tenant. There is no manual migration step and no data migration.
  • Storage keeps its existing location. Schemas, index prefixes, and document store paths are not reorganized.
  • The default Physical Tenant is always present, and cannot be renamed, disabled, or deleted.

Existing clients keep working​

Caller8.9 request8.10 behavior
REST/v2/...Unchanged. Routes to the default Physical Tenant, and is also addressable as /physical-tenants/default/v2/....
gRPCNo tenant headerUnchanged. Requests without the Camunda-Physical-Tenant header route to the default Physical Tenant.
Web apps/operate, /tasklistUnchanged. /operate and /physical-tenants/default/operate address the same application.

No client code changes are required for a single-tenant deployment. For the full routing rules, see API routing for Physical Tenants.

If you configure the default tenant explicitly​

Leaving the configuration untouched is the safe path. If you add any camunda.physical-tenants.default.* override, one validation rule changes.

While no camunda.physical-tenants.* configuration is present, the implicit default tenant inherits the full set of cluster identity providers. As soon as you configure camunda.physical-tenants.default explicitly, it must declare its own providers.assigned, exactly like any other tenant. On an OIDC cluster, omitting it fails startup:

Invalid physical-tenant provider selection: non-default physical tenant '<tenantId>' must declare a
non-empty 'camunda.physical-tenants.<tenantId>.security.authentication.providers.assigned' selecting
which cluster OIDC providers apply to it

Values under camunda.physical-tenants.default.* are interpreted as overrides of the existing default tenant, not as the creation of a new one.

Add Physical Tenants after upgrading​

Physical Tenants are provisioned through static configuration, so adding one is a configuration change followed by a rolling restart. Dynamic creation at runtime is not available. See provisioning and lifecycle, or set up two isolated Physical Tenants for a hands-on walkthrough.

A tenant's lifecycle follows its configuration. A tenant present in configuration is provisioned automatically, removing it from configuration disables it and retains its data, and re-adding it re-enables the tenant with that data. Deleting a tenant's data is not supported. A disabled tenant can be logically removed from the cluster topology, which deletes no data.

Three behaviors change once a node serves more than one tenant:

  • Each tenant's secondary storage is initialized independently. A tenant whose storage is unusable is degraded on its own, returning 503 with a Retry-After header, while the other tenants keep serving traffic.
  • Node readiness reports ready while at least one tenant is serviceable, so a ready node no longer implies every tenant is healthy.
  • Browser sessions become path-scoped per tenant. A user signed in to one tenant is not signed in to another, and signing in to a second tenant creates a second, independent session rather than replacing the first.

Before adding tenants, review storage isolation so each tenant resolves to a distinct storage location. Two tenants sharing a location fails startup.

Validate after upgrading​

  1. Confirm the cluster is operational with GET /cluster/v2/status.
  2. Confirm the default tenant accepts work with GET /physical-tenants/default/v2/topology.
  3. Run an existing unprefixed request, such as GET /v2/topology, and confirm it still succeeds.
  4. Open Operate and Tasklist at their existing unprefixed URLs and confirm your data is present.

If a tenant-scoped request returns 404, the tenant is not configured in the cluster. This is not an authorization failure. See HTTP status codes.

Not supported​

There is no migration path from Logical Tenants to Physical Tenants. The two are independent mechanisms, and a Logical Tenant cannot be promoted to or moved into a Physical Tenant. Logical Tenants remain available inside each Physical Tenant as a lightweight subdivision.

Downgrading from 8.10 back to 8.9 is not supported. This is a general Camunda constraint rather than a Physical Tenants one, so there is no rollback path for the cluster and no return path for camunda.physical-tenants.default.* overrides. Take a backup before you upgrade, and rehearse the upgrade in a non-production cluster first.

Elasticsearch/OpenSearch Exporter​

Default replica count changed​

In 8.10, the default value of number-of-replicas for Elasticsearch/OpenSearch Exporter indices changed from 0 to 1.

This applies to new indices created after upgrading. Existing indices are not affected.

  • Single-node clusters: Set number-of-replicas: 0 explicitly in your exporter configuration to avoid yellow cluster health. On a single node, replicas cannot be assigned and remain unassigned, which causes the cluster to report yellow health and may trigger monitoring alerts.
  • Multi-node clusters: No action required. The new default improves fault tolerance. Note that each replica stores a full copy of the shard data, so enabling replicas increases disk usage for new indices.

Optimize​

Default objectVariable inclusion changed​

This is a breaking change for Self-Managed. In 8.10, the default value of zeebe.includeObjectVariableValue changed from true to false. Optimize no longer flattens object variables into per-property fields or stores their raw value by default. See the 8.10 breaking change announcement for the full rationale.

Setting8.98.10
zeebe.includeObjectVariableValuetruefalse

Action: If your reports, filters, or Raw Data Reports rely on flattened object variable properties, set zeebe.includeObjectVariableValue: true (environment variable CAMUNDA_OPTIMIZE_ZEEBE_INCLUDE_OBJECT_VARIABLE=true) before upgrading:

zeebe:
includeObjectVariableValue: true

Optimize logs a WARN on startup whenever object variable values are not being imported. The message includes the opt-in setting.

In 8.10, Optimize accepts the same camunda.security.* configuration as the Orchestration Cluster, and its authentication behavior changes accordingly. See Optimize authentication in Self-Managed for the full configuration reference. The following sections cover the configuration key changes.

Client bearer tokens are now classified for permission checks​

Optimize now classifies each bearer token as belonging to a user or a machine-to-machine (M2M) client, using camunda.security.authentication.oidc.username-claim and client-id-claim, and enforces your configured Optimize permission only on tokens it classifies as a user's.

A token Optimize can't classify as an M2M client's is treated as belonging to a user, and checked against your configured Optimize permission.

The Camunda Helm chart doesn't configure either claim for Optimize. username-claim keeps its software default of sub, and client-id-claim has no default at all, so Optimize can't classify any client token as M2M until you set it — every bearer token is checked against your configured Optimize permission. Set both claims through optimize.extraConfiguration, matching the values your identity provider uses (for example, preferred_username and client_id for Keycloak; see the setup instructions for your identity provider for other providers):

optimize:
extraConfiguration:
- file: security.yaml
content: |
camunda:
security:
authentication:
oidc:
username-claim: preferred_username
client-id-claim: client_id

Action: Set username-claim and client-id-claim to match your identity provider before upgrading. Otherwise, M2M clients without an Optimize permission may see new permission errors after upgrading.

Component-specific security configuration keys are deprecated​

The following component-specific keys are deprecated in favor of camunda.security.*. They remain supported in 8.10. Camunda plans to remove them, and the component-specific configuration, in a future release.

Optimize maps each recognized component-specific key to its replacement automatically and logs a deprecation warning naming the replacement, so existing deployments keep working unchanged through 8.10.

Component-specific keyReplacement
CAMUNDA_OPTIMIZE_IDENTITY_ISSUER_URLcamunda.security.authentication.oidc.issuer-uri
CAMUNDA_OPTIMIZE_IDENTITY_CLIENTIDcamunda.security.authentication.oidc.client-id
CAMUNDA_OPTIMIZE_IDENTITY_CLIENTSECRETcamunda.security.authentication.oidc.client-secret
CAMUNDA_OPTIMIZE_IDENTITY_AUDIENCEcamunda.security.authentication.oidc.audiences
CAMUNDA_OPTIMIZE_AUTH0_CLIENTIDcamunda.security.authentication.oidc.client-id
CAMUNDA_OPTIMIZE_AUTH0_CLIENTSECRETcamunda.security.authentication.oidc.client-secret
CAMUNDA_OPTIMIZE_AUTH0_DOMAINcamunda.security.authentication.oidc.issuer-uri (issuer is derived from the Auth0 domain)
CAMUNDA_OPTIMIZE_AUTH0_ORGANIZATIONcamunda.security.saas.*
CAMUNDA_OPTIMIZE_CLIENT_AUDIENCEcamunda.security.authentication.oidc.audiences
CAMUNDA_OPTIMIZE_CLIENT_CLUSTERIDcamunda.security.saas.* (also derives the redirect URI ?uuid and the servlet context path)
CAMUNDA_OPTIMIZE_M2M_ACCOUNTS_AUTH0_AUDIENCEcamunda.security.authentication.oidc.audiences
SPRING_SECURITY_OAUTH2_RESOURCESERVER_JWT_JWK_SET_URIcamunda.security.authentication.oidc.jwk-set-uri
CAMUNDA_OPTIMIZE_API_AUDIENCEcamunda.security.authentication.oidc.audiences
CAMUNDA_OPTIMIZE_SECURITY_RESPONSE_HEADERS_HSTS_MAX_AGEcamunda.security.http-headers.hsts.max-age-in-seconds (a negative value disables the header)
camunda.identity.issuerBackendUrlcamunda.security.authentication.oidc.issuer-uri, or one of the endpoint-specific overrides (jwk-set-uri, authorization-uri, token-uri, user-info-uri) if your Keycloak back channel is reachable at a different address than the public-facing issuer
camunda.identity.clientIdcamunda.security.authentication.oidc.client-id
camunda.identity.clientSecretcamunda.security.authentication.oidc.client-secret

Note the following:

  • Precedence: If you set both a component-specific key and its camunda.security.* replacement, the camunda.security.* value wins.
  • audiences replaces, not merges: If you set camunda.security.authentication.oidc.audiences yourself, that list replaces the audiences from CAMUNDA_OPTIMIZE_IDENTITY_AUDIENCE and CAMUNDA_OPTIMIZE_API_AUDIENCE. Include every audience you still need in your explicit list.
  • CAMUNDA_OPTIMIZE_IDENTITY_BASE_URL is not deprecated: Keep it set. Optimize still uses it to look up users, for example when adding users to a collection.

Action: Migrate to the camunda.security.* keys as soon as you can. Camunda plans to remove these keys and the component-specific configuration in a future release.

Keys with no replacement​

The following keys are no longer used in 8.10. Optimize still starts if you leave them in place, but they have no effect, so remove them:

  • CAMUNDA_OPTIMIZE_SECURITY_AUTH_TOKEN_SECRET
  • CAMUNDA_OPTIMIZE_SECURITY_AUTH_COOKIE_MAX_SIZE
  • CAMUNDA_OPTIMIZE_SECURITY_AUTH_COOKIE_SAME_SITE_ENABLED
  • security.responseHeaders.X-XSS-Protection

Static API access token is no longer accepted​

In 8.10, Optimize accepts only OIDC bearer tokens on its API. Directly after the upgrade, Optimize rejects each request that carries the static token from api.accessToken (environment variable OPTIMIZE_API_ACCESS_TOKEN) with a 401 response. This applies to the Optimize API and to the external variable ingestion endpoint. The Camunda Helm chart and Camunda 8 SaaS do not set api.accessToken. They configure OIDC for the Optimize API. You are affected only if you set the property or the OPTIMIZE_API_ACCESS_TOKEN environment variable yourself, for example as an Optimize property override or an extra environment variable in your Helm values, or in a manual or Docker Compose installation.

Optimize logs an obsolete-property warning for the environment variable, but not for the YAML key. Check your YAML configuration for api.accessToken too.

Action: Change the API clients that send the static token to OIDC bearer tokens before you upgrade. Then remove api.accessToken and OPTIMIZE_API_ACCESS_TOKEN from your configuration. If you need more time, set optimize.security.csl.enabled=false. This opts into the 8.9 component-specific configuration fallback, and the static token works again. Camunda plans to remove this fallback and the component-specific configuration keys in a future release.

Zeebe​

Job leasing during the rolling upgrade​

Camunda 8.10 introduces job leasing. During a rolling upgrade from 8.9, jobs on partitions that are still running 8.9 return a null jobLeaseToken, even when activated with withLease set to true, because 8.9 brokers do not support job leasing.

If your worker requires the lease to process a job safely, treat a null jobLeaseToken as not yet supported on that partition: fail the job with a retry backoff, and set retries back to the job's current value so the fail doesn't burn through them while the upgrade is in progress. The lease becomes available after that job's partition leader is upgraded to 8.10, and the retry converges.

When using the REST API, a gateway instance still running 8.9 rejects the unknown withLease field with a 400 error instead of returning null. This handling is no longer required after every gateway in the cluster has been upgraded to 8.10.

final JobHandler paymentJobHandler =
(jobClient, job) -> {
final String jobLeaseToken = job.getJobLeaseToken();

if (jobLeaseToken == null) {
// This partition hasn't upgraded to 8.10 yet. Fail with retries
// preserved so the job converges once the upgrade completes,
// instead of being burned into an incident.
jobClient
.newFailCommand(job)
.retries(job.getRetries())
.retryBackoff(Duration.ofSeconds(30))
.errorMessage("Lease required but not returned; retrying until the partition upgrades to 8.10")
.send();
return;
}

// process the job

jobClient.newCompleteCommand(job).send();
};

client
.newWorker()
.jobType("process-payment")
.handler(paymentJobHandler)
.withLease(true)
.open();

Deleting a process definition with running instances defers history deletion​

The delete resource endpoint now accepts process definition deletion when the definition still has running instances. Instead of rejecting the request or waiting for physical removal, the definition drains: new instances are blocked immediately, running instances continue to completion, and the definition is removed automatically afterwards.

As a result, when deleteHistory is true, the batchOperation field in the delete response is null for such a definition. Its history is removed as part of the draining lifecycle rather than through an immediately-returned batch operation.

Action: If any caller reads batchOperation from the delete response to track history deletion, handle a null value. Observe the definition's DRAINING state through the process definition API or the zeebe_process_definitions_draining_count metric instead.