Skip to main content

Identity Domain

The Identity domain manages identity and access management for the Control Plane through Keycloak integration. It provisions identity providers, realms, and service-account clients in a declarative, Kubernetes-native way.

Custom Resources​

Client​

Client is the Schema for the clients API

Group: identity.cp.ei.telekom.de · Version: v1 · Scope: Namespaced

ClientSpec​

Appears in: Client

ClientSpec defines the desired state of Client

FieldTypeDefaultValidation
clientIdstring—Required
clientSecretstring—Required
realmObjectRef—Required

ObjectRef​

Appears in: ClientSpec, RealmSpec, Connection

ObjectRef is a reference to a Kubernetes object It is similar to types.NamespacedName but has the required json tags for serialization

FieldTypeDefaultValidation
namestring—Required
namespacestring—Required
uidstring—Optional

ClientStatus​

Appears in: Client

ClientStatus defines the observed state of Client

FieldTypeDefaultValidation
allowedOriginsstring[]—Optional
clientUidstring—Optional
conditionsCondition[]—Optional
issuerUrlstring—Required
rotatedClientSecretstring—Optional
rotatedSecretExpiresAtstring—Optional, Format: date-time
secretExpiresAtstring—Optional, Format: date-time

Condition​

Appears in: ClientStatus, IdentityProviderStatus, RealmStatus

FieldTypeDefaultValidation
lastTransitionTimestring—Required, Format: date-time
messagestring—Required, maxLength: 32768
observedGenerationinteger—Optional, Format: int64, minimum: 0
reasonstring—Required, minLength: 1, maxLength: 1024, pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
statusstring—Required, Enum: True \| False \| Unknown
typestring—Required, maxLength: 316, pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$

IdentityProvider​

IdentityProvider is the Schema for the identityproviders API

Group: identity.cp.ei.telekom.de · Version: v1 · Scope: Namespaced

IdentityProviderSpec​

Appears in: IdentityProvider

IdentityProviderSpec defines the desired state of IdentityProvider

FieldTypeDefaultValidation
adminClientIdstring—Required
adminPasswordstring—Required
adminUrlstring—Required
adminUserNamestring—Required
tlsTls—Optional

Tls​

Appears in: IdentityProviderSpec

TLS configures additional CA certificates trusted for the admin API and token endpoint. The referenced ConfigMap must be in the namespace of the IdentityProvider.

FieldTypeDefaultValidation
configMapRefConfigMapRef—Required

ConfigMapRef​

Appears in: Tls, RealmTls

ConfigMapRef references the PEM encoded CA certificates.

FieldTypeDefaultValidation
keystring—Required, minLength: 1, maxLength: 253, pattern: ^[-._a-zA-Z0-9]+$
namestring—Required, minLength: 1, maxLength: 253, pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$

IdentityProviderStatus​

Appears in: IdentityProvider

IdentityProviderStatus defines the observed state of IdentityProvider

FieldTypeDefaultValidation
adminConsoleUrlstring—Optional
adminTokenUrlstring—Required
adminUrlstring—Required
conditionsCondition[]—Optional

Realm​

Realm is the Schema for the realms API

Group: identity.cp.ei.telekom.de · Version: v1 · Scope: Namespaced

RealmSpec​

Appears in: Realm

RealmSpec defines the desired state of Realm

FieldTypeDefaultValidation
allowedOriginsstring[]—Optional
attributesmap<string, string>—Optional
claimsClaims[]—Optional
identityProviderObjectRef—Required
secretRotationSecretRotation—Optional

Claims​

Appears in: RealmSpec

Claims defines claims that are added to all tokens issued for clients in this realm. Each claim can be a static value (HardcodedClaim) or derived from a Keycloak session note (SessionNote). The controller manages a dedicated Keycloak client scope with protocol mappers for each claim.

FieldTypeDefaultValidation
namestring—Required, minLength: 1
typestringHardcodedClaimOptional, Enum: HardcodedClaim \| SessionNote
valuestring—Optional

SecretRotation​

Appears in: RealmSpec

SecretRotation configures the Keycloak client-secret rotation policy for this realm. When set, the controller ensures a client-policy profile + policy with the given grace period exists in Keycloak. When nil, the controller does not manage rotation policy.

FieldTypeDefaultValidation
expirationPeriodstring—Required
gracePeriodstring—Required
remainingRotationPeriodstring—Required

RealmStatus​

Appears in: Realm

RealmStatus defines the observed state of Realm

FieldTypeDefaultValidation
adminClientIdstring—Required
adminPasswordstring—Required
adminTokenUrlstring—Required
adminUrlstring—Required
adminUserNamestring—Required
conditionsCondition[]—Optional
connectionConnection—Optional
issuerUrlstring—Required
managedAttributesstring[]—Optional

Connection​

Appears in: RealmStatus

