Join us at KeycloakCon Japan 2026, colocated with KubeCon Japan 2026 · July 28 · Register Today →

Managing Keycloak Clients

Manage Keycloak OIDC and SAML clients declaratively using the operator.

Managing OIDC and SAML clients with the Operator

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.

Prerequisites

The following must be in place before creating client CRs.

Enable the Client Admin API feature

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
  ...

Configure the admin credentials

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.

Mutual TLS

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.

Creating an OIDC Client

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

Creating a SAML Client

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

Using Secret References for OIDC Authentication

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.

Checking Client Status

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.

Updating a Client

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.

Deleting a Client

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.

On this page