keycloak-rest-adapter
is a REST API made in Flask that abstracts Keycloak's Admin REST API. It is documented using Swagger: run the application and check the /swagger-ui
endpoint in your web browser for API documentation.
For security reasons, it is recommended that clients typically be registered in a custom Keycloak Realm, i.e. not in Master. The REST Adapter is an exception and must be registered in the Master Realm to be able to create and manage Keycloak clients.
Register keycloak-rest-adapter
in the your Keycloak instance, in the "master" realm with
client credentials enabled. Enable admin permissions for the REST Adapter in the "Service Account Roles" tab.
Modify default_adapter_config.py
to contain your configuration, notably:
# Keycloak
KEYCLOAK_SERVER = "<Your Keycloak server>"
KEYCLOAK_REALM = "master"
KEYCLOAK_CLIENT_ID = "keycloak-rest-adapter"
KEYCLOAK_CLIENT_SECRET ="<Client Secret>"
Now configure OIDC for the REST Adapter. Register keycloak-rest-adapter
again in Keycloak, this time in realm you use to register clients. Enable Implicit flow since this is used by the Swagger interface.
Modify default_adapter_config.py
to contain your configuration, notably:
# Keycloak server
KEYCLOAK_SERVER = "https://keycloak-dev.cern.ch"
# The realm on which the rest adapter operates
KEYCLOAK_REALM = "cern"
# Client that needs to have admin rights in the 'cern' realm and exist in the 'master' realm
KEYCLOAK_CLIENT_ID = "keycloak-rest-adapter"
# Note that this must be the client secret of the "keycloak-rest-adapter" client in
# the "master" realm
KEYCLOAK_SECRET = "xxxx"
If you need to override the default configs, you can set the KEYCLOAK_REST_ADAPTER_CONFIG
environment variable with the path
to the configuration overrides:
export KEYCLOAK_REST_ADAPTER_CONFIG=/opt/config/keycloak-overrides.py
Run the activate.sh
script using this command. It will create a virtualenv
and install all the project dependencies.
source activate.sh
Note: this project uses
pip-compile
to generate the requirements.txt file. It should not be edited manually!
In order to run the server locally, the simplest way is to use the flask debug server.
Copy the file default_adapter_config.py
to test_adapter_config.py
(test_adapter_config*.py
files are gitignored)
and override the settings you need to override, most likely KEYCLOAK_CLIENT_SECRET
:
# Note that this must be the client secret of the "keycloak-rest-adapter" client in
# the "master" realm
KEYCLOAK_CLIENT_SECRET = "blah-blah-guid"
The .flaskenv
file will set KEYCLOAK_REST_ADAPTER_CONFIG=test_adapter_config.py
so that your
configuration overrides are loaded, then you can run
flask run
and access the swagger api on your local machine.
If you want to run all the integration tests, you'll need to have Docker started on your machine.
To install all the test dependencies:
pip install -r test-requirements.txt
Then, in the main folder, run:
pytest
In order to teardown the Keycloak instance running locally on port 8081, set TEARDOWN = True
in test_keycloak_api_client.py
.
After the integration tests run you can checkout your things with user/pass: admin:admin
on http://localhost:8081
.
We manage the dependencies using pip. It is very advisable to install the dependencies in an isolated environment using virtualenv or a similar tool.
yum install python3-pip
Once we have pip installed, we will use it to fulfill the list of dependencies.
PIP_CONFIG_FILE=pip.conf pip install -r requirements.txt
On Windows (PowerShell):
$env:PIP_CONFIG_FILE="$pwd\pip.conf"
pip install -r requirements.txt
We use pip-compile
to keep track of all project dependencies. The requirements.in
file lists all dependencies for this
project. To update these (except for the packages that are version locked) run:
$ pip-compile -U
Note:
pip-tools
must be installed to run the above command.
To build the docker container:
docker build . -t kc-rest
To run it exposing the port:
docker run -d --name keycloak-rest-adapter -p 8080:8080 kc-rest
Find the path where the system installed the python script. We will need it to configure the systemd unit later on.
find /usr/lib/ -name keycloak_rest_adapter.py
/usr/lib/python2.7/site-packages/keycloak_rest_adapter-0.1-py2.7.egg/keycloak-rest-adapter/keycloak_rest_adapter.py
Create the file keycloak-rest-adapter.service on /etc/systemd/system/. We need to edit the value of the variable of ExecStart, and make sure it points to the python script returned before.
Example:
$ cat /etc/systemd/system/keycloak-rest-adapter.service
[Unit]
Description=Python Keycloak Rest Adapter
After=syslog.target network.target
[Service]
Type=simple
WorkingDirectory=/usr/lib/python2.7/site-packages/
ExecStart=/usr/bin/python /usr/lib/python2.7/site-packages/keycloak_rest_adapter-0.1-py2.7.egg/keycloak-rest-adapter/keycloak_rest_adapter.py
StandardOutput=syslog
StandardError=syslog
[Install]
WantedBy=multi-user.target
After creating the new systemd unit, we just need to reload the systemd daemon, so it picks up these new changes.
systemctl daemon-reload
systemctl start keycloak-rest-adapter.service
journalctl -u keycloak -f