1. Introduction
Keycloak is an open-source identity and access management solution aimed at modern applications and services. By default, Keycloak uses files or an embedded H2 database ot store configuration data. The storage is located inside a container and is not persistent when container is removed or recreated. To ensure data persistence, it is recommended to configure Keycloak to use an external database.
2. Database
Create a user keycloak and database keycloak owning by that user.
2.1. Local database
If there is a need to reuse local database already running on local machine directly (without docker image), an configuration update is required.
I file postgresql.conf update the listen_addresses.
Use either * (be sure that firewall is configured correctly) or the specific interface.:
listen_addresses = '*'
Adjust the pg_hba.conf file to allow connections from docker container.
# Docker Internal Network Access
# Adjust the IP range if your Docker setup uses a non-standard one (if needed)
host all all 172.17.0.0/16 scram-sha-256
Restart PostgreSQL service to apply changes.
You can test setup by running test PostgreSQL container
docker run -ti --rm postgres:18 psql -h host.docker.internal -p 5432 -U keycloak -d keycloak
The command should ask for password. Enter password na verify that connection is established.
In case of wrong configuration various error messages may be displayed.
3. Keycloak configuration
Then the keycloak (in development mode) can by run by following command:
docker run -p 18080:8080 \
--name keycloak \
-e KEYCLOAK_ADMIN=admin \
-e KEYCLOAK_ADMIN_PASSWORD=admin \
-e KC_DB=postgres \
-e KC_DB_URL=jdbc:postgresql://host.docker.internal:5432/keycloak \
-e KC_DB_USERNAME=keycloak \
-e KC_DB_PASSWORD=your_secure_password \
quay.io/keycloak/keycloak:26.4.7 \
start-dev
Now should be the keycloak accessible on port 18080 on localhost.
4. Keycloak setup
4.1. Realm
Create new realm pdm for PDM project .
More instruction can be found on youtube - Create and configure realm
4.1.1. Admin user
Create admin user for the realm to be able manage users.
Go to and create new user with following configuration:
* Username: realm-admin (it must be name which does not conflict with existing users of PDM.control)
* Set the rest according to your needs.
Set password for the user. Go to and set new password. Set temporary to off and click Save.
Add admin role to the user.
Go to .
Assign role realm-admin, user-admin to this user.
4.2. Clients
4.2.1. UI client
Create a new client pdm-control for PDM.control UI application.
-
Client ID:
pdm-control -
Name: PDM.control client
-
Description: Public client for PDM.control UI application.
-
Click Next
-
Client authentication: Off
-
Authorization: Off
-
Authentication flow:
-
Standard Flow: On
-
-
Click Next
-
Root URL: <application URL> (e.g.,
https://stage.pdm-dev.de/) -
Home URL: <application URL> (e.g.,
https://stage.pdm-dev.de/) -
Valid redirect URIs: see internal help (e.g.
https://stage.pdm-dev.de/*) -
Valid post logout redirect URIs: see internal help (e.g.
https://stage.pdm-dev.de/*) -
Web origins: (see internal help) (e.g.
https://stage.pdm-dev.de)-
Standard Flow: On
-
-
Click Next
More info - youtube - Create client. Read Explanation of client options. Additionally add just created scope. menu: Clients[pdm-control > Client Scopes > Add Client scope > Default Client Scopes > {pdm-user} > Add > Default].
Test: call POST https://auth.pdm-dev.de/realms/pdm/protocol/openid-connect/token.
Create test user e.g. realm-admin with password admin to test token retrieval.
|
curl --location 'https://auth.pdm-dev.de/realms/pdm/protocol/openid-connect/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=password' \
--data-urlencode 'client_id=pdm-control' \
--data-urlencode 'username=realm-admin' \
--data-urlencode 'password=admin'
| You need temporarily allow direct access grants to test the token retrieval. |
The token should contains also time_zone and areas attributes.
Remove unnecessary claims
Remove unnecessary claims from JWT to make it shorter. Unnecessary claim are user personal data. It is possible to load them from http://kyecloak/realms/{realm}/protocol/openid-connect/userinfo See request_user_info.py to see how it works.
Open client
4.2.2. Backend client
Create a client with higher privileges to allow backend services query / manage other users from this realm.
Open and create new client. Read Explanation of client options. Then use following configuration:
General Settings
-
Client ID:
pdm-control-private -
Name: Internal backend client
-
Description: Client for backend services for querying and managing users
-
Always display in UI: Off
Click button Next.
Select following settings:
-
Client authentication: ON
-
: checked
-
: checked. This is required to be able emulate basic authentication for external API. It allows to exchange username and password for access token without need to log in to Keycloak UI. It can be removed after migration to Oauth2 method is completed. However this client is not publicly accessible, therefore such permission should not cause security issues.
Leave or set OFF or unchecked the rest of the options.
Click button Next.
Leave everything empty.
Click button Save.
Add following roles to the service account tab of the client to be able manage users:
-
realm-management:view-users -
realm-management:query-users
To get the 'access token' open and copy the Secret value.
Alternatively it is possible to set lifespan of backend token shorter then standard one. See https://youtu.be/ZQ1KApBJbR8
4.2.3. Explanation of client options
| AI generated. Please review and adjust the content if needed. |
Capability config
Client authentication: ON
Meaning: This makes the client "Confidential." It generates a Client Secret (a password for your internal backend Java app).
Without this (turning off), the client is "public" (like a mobile app) and cannot safely hold the permissions needed to query the User API. Client always requires a user to log in.
Authorization: Off
Meaning: This refers to Keycloak’s "Fine-Grained Authorization Services" (complex policies/permissions). You don’t need this for a simple user lookup.
Service accounts roles: ON
Meaning: It allows the client to act as its own "user." It creates a background service account that stays active without a human logging in. You can assign the specific permissions to this specific service account.
| Flow | Meaning | Should you use it? |
|---|---|---|
Standard Flow |
Used for browser-based logins (redirects to Keycloak login page). |
Only if your Java app has a UI where users log in. |
Direct Access Grants |
Allows exchanging a username + password directly for a token. |
No. This is less secure and bypasses MFA. |
Implicit Flow |
"An old, insecure flow for legacy JavaScript apps." |
No. (Deprecated in modern security). |
Standard Token Exchange |
"Allows one client to ""swap"" its token for a token for another client." |
No. Too complex for your current needs. |
OAuth 2.0 Device Auth |
Used for devices with no browser (like Smart TVs). |
No. |
OIDC CIBA Grant |
"Used for ""out-of-band"" auth (e.g., approving a login on a phone app)." |
No. |
Service accounts roles |
This refers to Keycloak’s "Fine-Grained Authorization Services" (complex policies/permissions). You don’t need this for a simple user lookup. |
Yes |
6. Setup for development and system test
|
Do not use it in production. The setup described below was not reviewed by any security expert and may contains some security flows. Always contact our security experts for optimal settings. |
|
Because some customers did not entered the e-mail address the keycloak import of such a record fails.
To mitigate the problem we provide the email address of administrator However keycloak does not support duplicated email addresses. To allow this got to To save the file, select . Select and set
|
Important tips:
-
Remember to set .
Without this it will not be possible to return from profile setting back to application.
7. Import existing users
First create an realm administrator user. Select a user name which does not conflict with existing users of PDM.control which will be imported.
Be sure that it has role realm-admin assigned.
Otherwise he will not be able to see dashboard and manage settings.
-
In Keycloak, fine-grained admin permissions aren’t usually global "realm roles"; they are often linked to the realm-management client. Ensure you have done the following:
-
Go to the user kc-admin.
-
Go to the Role Mapping tab.
-
Click Assign Role and filter by Client roles.
-
Search for the Client ID named realm-management.
-
Assign roles like realm-admin (full power) or the specific ones you mentioned (manage-users, etc.).
Then login using one of the following URLs:
Goal |
URL Path |
Super Admin (Global) |
{keycloak-url}/admin/master/console/ |
Realm Admin (Your User) |
{keycloak-url}/admin/{your-realm}/console/ |
Account Console (User Profile) |
{keycloak-url}/realms/{your-realm}/account/ |
Use kc-migrator tool to import existing users from PDM.control database to Keycloak. Read the documentation of the tool for more details.