Secret references
Sensitive values belong in Kubernetes Secrets, not in Custom Resource YAML. The operator has two kinds of secret fields.
configSecretRef
CRs whose Keycloak payload has a definition.config map can merge every key from a Secret into that map before the operator talks to Keycloak:
- KeycloakIdentityProvider
- KeycloakComponent
- KeycloakProtocolMapper
- KeycloakIdentityProviderMapper
- KeycloakRequiredAction
Secret keys must already be the Keycloak config names (bindCredential, clientSecret, not password). Extra keys in the Secret are also pushed to Keycloak. Secret values win over the same key in definition.config.
A Secret generated by a KeycloakClient can be reused here if its clientSecretRef sets clientIdKey: clientId and clientSecretKey: clientSecret; the default client-id / client-secret keys are not recognised by Keycloak. See Realm-to-realm brokering.
The Secret must live in the same namespace as the CR. When the Secret changes, the operator re-reconciles.
kubectl create secret generic ldap-credentials \
--from-literal=bindCredential=s3cret
apiVersion: keycloak.hostzero.com/v1beta1
kind: KeycloakComponent
metadata:
name: ldap-federation
spec:
realmRef:
name: my-realm
name: corporate-ldap
configSecretRef:
name: ldap-credentials
definition:
providerId: ldap
providerType: org.keycloak.storage.UserStorageProvider
config:
enabled: ["true"]
vendor: ["ad"]
bindDn: ["cn=admin,dc=example,dc=com"]
Component config is a list of strings per key. The operator wraps each Secret value as ["…"] (bindCredential: "s3cret" in the Secret becomes ["s3cret"] in Keycloak). Identity providers, protocol mappers, identity provider mappers, and required actions keep string values.
configSecretRefs (KeycloakComponent)
KeycloakComponent also supports configSecretRefs, a plural form that maps individual Secret keys to specific Keycloak config keys. Use it when the Secret key names can’t match Keycloak’s config names (e.g. cert-manager emits tls.key / tls.crt but the realm key provider wants privateKey / certificate):
apiVersion: keycloak.hostzero.com/v1beta1
kind: KeycloakComponent
metadata:
name: external-signing-key
spec:
realmRef:
name: my-realm
name: external-signing-key
configSecretRefs:
- secretName: my-tls-secret
key: tls.key
configKey: privateKey
- secretName: my-tls-secret
key: tls.crt
configKey: certificate
definition:
providerId: rsa
providerType: org.keycloak.keys.KeyProvider
config:
enabled: ["true"]
Each mapping’s key is read from the referenced Secret and injected into definition.config under configKey as a single-element list. It can be combined with configSecretRef; a config key that is already set, inline or by configSecretRef, must not also be targeted by a mapping.
Other secret APIs
Do not use configSecretRef for these. They have their own typed fields:
| Resource | Field | Purpose |
|---|---|---|
| KeycloakClient | clientSecretRef | OAuth client id / secret |
| KeycloakRealm / ClusterKeycloakRealm | smtpSecretRef | SMTP username and password |
| KeycloakUserCredential | userSecret | User password |
| KeycloakInstance / ClusterKeycloakInstance | auth.*.secretRef, tls.caCert.* | Operator credentials to Keycloak, CA bundle |
Namespaced resources always read Secrets from their own namespace. Only the
cluster-scoped ClusterKeycloakInstance and ClusterKeycloakRealm take a
namespace on their references.