Sign inSign up

adorsys/keycloak-config-cli

By adorsys

•Updated 23 days ago

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

Image
3

1M+

adorsys/keycloak-config-cli repository overview

CI GitHub release (latest SemVer) GitHub All Releases Docker Pulls codecov GitHub license

⁠Table of Contents

⁠keycloak-config-cli

keycloak-config-cli is a Keycloak utility to ensure the desired configuration state for a realm based on a JSON/YAML file. The format of the JSON/YAML file based on the export realm format. Store and handle the configuration files inside git just like normal code. A Keycloak restart isn't required to apply the configuration.

⁠Config files

The config files are based on the keycloak export files. You can use them to re-import your settings. But keep your files as small as possible. Remove all UUIDs and all stuff which is default set by keycloak.

moped.json⁠ is a full working example file you can consider. Other examples are located in the test resources⁠.

⁠Variable Substitution

keycloak-config-cli supports variable substitution of config files. This could be enabled by import.var-substitution.enabled=true (disabled by default).

Variables exposed by spring boot (through configtree or external configuration⁠) can be accessed by $(property.name).

In additional, the string substitution support multiple prefixes for different approaches

Base64 Decoder:        $(base64Decoder:SGVsbG9Xb3JsZCE=)
Base64 Encoder:        $(base64Encoder:HelloWorld!)
Java Constant:         $(const:java.awt.event.KeyEvent.VK_ESCAPE)
Date:                  $(date:yyyy-MM-dd)
DNS:                   $(dns:address|apache.org)
Environment Variable:  $(env:USERNAME)
File Content:          $(file:UTF-8:src/test/resources/document.properties)
Java:                  $(java:version)
Localhost:             $(localhost:canonical-name)
Properties File:       $(properties:src/test/resources/document.properties::mykey)
Resource Bundle:       $(resourceBundle:org.example.testResourceBundleLookup:mykey)
Script:                $(script:javascript:3 + 4)
System Property:       $(sys:user.dir)
URL Decoder:           $(urlDecoder:Hello%20World%21)
URL Encoder:           $(urlEncoder:Hello World!)
URL Content (HTTP):    $(url:UTF-8:http://www.apache.org)
URL Content (HTTPS):   $(url:UTF-8:https://www.apache.org)
URL Content (File):    $(url:UTF-8:file:///$(sys:user.dir)/src/test/resources/document.properties)
XML XPath:             $(xml:src/test/resources/document.xml:/root/path/to/node)

to replace the values with java system properties or environment variables. Recursive variable replacement like $(file:UTF-8:$(env:KEYCLOAK_PASSWORD_FILE)) is enabled by default if import.var-substitution.enabled is set to true.

The variable substitution is running before the json parser gets executed. This allows json structures or complex values.

See Apache Common StringSubstitutor documentation⁠ for more information and advanced usage.

Note: Since variable substitution is a part of the keycloak-config-cli, it's done locally. This means, the environment variables need to be available where keycloak-config-cli is executed.

If import.var-substitution.prefix=${ and import.var-substitution.suffix=} (default in keycloak-config-cli 3.x) is set, then keycloak builtin variables like ${role_uma_authorization} needs to be escaped by $${role_uma_authorization}.

⁠Logging

⁠JSON logging support

keycloak-config-cli supports logging in JSON format. To enable, set SPRING_PROFILES_ACTIVE=json-log.

⁠Log level

CLI OptionENV VariableDescriptionDefault
--logging.level.rootLOGGING_LEVEL_ROOTdefine the root log levelinfo
--logging.level.keycloak-config-cliLOGGING_LEVEL_KEYCLOAKCONFIGCLIlog level of keycloak-config-cli componentsvalue of logging.level.root
--logging.level.httpLOGGING_LEVEL_HTTPlog level http requests between keycloak-config-cli and Keycloakvalue of logging.level.root
--logging.level.realm-configLOGGING_LEVEL_REALMCONFIGif set to trace, the realm config including sensitive information will be loggedvalue of logging.level.root

⁠Supported features

See: docs/FEATURES.md⁠

⁠Compatibility with keycloak

Since keycloak-config-cli 4.0 will support the latest 4 releases of keycloak, if possible. There are some exceptions:

  • keycloak-config-cli will try the keep an extended support for RH-SSO⁠
  • keycloak-config-cli will cut the support if keycloak introduces some breaking changes

⁠Build this project

keycloak-config-cli using maven⁠ to build and test keycloak-config-cli. In case maven is not installed on your system, the mvnw⁠ command will download maven for you.

Further development requirements

  • Java Development Kit (JDK)
  • Docker Desktop or an alternative replacement (e.g Rancher Desktop)

Before running mvn verify, you have to set the JAVA_HOME environment variable to prevent some test failures.

./mvnw verify

# Windows only
mvnw.cmd verify

If your are working with a Docker Desktop replacement, some of the Integrationtests can fail due to internal DNS Lookups (host.docker.internal is not reachable). In this case the host can be replaced by a property.

mvn verify -DJUNIT_LDAP_HOST=an.alternate.host.or.ip

⁠Run integration tests against real keycloak

We are using TestContainers⁠ in our integration tests. To run the integration tests a configured docker environment is required.

./mvnw verify

# Windows only
mvnw.cmd verify

⁠Run this project

Start a local keycloak on port 8080:

docker-compose down --remove-orphans && docker-compose up keycloak

before performing following command:

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

⁠Docker

A docker images is available at DockerHub⁠ (docker.io/adorsys/keycloak-config-cli) and quay.io⁠ (quay.io/adorsys/keycloak-config-cli)

Available docker tags

TagDescription
latestlatest available release of keycloak-config-cli which is built against the latest supported Keycloak release.
latest-x.y.zlatest available release of keycloak-config-cli which is built against the Keycloak version x.y.z.
edgelatest commit on the main branch and which is built against the latest supported Keycloak release.
a.b.ckeycloak-config-cli version a.b.c which is built against the latest supported Keycloak release.
a.b.c-x.y.zkeycloak-config-cli version a.b.c which is built against the Keycloak version x.y.z.
mavenSee below

Additionally, the tag maven contains the source code and compile keycloak-config-cli at runtime. This has the advantage to keycloak-config-cli with Keycloak versions, that not official supported., e.g.:

docker run --rm -ti -v $PWD:/config/ -eKEYCLOAK_VERSION=23.0.1 -eMAVEN_CLI_OPTS="-B -ntp -q" adorsys/keycloak-config-cli:edge-build
⁠Docker run

For docker -e you have to replace dots with underscores.

docker run \
    -e KEYCLOAK_URL="http://<your keycloak host>:8080/" \
    -e KEYCLOAK_USER="<keycloak admin username>" \
    -e KEYCLOAK_PASSWORD="<keycloak admin password>" \
    -e KEYCLOAK_AVAILABILITYCHECK_ENABLED=true \
    -e KEYCLOAK_AVAILABILITYCHECK_TIMEOUT=120s \
    -e IMPORT_FILES_LOCATIONS='/config/*' \
    -v <your config path>:/config \
    adorsys/keycloak-config-cli:latest
⁠Docker build

You can build an own docker image by running

docker build -t keycloak-config-cli .

⁠Helm

We provide a helm chart here⁠.

Since it makes no sense to deploy keycloak-config-cli as standalone application, you could add it as dependency to your chart deployment.

Checkout helm docs about chart dependencies⁠!

⁠Configuration

⁠CLI option / Environment Variables

⁠Keycloak options
CLI OptionENV VariableDescriptionDefaultDocs
--keycloak.urlKEYCLOAK_URLKeycloak URL including web context. Format: scheme://hostname:port/web-context.-
--keycloak.userKEYCLOAK_USERlogin user nameadmin
--keycloak.passwordKEYCLOAK_PASSWORDlogin user password-
--keycloak.client-idKEYCLOAK_CLIENTIDlogin clientIdadmin-cli
--keycloak.client-secretKEYCLOAK_CLIENTSECRETlogin client secret-
--keycloak.grant-typeKEYCLOAK_GRANTTYPElogin grant_typepassword
--keycloak.login-realmKEYCLOAK_LOGINREALMlogin realmmaster
--keycloak.ssl-verifyKEYCLOAK_SSLVERIFYVerify ssl connection to keycloaktrue
--keycloak.http-proxyKEYCLOAK_HTTPPROXYConnect to Keycloak via HTTP Proxy. Format: scheme://hostname:port-
--keycloak.connect-timeoutKEYCLOAK_CONNECTTIMEOUTConnection timeout10s
--keycloak.read-timeoutKEYCLOAK_READTIMEOUTRead timeout10sconfigured as Java Duration⁠
--keycloak.availability-check.enabledKEYCLOAK_AVAILABILITYCHECK_ENABLEDWait until Keycloak is availablefalseconfigured as Java Duration⁠
--keycloak.availability-check.timeoutKEYCLOAK_AVAILABILITYCHECK_TIMEOUTWait timeout for keycloak availability check120s
⁠Import options
CLI OptionENV VariableDescriptionDefaultDocs
--import.validateIMPORT_VALIDATEValidate configuration settingsfalse
--import.parallelIMPORT_PARALLELEnable parallel import of certain resourcesfalse
--import.files.locationsIMPORT_FILES_LOCATIONSLocation of config files (URL, file path, or Ant-style pattern)-IMPORT.md⁠
--import.files.include-hidden-filesIMPORT_FILES_INCLUDE_HIDDEN_FILESIncludes files that marked as hiddenfalse
--import.files.excludesIMPORT_FILES_EXCLUDESExclude files with Ant-style pattern-
--import.cache.enabledIMPORT_CACHE_ENABLEDEnable caching of import file locationstrue
--import.cache.keyIMPORT_CACHE_KEYCache key for importing config.default
--import.remote-state.enabledIMPORT_REMOTESTATE_ENABLEDEnable remote state management. Purge only resources managed by keycloak-config-cli.trueMANAGED.md⁠
--import.remote-state.encryption-keyIMPORT_REMOTESTATE_ENCRYPTIONKEYEnables remote state in encrypted format. If unset, state will be stored in plain-
--import.var-substitution.enabledIMPORT_VARSUBSTITUTION_ENABLEDEnable variable substitution config filesfalse
--import.var-substitution.nestedIMPORT_VARSUBSTITUTION_NESTEDExpand variables in variables.true
--import.var-substitution.undefined-is-errorIMPORT_VARSUBSTITUTION_UNDEFINEDISTERRORRaise exceptions, if variables are not defined.true
--import.var-substitution.prefixIMPORT_VARSUBSTITUTION_PREFIXConfigure the variable prefix, if import.var-substitution.enabled is true.$(
--import.var-substitution.suffixIMPORT_VARSUBSTITUTION_SUFFIXConfigure the variable suffix, if import.var-substitution.enabled is true.)
--import.behaviors.sync-user-federationIMPORT_BEHAVIORS_SYNC_USER_FEDERATIONEnable the synchronization of user federation.false

Tag summary

Content type

Image

Digest

sha256:7b3b1d8d8…

Size

220.1 MB

Last updated

23 days ago

docker pull adorsys/keycloak-config-cli:edge-build