apiVersion: k8s.keycloak.org/v2beta1
kind: Keycloak
metadata:
name: example-kc
spec:
features:
enabled:
- client-admin-api:v2
...
| This feature is experimental and may introduce breaking changes in future versions of Keycloak. Do not use this feature in production environments. |
To provide feedback, use the Client Admin API v2 GitHub Discussion.
The Keycloak Operator can manage OIDC and SAML clients declaratively through Custom Resources. The operator creates, updates, and deletes clients on the Keycloak server to match the desired state defined in the CR.
|
Do not modify operator-managed clients through the Admin UI or API, including server-side client secret rotation. The operator does not detect external changes and will overwrite them. A future release will introduce resource ownership controls that prevent such modifications automatically. |
The following must be in place before creating client CRs.
The client-admin-api:v2 feature must be enabled on the Keycloak server.
For more details about this API, see the Admin API v2: Reference guide.
Add it to the Keycloak CR:
apiVersion: k8s.keycloak.org/v2beta1
kind: Keycloak
metadata:
name: example-kc
spec:
features:
enabled:
- client-admin-api:v2
...
The operator authenticates to Keycloak using the client credentials flow against the master realm.
It reads credentials from a Kubernetes Secret named <keycloak-cr-name>-admin in the same namespace, which must contain client-id and client-secret keys.
This Secret must be created manually as part of the bootstrap admin setup.
For setup details, see the Admin Bootstrapping section in the Advanced configuration guide.
A future release may simplify this by automating the credential setup.
If Keycloak Configuring trusted certificates for mTLS,
spec.admin.tlsSecret is used to provide the name of a Kubernetes TLS Secret containing the operator’s client certificate and private key (tls.crt and tls.key), which must be trusted by the server.
Create a file my-oidc-client.yaml:
apiVersion: k8s.keycloak.org/v2alpha1
kind: KeycloakOIDCClient
metadata:
name: my-oidc-app (1)
spec:
keycloakCRName: example-kc (2)
realm: my-realm (3)
client: (4)
loginFlows:
- STANDARD
redirectUris:
- "https://my-app.example.com/*"
| 1 | Becomes the clientId in Keycloak. Cannot be changed after creation. |
| 2 | Must match the metadata.name of the Keycloak CR (e.g., example-kc from the prerequisite example). Cannot be changed after creation. |
| 3 | The realm where the client is created. Cannot be changed after creation. |
| 4 | Available fields are defined by the client representations in the Admin API v2: Reference guide. |
Apply the CR:
kubectl apply -f my-oidc-client.yaml
Create a file my-saml-client.yaml:
apiVersion: k8s.keycloak.org/v2alpha1
kind: KeycloakSAMLClient
metadata:
name: my-saml-app
spec:
keycloakCRName: example-kc
realm: my-realm
client:
nameIdFormat: persistent
signDocuments: true
signAssertions: true
forcePostBinding: true
Apply the CR:
kubectl apply -f my-saml-client.yaml
OIDC clients that use client-secret authentication can store the secret in a Kubernetes Secret rather than inline in the CR.
apiVersion: v1
kind: Secret
metadata:
name: my-app-credentials
stringData:
client-secret-key: "my-secret"
apiVersion: k8s.keycloak.org/v2alpha1
kind: KeycloakOIDCClient
metadata:
name: my-confidential-app
spec:
keycloakCRName: example-kc
realm: my-realm
client:
auth:
method: client-secret
secretRef:
name: my-app-credentials (1)
key: client-secret-key (2)
| 1 | Name of the Kubernetes Secret in the same namespace. |
| 2 | Key within the Secret that holds the client secret value. |
If the referenced Secret does not exist, the CR will report a HasErrors status condition.
When the value in the Kubernetes Secret changes, the operator detects the change within its polling interval and updates the client on the Keycloak server.
To check the status of a client CR:
kubectl get keycloakoidcclients/my-oidc-app -o go-template='{{range .status.conditions}}CONDITION: {{.type}}{{"\n"}} STATUS: {{.status}}{{"\n"}} MESSAGE: {{.message}}{{"\n"}}{{end}}'
When the client has been created successfully:
CONDITION: HasErrors
STATUS: false
MESSAGE:
Common error causes include a missing client-admin-api:v2 feature, a missing secret reference, or the Keycloak server not being ready.
The operator retries the operation periodically until it succeeds.
To update a client, modify the spec.client fields in the CR and re-apply:
kubectl apply -f my-oidc-client.yaml
The Custom Resource must contain the complete desired client configuration. The operator detects changes and updates the client on the Keycloak server.
To delete a client from Keycloak, delete the CR:
kubectl delete keycloakoidcclients/my-oidc-app
The operator deletes the client from the Keycloak server before removing the CR.
|
If the Keycloak CR is deleted before the client CR, the operator cannot reach the server and the client will remain on the Keycloak server. |