KeycloakInstance
A KeycloakInstance represents a connection to a Keycloak server. It is the root resource for managing Keycloak configuration in a namespace.
Specification
apiVersion: keycloak.hostzero.com/v1beta1
kind: KeycloakInstance
metadata:
name: my-keycloak
spec:
baseUrl: https://keycloak.example.com
# Optional: admin realm to authenticate against (default: master)
realm: master
# Required: exactly one of auth.passwordGrant or auth.clientCredentials
auth:
# Password grant via an admin user (e.g. master-realm admin)
passwordGrant:
# Optional inline username; when set, overrides secretRef.usernameKey
username: admin
secretRef:
name: keycloak-admin
# Optional: namespace of the secret (defaults to resource namespace)
namespace: keycloak-operator
# Optional: keys inside the secret (defaults shown)
usernameKey: username
passwordKey: password
# OR: client_credentials grant via a confidential client
clientCredentials:
# Optional inline client_id; when set, overrides secretRef.clientIdKey
clientId: keycloak-operator
secretRef:
name: keycloak-operator-client
namespace: keycloak-operator
clientIdKey: client-id
clientSecretKey: client-secret
# Optional: TLS verification for the Keycloak HTTPS endpoint
tls:
# Reference a PEM-encoded CA bundle from a Secret or ConfigMap
caCert:
# Use either secretRef OR configMapRef (mutually exclusive)
secretRef:
name: keycloak-ca
# Optional: defaults to the KeycloakInstance namespace
namespace: keycloak-operator
# Optional: key inside the secret (default: ca.crt)
key: ca.crt
# configMapRef:
# name: keycloak-ca
# key: ca.crt
# Disable TLS verification entirely. Do not use in production.
insecureSkipVerify: false
# Optional: token caching configuration
token:
secretName: keycloak-token-cache
tokenKey: token
expiresKey: expires
TLS
spec.tls is optional. When omitted, the operator uses the system CA pool to
verify the Keycloak server certificate.
tls.caCertreferences a PEM-encoded CA bundle from either aSecretor aConfigMap. Exactly one ofsecretRef/configMapRefmay be set; setting both is rejected by admission. The default key isca.crt.tls.insecureSkipVerify: truedisables certificate verification. When set,caCertis ignored.
Authentication
Exactly one of auth.passwordGrant or auth.clientCredentials must be set; the
admission webhook rejects specs that omit both or set both. auth.passwordGrant
issues a password-grant token (typical for the master-realm admin user);
auth.clientCredentials issues a client_credentials token against a
confidential client / service account.
Username and client_id are not secrets, so they can be either inlined on the
spec or read from a key of the referenced Secret. When the inline field is set,
the corresponding *Key field on secretRef is ignored. Passwords and client
secrets always come from the Secret.
Credentials Secret (password grant)
apiVersion: v1
kind: Secret
metadata:
name: keycloak-admin
type: Opaque
stringData:
username: admin
password: your-secure-password
Client credentials Secret
apiVersion: v1
kind: Secret
metadata:
name: keycloak-operator-client
type: Opaque
stringData:
client-id: keycloak-operator
client-secret: your-client-secret
A one-liner:
kubectl create secret generic keycloak-operator-client \
--from-literal=client-id=keycloak-operator \
--from-literal=client-secret=$(openssl rand -hex 32)
Status
status:
ready: true
version: "26.0.0"
status: "Ready"
message: "Connected to Keycloak"
conditions:
- type: Ready
status: "True"
reason: Ready
lastTransitionTime: "2024-01-01T12:00:00Z"
Examples
Basic instance with password grant
apiVersion: keycloak.hostzero.com/v1beta1
kind: KeycloakInstance
metadata:
name: production-keycloak
namespace: keycloak-operator
spec:
baseUrl: https://auth.example.com
auth:
passwordGrant:
secretRef:
name: keycloak-admin
Service-account client
apiVersion: keycloak.hostzero.com/v1beta1
kind: KeycloakInstance
metadata:
name: production-keycloak
spec:
baseUrl: https://auth.example.com
auth:
clientCredentials:
secretRef:
name: keycloak-operator-client
Migrating from the pre-auth shape
Earlier v1beta1 revisions used spec.credentials and spec.client at the
top level. The fields have been replaced by spec.auth. Existing manifests
must be migrated; the operator rejects the old shape.
Password grant
Before:
spec:
baseUrl: https://auth.example.com
credentials:
secretRef:
name: keycloak-admin
usernameKey: username
passwordKey: password
After:
spec:
baseUrl: https://auth.example.com
auth:
passwordGrant:
secretRef:
name: keycloak-admin
usernameKey: username
passwordKey: password
Client credentials
Before (client_id and client_secret were inlined in the spec):
spec:
baseUrl: https://auth.example.com
credentials:
secretRef:
name: dummy-unused-admin
client:
id: keycloak-operator
secret: my-client-secret
After (move the credentials into a Secret, drop the dummy credentials block):
spec:
baseUrl: https://auth.example.com
auth:
clientCredentials:
secretRef:
name: keycloak-operator-client
with a companion Secret:
kubectl create secret generic keycloak-operator-client \
--from-literal=client-id=keycloak-operator \
--from-literal=client-secret=my-client-secret
Short names
| Alias | Full name |
|---|---|
kci | keycloakinstances |
kubectl get kci