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

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