Skip to content

CamundaPlatformConfig

CamundaPlatformConfig is a cluster-scoped resource that holds the settings every orchestration cluster of an environment shares. You create it, or another tool creates it for you.

The settings that are the same for every orchestration cluster live here. They are how users and clients authenticate (basic or OIDC), the Camunda license, and the repositories that images are pulled from. You create one per environment. Each CamundaCluster references it by name through platformConfigRef, so you define the settings once. A CamundaManagementCluster references it the same way.

The OIDC fields follow the OIDC discovery vocabulary. They work with Keycloak, Auth0, Entra ID, Okta, or any other OIDC-compliant identity provider.

The operator creates no resources from this kind. It makes sure that the referenced Secrets exist and carry the named keys, and reports the result in Ready. Every CamundaCluster that references this resource reads its values and renders them into the workloads.

The smallest platform config names the authentication method:

apiVersion: core.camunda.io/v1
kind: CamundaPlatformConfig
metadata:
  name: my-platform-config
spec:
  auth:
    method: basic
graph LR
    CC[CamundaCluster] -.->|platformConfigRef| PFC[CamundaPlatformConfig]
    MC[CamundaManagementCluster] -.->|platformConfigRef| PFC
    CCP[CamundaClusterPreset] -.->|auth baseline| CC
    PFC -.->|clientSecretRef, licenseSecretRef| SEC["Secrets"]
    PFC -.->|issuerUrl| IDP["Identity provider (external)"]
Hold "Alt" / "Option" to enable pan & zoom

Override order

The OIDC client credentials here are the defaults of the environment. A CamundaClusterPreset auth block overrides them for its clusters, and the auth block of a CamundaCluster overrides both. When a preset or a cluster sets its own clientId, the audience and the client secret of this resource no longer apply to it. Per-cluster client explains the rule. The authentication method and the identity provider connection always come from this resource.

Claims

usernameClaim and clientIdClaim name the claims that identify a caller. A token that holds the client id claim is a machine client. A token without it is a person, identified by the username claim. The claim identifies a caller and grants nothing: the spec.auth.admin block of a CamundaCluster makes a caller an administrator.

Caution: The claim that you name in clientIdClaim must be present in the tokens of machine clients only. If the tokens of persons also carry that claim, every person becomes a machine client, even after a browser login. Some providers put a client identifier in every token, for example azp in Keycloak. Pick a claim that the provider adds to machine tokens only.

Split horizon

The identity provider can be reachable at a different URL from inside the Kubernetes cluster. In that case, keep issuerUrl equal to the issuer claim of the tokens. Set jwksUrl and tokenUrl to the in-cluster endpoints.

The authentication guide explains the setup of both methods.

The clients of the management plane

spec.auth.oidc.management.clients names the identity provider application of each component of the management plane. A CamundaManagementCluster reads them only when its spec.identityProvider is oidc, your own OIDC provider. Then you register the applications at your provider yourself. When spec.identityProvider is keycloak or externalKeycloak, Management Identity creates every client, and this block stays empty.

Declare the client of each component you deploy:

Client Type Needed when
identity confidential Always. Management Identity is always deployed.
optimize confidential Always. The ManagementAuthConfig always carries it, and CamundaOptimize reads it from there.
console public spec.console is set on the CamundaManagementCluster.
webModeler public spec.webModeler is set. It is the client of the user interface.
webModelerApi confidential spec.webModeler is set. It is the client of the API behind that interface.

A confidential client names a clientSecretRef. A public client runs in a browser and holds no secret. Camunda lists the same split in Connect Management Identity to an identity provider.

apiVersion: core.camunda.io/v1
kind: CamundaPlatformConfig
metadata:
  name: my-platform-config
spec:
  auth:
    method: oidc
    oidc:
      issuerUrl: "https://login.example.com/realms/camunda"
      authUrl: "https://login.example.com/realms/camunda/protocol/openid-connect/auth"
      tokenUrl: "https://login.example.com/realms/camunda/protocol/openid-connect/token"
      jwksUrl: "https://login.example.com/realms/camunda/protocol/openid-connect/certs"
      clientId: "camunda-orchestration"
      clientSecretRef:
        name: "my-oidc-credentials"
        namespace: "camunda-system"
        key: "client-secret"
      management:
        clients:
          identity:
            clientId: "camunda-identity"
            clientSecretRef:
              name: "my-management-identity-credentials"
              namespace: "camunda-system"
              key: "client-secret"
          optimize:
            clientId: "camunda-optimize"
            clientSecretRef:
              name: "my-optimize-credentials"
              namespace: "camunda-system"
              key: "client-secret"
  # ... the rest of your platform config

