Exporting Realms & Users¶
This guide provides instructions for exporting Keycloak realms, users, and secrets for migration purposes. These exports can be used to migrate existing Keycloak installations to this operator.
Overview¶
The migration process generally involves: 1. Exporting data from your existing Keycloak instance. 2. Transforming configuration into Kubernetes Custom Resources (CRDs). 3. Importing data (users, sessions) into the new instance.
Scope of Export¶
Standard Keycloak exports include: * Realm Configuration: Roles, groups, settings. * Clients: Configurations, redirect URIs. * Users: Credentials (hashed), attributes, role mappings. * Secrets: Client secrets and hashed user passwords (encrypted).
Scenarios¶
Choose the instruction set that matches your current environment.
1. Kubernetes (Clustered Quarkus with Infinispan)¶
For Keycloak deployed on Kubernetes (Quarkus distribution) with an external database (e.g., CNPG, RDS).
Prerequisites:
* kubectl access to the cluster.
* Database credentials (usually in a Secret).
Steps:
-
Identify Database Credentials: Locate the secret containing your database credentials.
-
Scale Down Keycloak: To ensure data consistency and release database locks, scale the Keycloak StatefulSet to 0.
-
Run Export Job: Deploy a temporary Job to perform the export. Replace environment variables with your specific database configuration.
# export-job.yaml apiVersion: batch/v1 kind: Job metadata: name: keycloak-export namespace: keycloak-namespace spec: template: spec: containers: - name: keycloak image: quay.io/keycloak/keycloak:26.0.0 # Use your current version command: ["/bin/sh", "-c"] args: - | /opt/keycloak/bin/kc.sh export --dir /tmp/export --users realm_file --realm my-realm # Keep pod running to allow copying sleep 3600 env: - name: KC_DB value: postgres - name: KC_DB_URL value: jdbc:postgresql://keycloak-db-rw:5432/keycloak - name: KC_DB_USERNAME valueFrom: secretKeyRef: name: keycloak-db-credentials key: username - name: KC_DB_PASSWORD valueFrom: secretKeyRef: name: keycloak-db-credentials key: password restartPolicy: Never -
Copy Exported Data: Once the job is running (check
kubectl get pods), copy the files to your local machine. -
Cleanup:
2. Single Node Container (Docker/Podman)¶
For a single Keycloak container running locally or on a server.
Steps:
-
Stop the Container:
-
Run Export: Run a temporary container attached to the same network/volume/database.
If using an external database container:
docker run --rm \ --network keycloak-network \ -v $(pwd)/export:/tmp/export \ -e KC_DB=postgres \ -e KC_DB_URL=jdbc:postgresql://postgres-container:5432/keycloak \ -e KC_DB_USERNAME=keycloak \ -e KC_DB_PASSWORD=password \ quay.io/keycloak/keycloak:26.0.0 \ export --dir /tmp/export --users realm_file --realm my-realmIf using an internal H2 database (not recommended for production): You must mount the data volume of the stopped container.
3. Single Node VM (Systemd/Bare Metal)¶
For Keycloak running directly on a Virtual Machine.
Steps:
-
Stop Keycloak Service:
-
Run Export Command: Switch to the Keycloak user and run the export CLI.
-
Restart Service:
4. Legacy WildFly Keycloak (Pre-Quarkus)¶
Older versions of Keycloak (16 and below) running on WildFly require a different approach.
Strategy: Upgrade then Export Directly exporting from WildFly and importing into Quarkus often leads to compatibility issues. The recommended path is:
- Migrate Database: Perform a database migration to a newer Keycloak version (Quarkus) using the official Keycloak migration guide.
- Export from New Version: Once the database is upgraded and running with a Quarkus distribution, use Scenario 1, 2, or 3 above to perform the export.
Importing into Keycloak Operator¶
This operator follows a GitOps-first approach. It manages configuration (Realms, Clients) but does not manage stateful data (Users, Sessions) via CRDs.
1. Transform Configuration with the Migration Toolkit¶
Use the Migration Toolkit to automatically transform your export files into Helm chart values:
keycloak-migrate transform \
--input ./keycloak-export/my-realm-realm.json \
--output-dir ./migration-output \
--operator-namespace keycloak-system \
--secret-mode eso \
--eso-store my-vault-store
This produces:
realm-values.yaml— Helm values for thekeycloak-realmchartclients/<name>/values.yaml— Helm values for eachkeycloak-clientchart releasesecrets.yaml— Secret manifests (plain, ExternalSecret, or SealedSecret)unsupported-features.json— Features not yet supported with tracking issue linksNEXT-STEPS.md— Actionable migration checklist
See the Migration Toolkit Guide for full command reference, secret mode options, and examples.
2. Deploy with Helm¶
# Deploy realm
helm install my-realm keycloak-realm \
-f migration-output/my-realm/realm-values.yaml \
-n my-namespace
# Deploy each client
helm install my-app keycloak-client \
-f migration-output/my-realm/clients/my-app/values.yaml \
-n my-namespace
3. Import Users (Data Migration)¶
Since the KeycloakRealm CRD does not manage users, you must import them separately.
Option A: Database Migration (Recommended) If migrating the entire installation, backup and restore the PostgreSQL database directly using CloudNativePG. This preserves all data, including users, sessions, and history.
- See Database Setup Guide for restore instructions.
Option B: Partial Import (Manual) If starting fresh and only migrating specific users:
- Deploy Keycloak using the operator.
- Log in to the Keycloak Admin Console.
- Navigate to Realm Settings > Partial Import.
- Upload the
users.jsonfile generated by the migration toolkit. - Select Overwrite or Skip strategy as needed.
User passwords are preserved
Keycloak exports include password hashes. Users imported via Partial Import retain their existing passwords — no password reset is required.