From 2b9b8bafa61797475bf688083a08a55c37ef3a5f Mon Sep 17 00:00:00 2001 From: Philipp Date: Tue, 28 Jan 2025 20:35:50 +0100 Subject: [PATCH 1/6] add keycloak deployment files --- .gitignore | 2 ++ Containerfile.keycloak | 12 ++++++++++++ README.md | 13 ++++++++++++- compose.yml | 38 ++++++++++++++++++++++++++++++++++++++ sample.env | 7 +++++++ 5 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 .gitignore create mode 100644 Containerfile.keycloak create mode 100644 compose.yml create mode 100644 sample.env diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6ee0103 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/data +/.env diff --git a/Containerfile.keycloak b/Containerfile.keycloak new file mode 100644 index 0000000..046d833 --- /dev/null +++ b/Containerfile.keycloak @@ -0,0 +1,12 @@ +ARG KEYCLOAK_VERSION +FROM quay.io/keycloak/keycloak:${KEYCLOAK_VERSION} as builder + +RUN /opt/keycloak/bin/kc.sh build --features-disabled=impersonation --db=postgres + +FROM quay.io/keycloak/keycloak:${KEYCLOAK_VERSION} +WORKDIR /opt/keycloak +COPY --from=builder /opt/keycloak/ /opt/keycloak/ +ENV KC_DB_URL=keycloak_db + +ENTRYPOINT ["/opt/keycloak/bin/kc.sh"] +CMD ["start", "--optimized"] diff --git a/README.md b/README.md index 322096a..f7db0ed 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,13 @@ -# keycloak-deployment +# Keycloak Deployment +This repos contains all files required to deploy the keycloak service using docker-compose. + +The deployment is tailored towards a setup using postgres as the database and running keycloak behind a reverse proxy using HTTP. If you want to use it with any other configuration, you will have to adapt the compose file. + +## Setup + +Copy the `sample.env` file into a `.env` file and choose secure passwords. Then run `docker compose up -d` + +## Updating + +Change the Postgres and Keycloak version in your `.env` file and run `docker compose build` (only required for updating Keycloak). Then run `docker compose up -d` again. diff --git a/compose.yml b/compose.yml new file mode 100644 index 0000000..5348884 --- /dev/null +++ b/compose.yml @@ -0,0 +1,38 @@ +version: '3.9' + +services: + keycloak_db: + image: postgres:${POSTGRES_VERSION} + restart: always + environment: + - POSTGRES_DB=keycloak + - POSTGRES_USER=${KC_DB_USERNAME} + - POSTGRES_PASSWORD=${KC_DB_PASSWORD} + volumes: + - ./data/postgres:/var/lib/postgresql/data + + keycloak: + build: + dockerfile: Containerfile.keycloak + args: + KEYCLOAK_VERSION: ${KEYCLOAK_VERSION} + depends_on: + - keycloak_db + environment: + - KC_HEALTH_ENABLED=true + - KC_DB=postgres + - KC_DB_URL=jdbc:postgresql://keycloak_db:5432/keycloak + - KC_DB_URL_DATABASE=keycloak + - KC_PROXY_ADDRESS_FORWARDING=true + - KC_HOSTNAME_STRICT_HTTPS=false + - KC_PROXY=edge + - KC_HTTP_ENABLED=true + - KC_HOSTNAME_STRICT=false + - KC_HOSTNAME=${KC_HOSTNAME} + - KC_DB_USERNAME=${KC_DB_USERNAME} + - KC_DB_PASSWORD=${KC_DB_PASSWORD} + - KEYCLOAK_ADMIN=${KEYCLOAK_ADMIN} + - KEYCLOAK_ADMIN_PASSWORD=${KEYCLOAK_ADMIN_PASSWORD} + restart: always + ports: + - 8080:8080 diff --git a/sample.env b/sample.env new file mode 100644 index 0000000..b14f022 --- /dev/null +++ b/sample.env @@ -0,0 +1,7 @@ +KEYCLOAK_VERSION=22.0 +KEYCLOAK_ADMIN=idpadmin +KEYCLOAK_ADMIN_PASSWORD= +KC_DB_USERNAME=ctbkidpdb +KC_DB_PASSWORD= +KC_HOSTNAME=idp.ctbk.de +POSTGRES_VERSION=16.0 From e9feef29c72923b850b11d1daa947eeb1070ae91 Mon Sep 17 00:00:00 2001 From: Philipp Date: Tue, 28 Jan 2025 20:35:50 +0100 Subject: [PATCH 2/6] add realm config examples --- README.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/README.md b/README.md index f7db0ed..d580f5b 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,7 @@ This repos contains all files required to deploy the keycloak service using docker-compose. The deployment is tailored towards a setup using postgres as the database and running keycloak behind a reverse proxy using HTTP. If you want to use it with any other configuration, you will have to adapt the compose file. +Furthermore, the setup utilizes a custom Keycloak image that is built without impersonation features. ## Setup @@ -11,3 +12,15 @@ Copy the `sample.env` file into a `.env` file and choose secure passwords. Then ## Updating Change the Postgres and Keycloak version in your `.env` file and run `docker compose build` (only required for updating Keycloak). Then run `docker compose up -d` again. + +## Configuration + +The Keycloak configuration is not quite straight forward, which is why the following section contains some configuration examples. It is recommended to create a custom realm first instead of simply using the master realm. + +### Enforcing 2FA + +In the realm management console under `Authentication > Required Actions` certain actions can be enabled and set to be the default action. Useful defaults might be to enforce `Configure OTP`, `Update Password`, `Update Profile` and `Verify Email`. + +### Creating a realm admin + +Managing the custom realm can happen by using the global Keycloak admin, but it might make more sense to create per-realm admins. To do so, a new `Realm Role` can be added (e.g. named `realm-admin`). After creating this role, the action `Add associated roles` can be chosen. Choose to filter by clients and search for `realm-management`. Then choose all of the given roles and assign them to the `realm-admin` role. This role can be added to a given user under the `Role Mapping` tab in the users profile. Afterwards, the given realm can be managed using its web console on `https:///admin//console`. From de4253e0da43a59ec95eec502f3e2621e08b1a64 Mon Sep 17 00:00:00 2001 From: Philipp Date: Tue, 28 Jan 2025 20:35:50 +0100 Subject: [PATCH 3/6] add postgres backup script --- .gitignore | 1 + backup.sh | 6 ++++++ 2 files changed, 7 insertions(+) create mode 100755 backup.sh diff --git a/.gitignore b/.gitignore index 6ee0103..7913d1c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ /data /.env +/backup diff --git a/backup.sh b/backup.sh new file mode 100755 index 0000000..a1862e4 --- /dev/null +++ b/backup.sh @@ -0,0 +1,6 @@ +#!/bin/sh +time=$(date +"%Y-%m-%dT%H:%M:%S%z") +dir=backup +[ -d "${dir}" ] || mkdir -p "${dir}" +docker compose run --rm -u postgres keycloak_db sh -c 'PGPASSWORD=$POSTGRES_PASSWORD pg_dump -h keycloak_db -p 5432 -U $POSTGRES_USER keycloak' > "${dir}/${time}.sql" +# to restore: pg_restore -d newdb db.dump From a3b6fa4977d915aaaf8032747cc369d5b89c8b2a Mon Sep 17 00:00:00 2001 From: Philipp Date: Tue, 28 Jan 2025 20:35:50 +0100 Subject: [PATCH 4/6] enable declarative user profiles https://www.keycloak.org/docs/latest/server_admin/#user-profile --- Containerfile.keycloak | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Containerfile.keycloak b/Containerfile.keycloak index 046d833..0d4431f 100644 --- a/Containerfile.keycloak +++ b/Containerfile.keycloak @@ -1,7 +1,7 @@ ARG KEYCLOAK_VERSION FROM quay.io/keycloak/keycloak:${KEYCLOAK_VERSION} as builder -RUN /opt/keycloak/bin/kc.sh build --features-disabled=impersonation --db=postgres +RUN /opt/keycloak/bin/kc.sh build --features-disabled=impersonation --db=postgres --features=declarative-user-profile FROM quay.io/keycloak/keycloak:${KEYCLOAK_VERSION} WORKDIR /opt/keycloak From 27a794c10ff4bb1726d2193c2d4dc4caa51a0843 Mon Sep 17 00:00:00 2001 From: Philipp Date: Tue, 28 Jan 2025 20:35:50 +0100 Subject: [PATCH 5/6] docs: How to sync groups --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index d580f5b..120331d 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,12 @@ Change the Postgres and Keycloak version in your `.env` file and run `docker com The Keycloak configuration is not quite straight forward, which is why the following section contains some configuration examples. It is recommended to create a custom realm first instead of simply using the master realm. +## Map groups to OIDC claims + +To handle authorization centrally, groups can be created and assigned directly in Keycloak. Those groups are not sent to the OIDC client by default. To enable such functionality, create a new client scope named `groups`. For this scope, add a new mapper ('By Configuration') and select 'Group Membership'. Give it a descriptive name and set the token claim name to `groups`. + +For each client that relies on those group, explicitly add the `groups` scope to client scopes. The groups will now be sent to client upon request. + ### Enforcing 2FA In the realm management console under `Authentication > Required Actions` certain actions can be enabled and set to be the default action. Useful defaults might be to enforce `Configure OTP`, `Update Password`, `Update Profile` and `Verify Email`. From 25c41ecc926cc05f9f57c4c8f7ceae7c27e03e82 Mon Sep 17 00:00:00 2001 From: Philipp Date: Tue, 28 Jan 2025 20:35:50 +0100 Subject: [PATCH 6/6] docs: Add note for group name handling --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 120331d..7c9b995 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,8 @@ To handle authorization centrally, groups can be created and assigned directly i For each client that relies on those group, explicitly add the `groups` scope to client scopes. The groups will now be sent to client upon request. +**Note:** A group named `foo` will be displayed as `/foo`. For this reason, I recommend using group names like `appname/rolename` which will be sent to the client as `/appname/rolename`. + ### Enforcing 2FA In the realm management console under `Authentication > Required Actions` certain actions can be enabled and set to be the default action. Useful defaults might be to enforce `Configure OTP`, `Update Password`, `Update Profile` and `Verify Email`.