Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Custom Resource Definitions

The Keycloak Operator provides several Custom Resource Definitions (CRDs) to manage Keycloak resources declaratively.

Resource Hierarchy

KeycloakInstance / ClusterKeycloakInstance
    └── KeycloakRealm / ClusterKeycloakRealm
            ├── KeycloakClient
            │       ├── KeycloakUser (service account, via clientRef)
            │       ├── KeycloakRole (client role)
            │       └── KeycloakProtocolMapper
            ├── KeycloakUser (regular users, via realmRef)
            │       └── KeycloakUserCredential
            ├── KeycloakGroup
            ├── KeycloakClientScope
            │       └── KeycloakProtocolMapper
            ├── KeycloakRole (realm role)
            ├── KeycloakRoleMapping (maps roles to Users/Groups)
            ├── KeycloakComponent (LDAP, key providers, etc.)
            ├── KeycloakIdentityProvider
            │       └── KeycloakIdentityProviderMapper
            ├── KeycloakAuthenticationFlow
            ├── KeycloakRequiredAction
            └── KeycloakOrganization (requires Keycloak 26+)

Overview

Instance Resources

CRDDescriptionScope
KeycloakInstanceConnection to a Keycloak serverNamespaced
ClusterKeycloakInstanceCluster-scoped Keycloak connectionCluster

Realm Resources

CRDDescriptionParent
KeycloakRealmRealm configurationKeycloakInstance
ClusterKeycloakRealmCluster-scoped realmClusterKeycloakInstance

OAuth & Client Resources

CRDDescriptionParent
KeycloakClientOAuth2/OIDC clientKeycloakRealm
KeycloakClientScopeClient scope configurationKeycloakRealm
KeycloakProtocolMapperToken claim mappersKeycloakClient or KeycloakClientScope

Identity Resources

CRDDescriptionParent
KeycloakUserUser managementKeycloakRealm or KeycloakClient¹
KeycloakUserCredentialUser password managementKeycloakUser
KeycloakGroupGroup managementKeycloakRealm

Role & Access Control

CRDDescriptionParent
KeycloakRoleRealm and client rolesKeycloakRealm or KeycloakClient
KeycloakRoleMappingRole-to-subject mappingsKeycloakUser or KeycloakGroup

Federation & Infrastructure

CRDDescriptionParent
KeycloakComponentLDAP federation, key providersKeycloakRealm
KeycloakIdentityProviderExternal identity providersKeycloakRealm
KeycloakIdentityProviderMapperIdentity provider claim/role/attribute mappersKeycloakIdentityProvider
KeycloakAuthenticationFlowCustom authentication / registration flowsKeycloakRealm
KeycloakRequiredActionRequired action providers (e.g. update password, verify email)KeycloakRealm
KeycloakOrganizationOrganization management²KeycloakRealm

¹ KeycloakUser supports clientRef for managing service account users associated with a client
² KeycloakOrganization requires Keycloak 26.0.0 or later

Common Patterns

Spec Layout

Every CRD that mirrors a Keycloak representation is built from the same four layers:

  1. Placement refs — typed references that anchor the resource in the hierarchy: realmRef, clusterRealmRef, clientRef, clientScopeRef, parentGroupRef, identityProviderRef, …
  2. Identity — one typed, required, immutable field naming the object in Keycloak: realmName, clientId, username, alias, or name. It is mirrored to status and shown as a printer column.
  3. Kubernetes integration — typed fields for anything that touches cluster objects or other CRs: Secret references (clientSecretRef, smtpSecretRef, configSecretRef), initialPassword, tokenExchange. The operator injects these into the payload or applies them through separate Keycloak API calls.
  4. Payloadspec.definition, the verbatim Keycloak API representation. The operator writes into it (identifier, secret merges) but never reads configuration out of it; everything else passes through unchanged. This is what lets you configure any Keycloak property, even ones the CRD does not model.
spec:
  instanceRef:                  # 1. placement
    name: my-keycloak
  realmName: my-realm           # 2. identity
  smtpSecretRef:                # 3. Kubernetes integration
    name: smtp-credentials
  definition:                   # 4. payload — full Keycloak API object
    enabled: true
    displayName: My Realm

Every datum has exactly one home. A value that belongs to a typed layer must not also be configured inside definition: an identifier in the definition is tolerated only when it matches the spec field, and a conflicting value sets Ready=False.

Fully typed CRDs without a definition (KeycloakInstance, KeycloakRoleMapping, KeycloakUserCredential) are operator constructs rather than representation mirrors, so they have no payload layer.

For contributors, the layer of a new field follows mechanically:

  • References a Kubernetes object or another CR? → typed spec field (layer 3).
  • Managed through a separate Keycloak API endpoint rather than the representation PUT? → its own CRD (like KeycloakRoleMapping) or a typed spec section — never keys inside definition.
  • Part of the Keycloak representation itself? → stays in definition, untyped.

Status Tracking

All resources expose status information:

status:
  ready: true
  message: "Resource synchronized successfully"
  conditions:
    - type: Ready
      status: "True"
      lastTransitionTime: "2024-01-01T00:00:00Z"
      reason: Synchronized
      message: "Resource is in sync with Keycloak"

Finalizers

Resources use finalizers to ensure proper cleanup when deleted:

metadata:
  finalizers:
    - keycloak.hostzero.com/finalizer

Preserving Resources on Deletion

By default, when you delete a Custom Resource, the operator also deletes the corresponding resource in Keycloak. If you want to keep the resource in Keycloak while removing the CR from Kubernetes, use the keycloak.hostzero.com/preserve-resource annotation:

apiVersion: keycloak.hostzero.com/v1beta1
kind: KeycloakRealm
metadata:
  name: my-realm
  annotations:
    keycloak.hostzero.com/preserve-resource: "true"
spec:
  # ...

When this annotation is set to "true", deleting the CR will:

  • Remove the CR from Kubernetes
  • Keep the resource in Keycloak untouched

This is useful for scenarios like:

  • Migrating management of a resource to a different system
  • Temporarily removing operator control without losing data
  • Testing or debugging without affecting production resources

Note: The annotation value must be exactly "true" (as a string) to preserve the resource. Any other value (or absence of the annotation) will result in normal deletion behavior.

Supported Resources: This annotation works with all resource types except KeycloakInstance and ClusterKeycloakInstance (which don’t manage Keycloak resources directly).

API Version

All CRDs use the keycloak.hostzero.com/v1beta1 API version:

apiVersion: keycloak.hostzero.com/v1beta1
kind: KeycloakRealm