Keycloak realm export and import is more than just a backup; it’s a serialization of your entire identity and access management configuration.
Let’s see this in action. Imagine you’ve just set up a new Keycloak instance, configured a realm named my-app-realm with a few clients, users, and a custom login flow.
# Export the realm
docker exec keycloak-container \
/opt/keycloak/bin/kc.sh export --realm my-app-realm \
--file /tmp/my-app-realm.json \
--users realm_file
This command, executed inside the Keycloak container, dumps the entire configuration of my-app-realm into a JSON file located at /tmp/my-app-realm.json. The --users realm_file flag ensures that user data is also included in the export.
Now, let’s say you need to migrate this configuration to a new Keycloak instance or restore it after a disaster.
# Import the realm
docker exec new-keycloak-container \
/opt/keycloak/bin/kc.sh import --realm my-app-realm \
--file /tmp/my-app-realm.json
This imports the my-app-realm configuration into the new-keycloak-container. If the realm already exists, the import will typically fail unless specific options are used to overwrite or merge.
The problem Keycloak export/import solves is the tedious and error-prone process of manually recreating complex identity and access management setups. This includes:
- Clients: OAuth 2.0/OIDC clients, their configurations, redirect URIs, web origins, and assigned roles.
- Users: User accounts, their attributes, credentials (hashed, of course), and group memberships.
- Roles: Realm-level and client-level roles, and their composite relationships.
- User Federation: Configurations for LDAP or Active Directory integration.
- Identity Providers: Social logins (Google, Facebook), SAML, or OIDC identity providers.
- Authentication Flows: Custom login, registration, and account management flows.
- Mappers: Attribute mappers for SAML and OIDC.
- Event Listeners: Custom logic triggered by Keycloak events.
- API Settings: Token policies, client session timeouts, etc.
Internally, the kc.sh export command queries Keycloak’s internal representation of the realm’s configuration and serializes it into a structured JSON format. This JSON is not just a flat dump; it’s a hierarchical representation that mirrors Keycloak’s own data model. The kc.sh import command then parses this JSON and uses Keycloak’s administrative API to recreate these resources.
The exact levers you control are primarily within the export command itself. For instance, you can choose to export only the realm configuration without users using --users realm_export (which exports users as a separate JSON file) or --users reset (which will reset users on import). The --users realm_file option is often preferred for full backups as it embeds user data directly.
When importing, the --realm argument specifies the target realm. If you want to import into a different realm name than the one exported, you’d typically export, edit the JSON file to change the realm field, and then import. However, a more common scenario is importing into an existing realm, where Keycloak’s behavior defaults to an error if the realm already exists. To handle this, you might use the import --merge-users option if you want to add users to an existing realm rather than replace them entirely, or --force to overwrite the existing realm configuration.
A crucial detail often overlooked is that the export file contains sensitive information, including hashed passwords. Treat these export files with the same security precautions you would any sensitive configuration data. If you’re exporting and then importing across different Keycloak versions, minor discrepancies in the JSON schema might arise, requiring manual adjustments. For example, a new feature introduced in a later version might add new fields to the export that are not present in the older Keycloak’s import logic, or vice-versa. Always check the Keycloak version compatibility matrix for export/import operations.
The next potential hurdle is managing secrets like client secrets or federated identity provider secrets, which are not always directly exported in a usable format for re-importing into a different environment without additional steps.