authUrl, tokenUrl, and jwksUrl are optional for an orchestration cluster, which reads them from the discovery document of your provider. A CamundaManagementCluster in the oidc mode needs all three, because the ManagementAuthConfig carries them. Read them from the discovery document of your provider and set them here.

A CamundaManagementCluster that finds no client for a component it deploys reports Ready=False with reason InvalidReference, and the message names the missing field.

providerType tells Management Identity what kind of provider is behind the issuer. Leave it generic for any OIDC-compliant provider. Set it to microsoft for Microsoft Entra ID.

Images

spec.images renames the images that the operator pulls, one entry per image. Use it for a mirror:

apiVersion: core.camunda.io/v1
kind: CamundaPlatformConfig
metadata:
  name: my-platform-config
spec:
  images:
    optimize: "mirror.example.com/camunda/optimize"
  # ... the rest of your platform config

An Optimize instance of version 8.9.9 then pulls mirror.example.com/camunda/optimize:8.9.9.

Two rules govern the field:

  • A value is a full repository, registry included. It carries no tag and no digest. The tag always comes from the version field of the resource that runs the image.
  • An image that spec.images does not name keeps its default repository. To mirror every image, name every image.

A value that names a registry with a port needs a path after the port, as in registry:5000/camunda/optimize. The tag goes on the end of the value, so the bare registry:5000 becomes the image registry:5000:8.9.9, which no runtime accepts.

To pin one exact reference, digest or patched tag included, for the clusters of one rollout, use spec.images on a CamundaRelease instead.

Two images need care in a mirror:

  • Keycloak pulls the tag quay-optimized-<version>, not the bare version. Copy that tag into your mirror. Camunda publishes its Keycloak build under it, see Keycloak deployment.
  • From Camunda 8.10, Web Modeler runs from camunda/hub and camunda/hub-websockets, as the 8.10 chart README names. Your rename still applies at 8.10. So before you move to 8.10, copy these two images into the repositories that webModelerRestapi and webModelerWebsockets name.

Changes and referenced Secrets

When you change this resource, every referencing cluster rolls its pods with the new values. So does a change to a key that the clusters read from one of its Secrets. A change to the labels or annotations of a Secret rolls nothing. The Secrets live in the namespace that each reference names. The operator copies them into the namespace of each cluster that uses them, unless they already live there.

When a referenced Secret or key is missing, Ready is False with reason MissingSecret. The message starts with the spec path of the reference, for example spec.auth.oidc.management.clients.identity.clientSecretRef. Each referencing cluster also reports MissingSecret and keeps its workloads.

Deletion

A platform config owns nothing, so a delete removes nothing else. A CamundaCluster that still names it reports Ready: False with reason InvalidReference and keeps running on the configuration that the operator applied last.

Status

kubectl get camundaplatformconfig shows Ready, its reason, and the age.

Type Reason Meaning What to do
Ready Healthy Every referenced Secret exists and carries the named key. Nothing.
Ready MissingSecret A Secret named by clientSecretRef, a management client, or licenseSecretRef is missing, or lacks the named key. Create the Secret with the named key. The message starts with the spec path of the reference.

status.observedGeneration is the last generation the operator reconciled.

Fields

The API reference lists every field of CamundaPlatformConfig, with its type, whether it is required, its default, and its validation.

Validation rules

  • spec.auth.method is basic or oidc. spec.auth.oidc.providerType is generic or microsoft.
  • spec.auth.oidc is required when spec.auth.method is oidc, and forbidden when the method is basic.
  • In spec.auth.oidc, issuerUrl, clientId, and clientSecretRef are required.
  • issuerUrl must be an http or https URL. jwksUrl, tokenUrl, and authUrl must be empty or an http or https URL.
  • Each spec.images value is a lowercase repository name, with no tag and no digest. A registry host can carry a port, as in registry:5000/camunda/optimize. A host that carries a port needs a path after it, so the bare registry:5000 is refused.
  • The API server accepts this resource without the Secrets it names. The operator reports Ready=False with reason MissingSecret until each Secret exists, so you can create or rotate one later.

A production-shaped example

apiVersion: core.camunda.io/v1
kind: CamundaPlatformConfig
metadata:
  name: my-platform-config
spec:
  auth:
    method: oidc
    oidc:
      issuerUrl: "https://login.example.com/realms/camunda"
      clientId: "camunda-orchestration"
      audience: "camunda-orchestration"
      usernameClaim: "preferred_username"
      clientIdClaim: "client_id"
      clientSecretRef:
        name: "oidc-credentials"
        namespace: "camunda-system"
        key: "client-secret"
  licenseSecretRef:
    name: "camunda-license"
    namespace: "camunda-system"
    key: "license-key"
  images:
    camunda: "registry.example.com/camunda/camunda"
    optimize: "registry.example.com/camunda/optimize"