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

KeycloakClient

A KeycloakClient represents an OAuth2/OIDC client within a Keycloak realm.

Specification

apiVersion: keycloak.hostzero.com/v1beta1
kind: KeycloakClient
metadata:
  name: my-app
spec:
  # One of realmRef or clusterRealmRef must be specified
  
  # Option 1: Reference to a namespaced KeycloakRealm
  realmRef:
    name: my-realm
    namespace: default  # Optional
  
  # Option 2: Reference to a ClusterKeycloakRealm
  # clusterRealmRef:
  #   name: my-cluster-realm
  
  # Optional: Client ID in Keycloak (defaults to metadata.name)
  clientId: my-app
  
  # Optional: Client definition (Keycloak ClientRepresentation)
  definition:
    clientId: my-app
    name: My Application
    enabled: true
    publicClient: false
    # ... any other Keycloak client properties
  
  # Optional: Configure client secret handling
  clientSecretRef:
    name: my-app-credentials
    # clientIdKey: client-id       # Default: client-id
    # clientSecretKey: client-secret  # Default: client-secret
    # create: true                 # Default: true

Status

status:
  ready: true
  status: "Ready"
  clientUUID: "12345678-1234-1234-1234-123456789abc"
  resourcePath: "/admin/realms/my-realm/clients/12345678-..."
  message: "Client synchronized successfully"
  instance:
    instanceRef: my-keycloak
  realm:
    realmRef: my-realm
  conditions:
    - type: Ready
      status: "True"
      reason: Synchronized

Client Secret Handling

The clientSecretRef field controls how client secrets are managed:

FieldTypeDefaultDescription
namestring(required)Name of the Kubernetes Secret
clientIdKeystringclient-idKey for the client ID in the secret
clientSecretKeystringclient-secretKey for the client secret in the secret
createbooleantrueWhether to create the secret if it doesn’t exist

Behavior

  • If the secret exists: The operator reads the client secret from the specified key and configures Keycloak to use it.
  • If the secret doesn’t exist and create: true: The operator lets Keycloak auto-generate a secret and creates the Kubernetes Secret.
  • If the secret doesn’t exist and create: false: The operator reports an error (strict mode for GitOps workflows).

Use Cases

Auto-generate secret (default):

clientSecretRef:
  name: my-app-credentials
  # create: true (default)

Use pre-existing secret (GitOps/Sealed Secrets):

clientSecretRef:
  name: my-sealed-secret
  create: false

Custom key names:

clientSecretRef:
  name: my-credentials
  clientIdKey: OIDC_CLIENT_ID
  clientSecretKey: OIDC_CLIENT_SECRET

Examples

Public Client (SPA)

apiVersion: keycloak.hostzero.com/v1beta1
kind: KeycloakClient
metadata:
  name: my-spa
spec:
  realmRef:
    name: my-realm
  definition:
    clientId: my-spa
    name: My Single Page Application
    enabled: true
    publicClient: true
    standardFlowEnabled: true
    directAccessGrantsEnabled: false
    rootUrl: https://my-app.example.com
    redirectUris:
      - https://my-app.example.com/*
    webOrigins:
      - https://my-app.example.com

Confidential Client (Backend)

apiVersion: keycloak.hostzero.com/v1beta1
kind: KeycloakClient
metadata:
  name: my-api
spec:
  realmRef:
    name: my-realm
  definition:
    clientId: my-api
    name: My Backend API
    enabled: true
    publicClient: false
    serviceAccountsEnabled: true
    standardFlowEnabled: false
    directAccessGrantsEnabled: false
  clientSecretRef:
    name: my-api-credentials

Service Account with Roles

apiVersion: keycloak.hostzero.com/v1beta1
kind: KeycloakClient
metadata:
  name: my-service
spec:
  realmRef:
    name: my-realm
  definition:
    clientId: my-service
    name: My Service Account
    enabled: true
    publicClient: false
    serviceAccountsEnabled: true
    standardFlowEnabled: false
    directAccessGrantsEnabled: false
    authorizationServicesEnabled: true
  clientSecretRef:
    name: my-service-credentials

Using Pre-existing Secret (Sealed Secrets / External Secrets)

# First, create or have your secret management tool create the secret:
apiVersion: v1
kind: Secret
metadata:
  name: my-sealed-secret
type: Opaque
data:
  client-id: bXktYXBw          # base64 encoded
  client-secret: c2VjcmV0...   # base64 encoded
---
# Then reference it with create: false
apiVersion: keycloak.hostzero.com/v1beta1
kind: KeycloakClient
metadata:
  name: my-app
spec:
  realmRef:
    name: my-realm
  definition:
    clientId: my-app
    enabled: true
    publicClient: false
  clientSecretRef:
    name: my-sealed-secret
    create: false  # Error if secret doesn't exist

Generated Secret Format

When the operator creates or manages a secret, it has this structure:

apiVersion: v1
kind: Secret
metadata:
  name: my-app-credentials
  ownerReferences:
    - apiVersion: keycloak.hostzero.com/v1beta1
      kind: KeycloakClient
      name: my-app
type: Opaque
data:
  client-id: bXktYXBw          # base64 encoded
  client-secret: c2VjcmV0...   # base64 encoded

Authentication Flow Binding Overrides

Keycloak allows overriding the default authentication flows (browser, direct grant) per client via authenticationFlowBindingOverrides. Normally this requires the internal UUID of the flow, which is generated dynamically and differs across environments – making it incompatible with GitOps.

The operator supports alias-based references so you can use the human-readable flow alias instead:

Alias KeyResolves ToDescription
browserFlowAliasbrowserBrowser authentication flow
directGrantFlowAliasdirect_grantDirect grant (Resource Owner Password) flow

The operator resolves aliases to UUIDs at reconciliation time. If both an alias key and the corresponding UUID key are present, the alias takes precedence.

Example: Using flow aliases

apiVersion: keycloak.hostzero.com/v1beta1
kind: KeycloakClient
metadata:
  name: my-app
spec:
  realmRef:
    name: my-realm
  definition:
    clientId: my-app
    enabled: true
    publicClient: true
    standardFlowEnabled: true
    authenticationFlowBindingOverrides:
      browserFlowAlias: "my-custom-browser-flow"
      directGrantFlowAlias: "my-custom-direct-grant"

Example: Using UUIDs (unchanged, still supported)

    authenticationFlowBindingOverrides:
      browser: "a3f5c2d1-1234-5678-90ab-abcdef123456"
      direct_grant: "b4e6d3a2-2345-6789-01bc-bcdef2345678"

If the specified alias does not match any authentication flow in the realm, the operator reports a FlowAliasResolutionFailed status with a descriptive error message.

Definition Properties

Common properties from Keycloak ClientRepresentation:

PropertyTypeDescription
clientIdstringClient identifier (required)
namestringDisplay name
enabledbooleanWhether client is enabled
publicClientbooleanPublic or confidential client
standardFlowEnabledbooleanEnable Authorization Code flow
directAccessGrantsEnabledbooleanEnable Resource Owner Password flow
serviceAccountsEnabledbooleanEnable service account
redirectUrisstring[]Valid redirect URIs
webOriginsstring[]Allowed CORS origins
rootUrlstringRoot URL for relative URIs

Short Names

AliasFull Name
kcckeycloakclients
kubectl get kcc