Connection identifies the IdentityProvider and CA bundle the admin connection fields above were derived from. Absent for realms reconciled before it was introduced.

FieldTypeDefaultValidation
identityProviderObjectRef—Required
tlsRealmTls—Optional

RealmTls​

Appears in: Connection

TLS references the CA bundle trusted for the connection. Absent means system roots only.

FieldTypeDefaultValidation
configMapRefConfigMapRef—Required
namespacestring—Required, minLength: 1

Secret Rotation Support​

When a Realm is configured with a secretRotation policy, the Identity domain provisions a Keycloak client-policy that enables graceful secret rotation for opted-in clients. During rotation:

  1. The current secret is moved to a "rotated" slot in Keycloak
  2. A new secret is set as the primary credential
  3. Both secrets are accepted until the grace period expires

Individual clients can opt out via the identity.cp.ei.telekom.de/disable-secret-rotation: "true" annotation.

Realm Attributes​

spec.attributes sets Keycloak realm attributes. Keys and values are passed to Keycloak as strings:

apiVersion: identity.cp.ei.telekom.de/v1
kind: Realm
metadata:
name: default
spec:
identityProvider:
name: my-idp
namespace: my-env--my-zone
attributes:
frontendUrl: https://iam.example.com/auth
displayName: Default realm

The controller only manages keys that it has applied itself. They are recorded in status.managedAttributes:

  • Attributes that were never listed in spec.attributes, for example attributes set manually in Keycloak, are left unchanged. This also applies to existing realms after an upgrade.
  • Removing a key from spec.attributes removes the attribute from Keycloak, but only if it is listed in status.managedAttributes. Setting a value to "" keeps the attribute with an empty value.
  • If the status cannot be written after Keycloak was updated (for example after a conflict), the ownership of newly added keys is lost. Such keys then stay in Keycloak when they are later removed from the spec and have to be removed manually.

Keys must not be empty. Do not store credentials or other secrets in attributes: they are stored in plain text in the Realm resource and in Keycloak.

Frontend URL and Issuer​

The frontendUrl attribute is the public base URL of Keycloak, not the issuer. Use an absolute http or https URL with a host and without credentials, query or fragment, for example https://iam.example.com/auth. A context path such as /auth is allowed and a trailing slash is ignored. An empty value means the frontend URL is not set. The value is not validated: it is passed to Keycloak as configured, and a misconfigured value is the responsibility of whoever set it.

status.issuerUrl is determined after every successful realm sync:

  1. If the realm has a valid frontendUrl (set by the spec or manually in Keycloak), the issuer is <frontendUrl>/realms/<realm>, for example https://iam.example.com/auth/realms/default.
  2. Otherwise (no or an invalid frontendUrl), the issuer is read from the realm's OIDC discovery document (/.well-known/openid-configuration). The document is fetched through the identity provider's admin URL, without admin credentials, using the same TLS settings as the admin API. The admin URL itself is never used as the issuer. The discovered issuer must be an http(s) URL without credentials, query or fragment ending with /realms/<realm>; otherwise the Realm is blocked.

If the issuer cannot be determined, for example because the discovery request fails, the controller clears status.issuerUrl, marks the Realm as not ready and retries. Clients of the realm are not provisioned until a confirmed issuer is available.

caution

Without a frontendUrl, Keycloak derives the issuer from the request it receives (depending on its hostname configuration). The issuer discovered through the internal admin URL may then differ from the issuer seen by external clients. Set frontendUrl, or configure a fixed Keycloak hostname, to get a stable public issuer.

Admin Connection Trust and Snapshots​

IdentityProvider.spec.tls.configMapRef optionally references CA certificates in a ConfigMap in the IDP's namespace. Realm and Client operations use these certificates, in addition to system roots, for both password/refresh token requests and the Keycloak admin API. Trust failures appear on those operations, not as proactive IdentityProvider readiness checks.

A Realm's status.connection records its IDP name, namespace, and UID, plus the optional CA reference and originating namespace; it contains no certificate bytes. Deletion can therefore use the stored connection without reading a live IDP. Clients use the same Realm snapshot and shared IDP-scoped factory. Old and new connection versions can coexist during reconciliation.

Legacy Realms without status.connection keep system-only behavior and Realm-scoped cache isolation. Present but incomplete connection metadata blocks the operation rather than silently discarding custom TLS. Missing trust retains finalizers when remote deletion is required; the existing Client exception for a missing or non-ready Realm remains unchanged.

See standalone examples and Outbound TLS Clients for the shared factory, leases, authentication lifetime, and recovery.

Domain Interactions​

  • Admin domain — Zones define which identity provider to use.
  • Organization domain — Team creation provisions identity clients.
  • Application domain — Application creation provisions identity clients.
  • Event domain — EventConfig provisioning creates identity clients for OAuth2 token exchange.
  • Secret Manager — Resolves secret references before provisioning clients in Keycloak.