Self-hosted service
adorsys/keycloak-config-cli avatar
adorsys/keycloak-config-cli

keycloak-config-cli brings configuration as code to Keycloak

Import YAML/JSON-formatted configuration files into Keycloak - Configuration as Code for Keycloak.

1,212 stars205 forksJavaApache-2.0

At a glance

What is it?
keycloak-config-cli applies declarative, idempotent Keycloak configuration from YAML or JSON files through the Admin API, without restarting Keycloak. It suits teams that want realm configuration stored in Git and applied in CI/CD pipelines.
Who is it for?
Adopt keycloak-config-cli if you manage Keycloak realms across environments and want configuration reviewed in Git rather than clicked through the admin console; skip it if you only need a one-off realm import, because the built-in export and import path is simpler for that, and verify first which Keycloak version you run against the release and Dockerfile defaults and whether variable substitution is enabled in your setup.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly Java, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What keycloak-config-cli solves

keycloak-config-cli provides declarative, idempotent configuration for Keycloak via the Admin API. It is version-controlled and CI/CD-ready, covering realms, clients, roles, flows, identity providers and more. The goal is to ensure the desired configuration state for a realm from a JSON or YAML file, with no Keycloak restart required to apply the configuration. Configuration files can be stored and managed in Git like normal code.

The README frames this as Configuration as Code for Keycloak. That framing matters for the buyer: the alternative is clicking through the admin console or running one-off imports, which is hard to review and hard to reproduce across environments. This tool turns realm state into a file that can be diffed, reviewed and applied repeatedly.

How it works: realm exports, idempotent apply and variable substitution

Config files are based on the Keycloak realm export format, so you can reuse exported settings as a starting point. The README advises keeping files as small as possible and removing all UUIDs and everything that is set by default by Keycloak. A full working example exists at `contrib/example-config/moped.json`, with more examples in the test resources.

The apply path goes through the Admin API rather than through Keycloak's startup import, which is why no restart is needed. Variable substitution is supported but disabled by default, enabled with `import.var-substitution.enabled=true`. Variables exposed by Spring Boot can be accessed with `$(property.name)`, and the tool supports a long list of prefixes including `env`, `file`, `url`, `date`, `base64Decoder`, `base64Encoder`, `java`, `sys`, `properties`, `xml` and others, plus recursive replacement.

There is also an opt-in JavaScript evaluation phase, enabled with `import.var-substitution.script-evaluation-enabled=true`, using the syntax `$${javascript: ... }`. It is sandboxed and only has access to an `env` object containing environment variables and system properties, and only JSON-serializable outputs are allowed. Variable substitution runs before the JSON parser, which allows JSON structures or complex values. Since substitution is part of the tool, environment variables must be available where keycloak-config-cli runs.

Running it: Docker and the JAR

The README gives two quick-start paths. With Docker:

bash
docker run --rm \
  -e KEYCLOAK_URL="http://localhost:8080" \
  -e KEYCLOAK_USER=admin \
  -e KEYCLOAK_PASSWORD=admin123 \
  -e IMPORT_FILES_LOCATIONS='/config/*' \
  -v "$PWD/contrib/example-config":/config \
  adorsys/keycloak-config-cli:latest

This mounts a local config directory at `/config` and points the importer at it. With a downloaded or built JAR:

bash
java -jar ./target/keycloak-config-cli.jar \
  --keycloak.url=http://localhost:8080 \
  --keycloak.user=admin \
  --keycloak.password=admin123 \
  --import.files.locations=./contrib/example-config/moped.json

The Dockerfile builds with Java 21 and Maven, using Eclipse Temurin images, with build arguments for Keycloak version 26.5.5 and Keycloak client version 26.0.8. The runtime image sets `IMPORT_FILES_LOCATIONS=file:/config/*` and runs as user 65534. A `docker-compose.yml` is included with Keycloak, a legacy Keycloak variant, OpenLDAP and the config-cli service wired together, which is useful for reproducing the integration test setup.

Configuration as code versus Keycloak's built-in import

The real alternative is Keycloak's own realm export and import. That path works from files that follow the same export format, so the input is not the differentiator. The difference is operational. keycloak-config-cli applies state through the Admin API at runtime, and the README stresses that a Keycloak restart is not required. Built-in import is typically tied to startup, which means changing configuration means restarting or re-provisioning the server. If you only need to load a realm once on a fresh instance, the built-in path is simpler and has no extra dependency. If you need to reconcile configuration repeatedly in a pipeline, or to diff changes in Git, the CLI earns its place.

Limitations and failure modes

Variable substitution is disabled by default, so a configuration that uses `$(...)` placeholders will not be expanded unless `import.var-substitution.enabled=true` is set. JavaScript evaluation is a further opt-in on top of that. The environment variables referenced by substitution must exist where the tool runs, because substitution happens locally inside keycloak-config-cli rather than on the Keycloak server.

Config files should be kept small, with UUIDs and default values removed; large export dumps full of generated data are not the intended input. The README also points to a compatibility section, so check the documentation for which Keycloak versions a given release supports. The Dockerfile defaults to Keycloak 26.5.5, which is at least a concrete data point for the container path.

Maintenance, licence and upgrade cost

The repository is not archived and its last push was on 2026-09-14. Recent releases are v6.5.1 on 2026-05-22, v6.5.0 on 2026-03-12 and v6.4.1 on 2026-01-28. The licence is Apache-2.0, documented in `LICENSE.txt`. The project is Java, built with Maven using the wrapper scripts `mvnw` and `mvnw.cmd`, with Spring Boot configuration and checkstyle rules in the repository. Documentation lives in `DOCUMENTATION.md`, `docs/FEATURES.md` and `docs/javascript-substitution.md`, and help is available via GitHub issues and a Slack channel. Upgrading means tracking both the Keycloak server version and the client version embedded in the build, and the README's compatibility guidance should be checked before moving between Keycloak releases.

Editorial conclusion

Adopt keycloak-config-cli if you manage Keycloak realms across environments and want configuration reviewed in Git rather than clicked through the admin console; skip it if you only need a one-off realm import, because the built-in export and import path is simpler for that, and verify first which Keycloak version you run against the release and Dockerfile defaults and whether variable substitution is enabled in your setup.

Frequently asked questions

How do I import configuration into Keycloak with keycloak-config-cli?

Run the Docker image with `IMPORT_FILES_LOCATIONS` pointing at your config directory, or run the JAR with `--import.files.locations` pointing at a JSON or YAML file. The tool applies the configuration through the Admin API without restarting Keycloak.

What format do keycloak-config-cli config files use?

They are based on the Keycloak realm export format in JSON or YAML. The README advises keeping them small and removing UUIDs and values that Keycloak sets by default.

Is variable substitution enabled by default in keycloak-config-cli?

No, it is disabled by default and must be enabled with `import.var-substitution.enabled=true`. JavaScript evaluation is a further opt-in feature.

Does keycloak-config-cli require a Keycloak restart?

No. The README states that a Keycloak restart is not required to apply the configuration, because changes go through the Admin API.

Official sources

  1. adorsys/keycloak-config-cli on GitHub
  2. License: Apache-2.0
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/adorsys-keycloak-config-cli.svg)](https://hysenlabs.com/projects/adorsys-keycloak-config-cli)

Was this useful?