From 6d04dfb304affec6bbd567bfc4d8b4499e4bf80e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Andr=C3=A9=20Fischer?= <a.fischer@opentalk.eu>
Date: Tue, 25 Jul 2023 11:16:51 +0200
Subject: [PATCH] remove lite

---
 config/controller.toml.sample                 |   36 +
 data/kc_data/h2/.gitkeep                      |    0
 .../import/12-30-22_example-export.json       | 2867 +++++++++++++++++
 data/minio/s3_bucket/.gitkeep                 |    0
 docker-compose.yaml                           |  248 ++
 env.sample                                    |  135 +
 extras/gen-common-params.sh                   |   23 +
 extras/nginx-samples/controller.conf.sample   |   50 +
 extras/nginx-samples/frontend.conf.sample     |   50 +
 extras/nginx-samples/keycloak.conf.sample     |   53 +
 .../snippets/letsencrypt.conf.sample          |    6 +
 .../snippets/sslsettings.conf.sample          |   15 +
 12 files changed, 3483 insertions(+)
 create mode 100644 config/controller.toml.sample
 create mode 100644 data/kc_data/h2/.gitkeep
 create mode 100644 data/kc_data/import/12-30-22_example-export.json
 create mode 100644 data/minio/s3_bucket/.gitkeep
 create mode 100644 docker-compose.yaml
 create mode 100644 env.sample
 create mode 100755 extras/gen-common-params.sh
 create mode 100644 extras/nginx-samples/controller.conf.sample
 create mode 100644 extras/nginx-samples/frontend.conf.sample
 create mode 100644 extras/nginx-samples/keycloak.conf.sample
 create mode 100644 extras/nginx-samples/snippets/letsencrypt.conf.sample
 create mode 100644 extras/nginx-samples/snippets/sslsettings.conf.sample

diff --git a/config/controller.toml.sample b/config/controller.toml.sample
new file mode 100644
index 0000000..2b103c5
--- /dev/null
+++ b/config/controller.toml.sample
@@ -0,0 +1,36 @@
+[database]
+url = "postgres://ot:<MyPostgresPW>@postgres:5432/k3k"
+
+[http]
+port = 11311
+cors.allowed_origin = ["https://<MyOtDomain>"]
+
+[keycloak]
+base_url = "https://accounts.<MyOtDomain>/auth"
+realm = "opentalk"
+client_id = "OtBackend"
+client_secret = "<MyKcClientSecret>"
+
+[room_server]
+max_video_bitrate = "1600000"
+max_screen_bitrate = "8000000"
+
+[[room_server.connections]]
+to_routing_key = "to-janus"
+exchange = "janus-exchange"
+from_routing_key = "from-janus"
+
+[rabbit_mq]
+url = "amqp://rabbit/%2F"
+mail_task_queue = "opentalk_mailer"
+recording_task_queue = "opentalk_recorder"
+
+[redis]
+url = "redis://redis:6379/"
+
+[minio]
+uri = "http://minio:9000"
+bucket = "s3_bucket"
+access_key = "minioadmin"
+secret_key = "minioadmin"
+
diff --git a/data/kc_data/h2/.gitkeep b/data/kc_data/h2/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/data/kc_data/import/12-30-22_example-export.json b/data/kc_data/import/12-30-22_example-export.json
new file mode 100644
index 0000000..5df3cb0
--- /dev/null
+++ b/data/kc_data/import/12-30-22_example-export.json
@@ -0,0 +1,2867 @@
+{
+  "id": "${KC_REALM_ID}",
+  "realm": "${KC_REALM_NAME}",
+  "displayName": "${KC_REALM_DISPLAYNAME}",
+  "displayNameHtml": "<div class=\"kc-logo-text\"><span>${KC_REALM_DISPLAYNAME}</span></div>",
+  "notBefore": 0,
+  "defaultSignatureAlgorithm": "",
+  "revokeRefreshToken": false,
+  "refreshTokenMaxReuse": 0,
+  "accessTokenLifespan": 300,
+  "accessTokenLifespanForImplicitFlow": 900,
+  "ssoSessionIdleTimeout": 1800,
+  "ssoSessionMaxLifespan": 36000,
+  "ssoSessionIdleTimeoutRememberMe": 0,
+  "ssoSessionMaxLifespanRememberMe": 0,
+  "offlineSessionIdleTimeout": 2592000,
+  "offlineSessionMaxLifespanEnabled": false,
+  "offlineSessionMaxLifespan": 5184000,
+  "clientSessionIdleTimeout": 0,
+  "clientSessionMaxLifespan": 0,
+  "clientOfflineSessionIdleTimeout": 0,
+  "clientOfflineSessionMaxLifespan": 0,
+  "accessCodeLifespan": 60,
+  "accessCodeLifespanUserAction": 300,
+  "accessCodeLifespanLogin": 1800,
+  "actionTokenGeneratedByAdminLifespan": 43200,
+  "actionTokenGeneratedByUserLifespan": 300,
+  "oauth2DeviceCodeLifespan": 600,
+  "oauth2DevicePollingInterval": 5,
+  "enabled": true,
+  "sslRequired": "external",
+  "registrationAllowed": false,
+  "registrationEmailAsUsername": false,
+  "rememberMe": true,
+  "verifyEmail": false,
+  "loginWithEmailAllowed": true,
+  "duplicateEmailsAllowed": false,
+  "resetPasswordAllowed": true,
+  "editUsernameAllowed": false,
+  "bruteForceProtected": true,
+  "permanentLockout": false,
+  "maxFailureWaitSeconds": 900,
+  "minimumQuickLoginWaitSeconds": 60,
+  "waitIncrementSeconds": 60,
+  "quickLoginCheckMilliSeconds": 1000,
+  "maxDeltaTimeSeconds": 43200,
+  "failureFactor": 30,
+  "roles": {
+    "realm": [
+      {
+        "id": "51f06436-092a-40e9-83bd-066707326c10",
+        "name": "uma_authorization",
+        "description": "${role_uma_authorization}",
+        "composite": false,
+        "clientRole": false,
+        "containerId": "${KC_REALM_NAME}",
+        "attributes": {}
+      },
+      {
+        "id" : "f099a60e-24f9-4281-99f6-e48feaf20447",
+        "name" : "opentalk-recorder",
+        "description" : "${role_opentalk-recorder}",
+        "composite" : false,
+        "clientRole" : false,
+        "containerId" : "${KC_REALM_NAME}",
+        "attributes" : { }
+      },
+      {
+        "id" : "69150a12-e39b-4ec5-a44f-afa2f699a055",
+        "name" : "opentalk-call-in",
+        "description" : "${role_opentalk-call-in}",
+        "composite" : false,
+        "clientRole" : false,
+        "containerId" :  "${KC_REALM_NAME}",
+        "attributes" : { }
+      },
+      {
+        "id": "2926bfcb-adaf-4609-886b-c6c00f4147a1",
+        "name": "offline_access",
+        "description": "${role_offline-access}",
+        "composite": false,
+        "clientRole": false,
+        "containerId": "${KC_REALM_NAME}",
+        "attributes": {}
+      },
+      {
+        "id": "b6a673fe-e708-4bac-9dd8-223fe65df76d",
+        "name": "default-roles-${KC_REALM_NAME}",
+        "description": "${role_default-roles}",
+        "composite": true,
+        "composites": {
+          "realm": [
+            "offline_access",
+            "uma_authorization"
+          ],
+          "client": {
+            "account": [
+              "view-profile",
+              "manage-account"
+            ]
+          }
+        },
+        "clientRole": false,
+        "containerId": "${KC_REALM_NAME}",
+        "attributes": {}
+      }
+    ],
+    "client": {
+      "OtBackend": [],
+      "realm-management": [
+        {
+          "id": "97ed4a84-c089-462c-abee-1909e163c1b4",
+          "name": "realm-admin",
+          "description": "${role_realm-admin}",
+          "composite": true,
+          "composites": {
+            "client": {
+              "realm-management": [
+                "manage-users",
+                "manage-realm",
+                "view-users",
+                "view-realm",
+                "manage-clients",
+                "query-groups",
+                "manage-events",
+                "query-users",
+                "create-client",
+                "query-clients",
+                "view-identity-providers",
+                "manage-identity-providers",
+                "view-clients",
+                "query-realms",
+                "manage-authorization",
+                "impersonation",
+                "view-events",
+                "view-authorization"
+              ]
+            }
+          },
+          "clientRole": true,
+          "containerId": "cad91a15-3c4d-4893-9897-ebc6dde8aef9",
+          "attributes": {}
+        },
+        {
+          "id": "443fca1a-34a7-4b71-8643-1ff7ff14e8c9",
+          "name": "manage-users",
+          "description": "${role_manage-users}",
+          "composite": false,
+          "clientRole": true,
+          "containerId": "cad91a15-3c4d-4893-9897-ebc6dde8aef9",
+          "attributes": {}
+        },
+        {
+          "id": "dec80935-9e78-4f1a-9171-01e5199d0b60",
+          "name": "manage-realm",
+          "description": "${role_manage-realm}",
+          "composite": false,
+          "clientRole": true,
+          "containerId": "cad91a15-3c4d-4893-9897-ebc6dde8aef9",
+          "attributes": {}
+        },
+        {
+          "id": "e3dcb867-8f93-4b34-8dce-1142ca233892",
+          "name": "view-users",
+          "description": "${role_view-users}",
+          "composite": true,
+          "composites": {
+            "client": {
+              "realm-management": [
+                "query-users",
+                "query-groups"
+              ]
+            }
+          },
+          "clientRole": true,
+          "containerId": "cad91a15-3c4d-4893-9897-ebc6dde8aef9",
+          "attributes": {}
+        },
+        {
+          "id": "783382df-cd68-44d3-b757-ac51a1ba5b6e",
+          "name": "manage-clients",
+          "description": "${role_manage-clients}",
+          "composite": false,
+          "clientRole": true,
+          "containerId": "cad91a15-3c4d-4893-9897-ebc6dde8aef9",
+          "attributes": {}
+        },
+        {
+          "id": "87ccda42-bb0c-4e24-80df-a5a788c9502a",
+          "name": "query-groups",
+          "description": "${role_query-groups}",
+          "composite": false,
+          "clientRole": true,
+          "containerId": "cad91a15-3c4d-4893-9897-ebc6dde8aef9",
+          "attributes": {}
+        },
+        {
+          "id": "3ed78fde-af20-4f92-bfe3-ee69fcc68fe7",
+          "name": "view-realm",
+          "description": "${role_view-realm}",
+          "composite": false,
+          "clientRole": true,
+          "containerId": "cad91a15-3c4d-4893-9897-ebc6dde8aef9",
+          "attributes": {}
+        },
+        {
+          "id": "bebf7998-7256-4b8a-b3b8-3d3bac5e8f33",
+          "name": "manage-events",
+          "description": "${role_manage-events}",
+          "composite": false,
+          "clientRole": true,
+          "containerId": "cad91a15-3c4d-4893-9897-ebc6dde8aef9",
+          "attributes": {}
+        },
+        {
+          "id": "b284dd8c-c1d7-4549-a111-4dd0be254161",
+          "name": "query-users",
+          "description": "${role_query-users}",
+          "composite": false,
+          "clientRole": true,
+          "containerId": "cad91a15-3c4d-4893-9897-ebc6dde8aef9",
+          "attributes": {}
+        },
+        {
+          "id": "49b312de-1801-4193-948c-8a96a54842fa",
+          "name": "create-client",
+          "description": "${role_create-client}",
+          "composite": false,
+          "clientRole": true,
+          "containerId": "cad91a15-3c4d-4893-9897-ebc6dde8aef9",
+          "attributes": {}
+        },
+        {
+          "id": "a0dae6c4-8a97-4155-b69c-d1c707cff6b6",
+          "name": "query-clients",
+          "description": "${role_query-clients}",
+          "composite": false,
+          "clientRole": true,
+          "containerId": "cad91a15-3c4d-4893-9897-ebc6dde8aef9",
+          "attributes": {}
+        },
+        {
+          "id": "cc00516b-ae68-49c4-8936-6233cbb569c9",
+          "name": "view-identity-providers",
+          "description": "${role_view-identity-providers}",
+          "composite": false,
+          "clientRole": true,
+          "containerId": "cad91a15-3c4d-4893-9897-ebc6dde8aef9",
+          "attributes": {}
+        },
+        {
+          "id": "83950cf2-381c-4e7c-bf77-2e3d5e61585b",
+          "name": "manage-identity-providers",
+          "description": "${role_manage-identity-providers}",
+          "composite": false,
+          "clientRole": true,
+          "containerId": "cad91a15-3c4d-4893-9897-ebc6dde8aef9",
+          "attributes": {}
+        },
+        {
+          "id": "593d09a0-54f7-437b-8812-575c101cdeba",
+          "name": "view-clients",
+          "description": "${role_view-clients}",
+          "composite": true,
+          "composites": {
+            "client": {
+              "realm-management": [
+                "query-clients"
+              ]
+            }
+          },
+          "clientRole": true,
+          "containerId": "cad91a15-3c4d-4893-9897-ebc6dde8aef9",
+          "attributes": {}
+        },
+        {
+          "id": "8876ffcd-5469-4d2e-87c5-9f7298d8ff91",
+          "name": "manage-authorization",
+          "description": "${role_manage-authorization}",
+          "composite": false,
+          "clientRole": true,
+          "containerId": "cad91a15-3c4d-4893-9897-ebc6dde8aef9",
+          "attributes": {}
+        },
+        {
+          "id": "63e75a80-b5b5-4515-8ae0-73837d0c1651",
+          "name": "query-realms",
+          "description": "${role_query-realms}",
+          "composite": false,
+          "clientRole": true,
+          "containerId": "cad91a15-3c4d-4893-9897-ebc6dde8aef9",
+          "attributes": {}
+        },
+        {
+          "id": "2e37ac1a-3ae8-47bd-8444-e91bd29c70f8",
+          "name": "impersonation",
+          "description": "${role_impersonation}",
+          "composite": false,
+          "clientRole": true,
+          "containerId": "cad91a15-3c4d-4893-9897-ebc6dde8aef9",
+          "attributes": {}
+        },
+        {
+          "id": "bc601b8a-997a-47e5-afd1-2b30edd2ab58",
+          "name": "view-events",
+          "description": "${role_view-events}",
+          "composite": false,
+          "clientRole": true,
+          "containerId": "cad91a15-3c4d-4893-9897-ebc6dde8aef9",
+          "attributes": {}
+        },
+        {
+          "id": "2df0f735-8185-4ac8-baba-f4f7e504a312",
+          "name": "view-authorization",
+          "description": "${role_view-authorization}",
+          "composite": false,
+          "clientRole": true,
+          "containerId": "cad91a15-3c4d-4893-9897-ebc6dde8aef9",
+          "attributes": {}
+        }
+      ],
+      "OtFrontend": [],
+      "security-admin-console": [],
+      "Recorder" : [ ],
+      "Obelisk" : [ ],
+      "admin-cli": [],
+      "account-console": [],
+      "broker": [
+        {
+          "id": "5052d28b-8b49-44f2-93fb-4f8beb8ff636",
+          "name": "read-token",
+          "description": "${role_read-token}",
+          "composite": false,
+          "clientRole": true,
+          "containerId": "43b53d8e-7af3-4876-b058-b8a29d60eb85",
+          "attributes": {}
+        }
+      ],
+      "account": [
+        {
+          "id": "d18b628a-8746-4996-bc36-942b1c8a9438",
+          "name": "delete-account",
+          "description": "${role_delete-account}",
+          "composite": false,
+          "clientRole": true,
+          "containerId": "55f21e46-0b32-4132-b54f-04c17f9c918f",
+          "attributes": {}
+        },
+        {
+          "id": "a7bc3639-e8be-4d20-89a2-c201bd0ca243",
+          "name": "view-applications",
+          "description": "${role_view-applications}",
+          "composite": false,
+          "clientRole": true,
+          "containerId": "55f21e46-0b32-4132-b54f-04c17f9c918f",
+          "attributes": {}
+        },
+        {
+          "id": "a11c0fe9-effb-4745-b207-880691fea62e",
+          "name": "view-profile",
+          "description": "${role_view-profile}",
+          "composite": false,
+          "clientRole": true,
+          "containerId": "55f21e46-0b32-4132-b54f-04c17f9c918f",
+          "attributes": {}
+        },
+        {
+          "id": "0d5bf788-0e68-4a57-8aba-dd0000b1579e",
+          "name": "manage-consent",
+          "description": "${role_manage-consent}",
+          "composite": true,
+          "composites": {
+            "client": {
+              "account": [
+                "view-consent"
+              ]
+            }
+          },
+          "clientRole": true,
+          "containerId": "55f21e46-0b32-4132-b54f-04c17f9c918f",
+          "attributes": {}
+        },
+        {
+          "id": "bed7d716-567b-412f-9670-7bd6c02dc225",
+          "name": "manage-account-links",
+          "description": "${role_manage-account-links}",
+          "composite": false,
+          "clientRole": true,
+          "containerId": "55f21e46-0b32-4132-b54f-04c17f9c918f",
+          "attributes": {}
+        },
+        {
+          "id": "f9c3a23c-bfca-4643-8870-800f803bb9eb",
+          "name": "view-consent",
+          "description": "${role_view-consent}",
+          "composite": false,
+          "clientRole": true,
+          "containerId": "55f21e46-0b32-4132-b54f-04c17f9c918f",
+          "attributes": {}
+        },
+        {
+          "id": "b0bc1ae4-8383-47fc-afe6-4a38644b6c0a",
+          "name": "manage-account",
+          "description": "${role_manage-account}",
+          "composite": true,
+          "composites": {
+            "client": {
+              "account": [
+                "manage-account-links"
+              ]
+            }
+          },
+          "clientRole": true,
+          "containerId": "55f21e46-0b32-4132-b54f-04c17f9c918f",
+          "attributes": {}
+        }
+      ]
+    }
+  },
+  "groups": [],
+  "defaultRole": {
+    "id": "b6a673fe-e708-4bac-9dd8-223fe65df76d",
+    "name": "default-roles-${KC_REALM_NAME}",
+    "description": "${role_default-roles}",
+    "composite": true,
+    "clientRole": false,
+    "containerId": "${KC_REALM_NAME}"
+  },
+  "requiredCredentials": [
+    "password"
+  ],
+  "passwordPolicy": "length(8) and notUsername",
+  "otpPolicyType": "totp",
+  "otpPolicyAlgorithm": "HmacSHA1",
+  "otpPolicyInitialCounter": 0,
+  "otpPolicyDigits": 6,
+  "otpPolicyLookAheadWindow": 1,
+  "otpPolicyPeriod": 30,
+  "otpSupportedApplications": [
+    "FreeOTP",
+    "Google Authenticator"
+  ],
+  "webAuthnPolicyRpEntityName": "${KC_DOMAIN} SSO",
+  "webAuthnPolicySignatureAlgorithms": [
+    "RS256",
+    "ES256",
+    "ES512",
+    "RS512"
+  ],
+  "webAuthnPolicyRpId": "${KC_HOSTNAME}",
+  "webAuthnPolicyAttestationConveyancePreference": "not specified",
+  "webAuthnPolicyAuthenticatorAttachment": "not specified",
+  "webAuthnPolicyRequireResidentKey": "not specified",
+  "webAuthnPolicyUserVerificationRequirement": "not specified",
+  "webAuthnPolicyCreateTimeout": 0,
+  "webAuthnPolicyAvoidSameAuthenticatorRegister": false,
+  "webAuthnPolicyAcceptableAaguids": [],
+  "webAuthnPolicyPasswordlessRpEntityName": "keycloak",
+  "webAuthnPolicyPasswordlessSignatureAlgorithms": [
+    "ES256"
+  ],
+  "webAuthnPolicyPasswordlessRpId": "",
+  "webAuthnPolicyPasswordlessAttestationConveyancePreference": "not specified",
+  "webAuthnPolicyPasswordlessAuthenticatorAttachment": "not specified",
+  "webAuthnPolicyPasswordlessRequireResidentKey": "not specified",
+  "webAuthnPolicyPasswordlessUserVerificationRequirement": "not specified",
+  "webAuthnPolicyPasswordlessCreateTimeout": 0,
+  "webAuthnPolicyPasswordlessAvoidSameAuthenticatorRegister": false,
+  "webAuthnPolicyPasswordlessAcceptableAaguids": [],
+  "users": [
+    {
+      "id": "b389e1d8-35ca-42e3-aa1c-d89831ef8a8d",
+      "createdTimestamp": 1666710782774,
+      "username": "service-account-otbackend",
+      "enabled": true,
+      "totp": false,
+      "emailVerified": false,
+      "serviceAccountClientId": "OtBackend",
+      "disableableCredentialTypes": [],
+      "requiredActions": [],
+      "realmRoles": [
+        "default-roles-${KC_REALM_NAME}"
+      ],
+      "clientRoles": {
+        "realm-management": [
+          "query-users",
+          "view-users"
+        ]
+      },
+      "notBefore": 0,
+      "groups": []
+    },
+    {
+      "id" : "e8f043cf-76a2-41e9-862c-95d32e6bcb3a",
+      "createdTimestamp" : 1669034343905,
+      "username" : "service-account-recorder",
+      "enabled" : true,
+      "totp" : false,
+      "emailVerified" : false,
+      "serviceAccountClientId" : "Recorder",
+      "credentials" : [ ],
+      "disableableCredentialTypes" : [ ],
+      "requiredActions" : [ ],
+      "realmRoles" : [ "opentalk-recorder", "default-roles-${KC_REALM_NAME}" ],
+      "notBefore" : 0,
+      "groups" : [ ]
+    },
+    {
+      "id" : "0568ab57-c6e7-45e9-85c5-b9081fcae119",
+      "createdTimestamp" : 1668685370945,
+      "username" : "service-account-obelisk",
+      "enabled" : true,
+      "totp" : false,
+      "emailVerified" : false,
+      "serviceAccountClientId" : "Obelisk",
+      "credentials" : [ ],
+      "disableableCredentialTypes" : [ ],
+      "requiredActions" : [ ],
+      "realmRoles" : [ "default-roles-${KC_REALM_NAME}", "opentalk-call-in" ],
+      "notBefore" : 0,
+      "groups" : [ ]
+    },
+  {
+    "id" : "40b652bb-fe83-4363-a025-7fa4ac0d4ef8",
+    "createdTimestamp" : 1667901317927,
+    "username" : "testuser",
+    "enabled" : "${KC_TESTUSER_ENABLE}",
+    "totp" : false,
+    "emailVerified" : true,
+    "firstName" : "test",
+    "lastName" : "user",
+    "email" : "testuser@foo.bar",
+    "credentials" : [ {
+      "id" : "0ffbcb30-1178-4c36-839a-87014f2db288",
+      "type" : "password",
+      "userLabel" : "My password",
+      "createdDate" : 1667901336402,
+      "secretData" : "{\"value\":\"HgLZpV0NiOfCgFk2TLC2d764VI1HysvylXVBOiG88j2K0RVV4cnY0E6upm+efaL1fRulI0b7dXD5RQvfcR3P/A==\",\"salt\":\"aa07LVMU7JgDEjcsHTryLg==\",\"additionalParameters\":{}}",
+      "credentialData" : "{\"hashIterations\":27500,\"algorithm\":\"pbkdf2-sha256\",\"additionalParameters\":{}}"
+     } ],
+    "disableableCredentialTypes" : [ ],
+    "requiredActions" : [ ],
+    "realmRoles" : [ "default-roles-${KC_REALM_NAME}" ],
+    "notBefore" : 0,
+    "groups" : [ ]
+  } ],
+ 
+  "scopeMappings": [
+    {
+      "clientScope": "offline_access",
+      "roles": [
+        "offline_access"
+      ]
+    }
+  ],
+  "clientScopeMappings": {
+    "account": [
+      {
+        "client": "account-console",
+        "roles": [
+          "manage-account"
+        ]
+      }
+    ]
+  },
+  "clients": [
+    {
+      "id": "1013466f-8bee-4a4d-889d-52cbdf27c5f0",
+      "clientId": "OtBackend",
+      "name": "OpenTalk Backend",
+      "description": "",
+      "adminUrl": "",
+      "baseUrl": "",
+      "surrogateAuthRequired": false,
+      "enabled": true,
+      "alwaysDisplayInConsole": false,
+      "clientAuthenticatorType": "client-secret",
+      "secret": "${KC_CLIENT_SECRET}",
+      "redirectUris": [
+        "https://${KC_DOMAIN}"
+      ],
+      "webOrigins": [],
+      "notBefore": 0,
+      "bearerOnly": false,
+      "consentRequired": false,
+      "standardFlowEnabled": true,
+      "implicitFlowEnabled": false,
+      "directAccessGrantsEnabled": false,
+      "serviceAccountsEnabled": true,
+      "publicClient": false,
+      "frontchannelLogout": false,
+      "protocol": "openid-connect",
+      "attributes": {
+        "backchannel.logout.session.required": "true",
+        "client_credentials.use_refresh_token": "false",
+        "display.on.consent.screen": "false",
+        "oauth2.device.authorization.grant.enabled": "false",
+        "backchannel.logout.revoke.offline.tokens": "false",
+        "use.refresh.tokens": "true",
+        "exclude.session.state.from.auth.response": "false"
+      },
+      "authenticationFlowBindingOverrides": {},
+      "fullScopeAllowed": true,
+      "nodeReRegistrationTimeout": -1,
+      "protocolMappers": [
+        {
+          "id": "e17ba82a-ea54-4877-87ea-979d41ef107e",
+          "name": "Client IP Address",
+          "protocol": "openid-connect",
+          "protocolMapper": "oidc-usersessionmodel-note-mapper",
+          "consentRequired": false,
+          "config": {
+            "user.session.note": "clientAddress",
+            "id.token.claim": "true",
+            "access.token.claim": "true",
+            "claim.name": "clientAddress",
+            "jsonType.label": "String"
+          }
+        },
+        {
+          "id": "0130d112-2f22-431e-bc29-61298eaec62c",
+          "name": "Client ID",
+          "protocol": "openid-connect",
+          "protocolMapper": "oidc-usersessionmodel-note-mapper",
+          "consentRequired": false,
+          "config": {
+            "user.session.note": "clientId",
+            "id.token.claim": "true",
+            "access.token.claim": "true",
+            "claim.name": "clientId",
+            "jsonType.label": "String"
+          }
+        },
+        {
+          "id": "0564a5b8-1259-429c-bab9-8feaf8f06166",
+          "name": "Client Host",
+          "protocol": "openid-connect",
+          "protocolMapper": "oidc-usersessionmodel-note-mapper",
+          "consentRequired": false,
+          "config": {
+            "user.session.note": "clientHost",
+            "id.token.claim": "true",
+            "access.token.claim": "true",
+            "claim.name": "clientHost",
+            "jsonType.label": "String"
+          }
+        }
+      ],
+      "defaultClientScopes": [
+        "web-origins",
+        "acr",
+        "roles",
+        "profile",
+        "email"
+      ],
+      "optionalClientScopes": [
+        "address",
+        "phone",
+        "offline_access",
+        "microprofile-jwt"
+      ]
+    },
+    {
+      "id": "011492ed-3859-44f2-820c-76eebf1233d5",
+      "clientId": "OtFrontend",
+      "name": "OpenTalk Frontend",
+      "description": "",
+      "adminUrl": "",
+      "baseUrl": "",
+      "surrogateAuthRequired": false,
+      "enabled": true,
+      "alwaysDisplayInConsole": false,
+      "clientAuthenticatorType": "client-secret",
+      "redirectUris": [
+        "https://${KC_DOMAIN}/auth/popup_callback",
+        "https://${KC_DOMAIN}/",
+        "https://${KC_DOMAIN}/auth/callback",
+        "https://${KC_DOMAIN}/dashboard"
+      ],
+      "webOrigins": [
+        "https://${KC_DOMAIN}"
+      ],
+      "notBefore": 0,
+      "bearerOnly": false,
+      "consentRequired": false,
+      "standardFlowEnabled": true,
+      "implicitFlowEnabled": false,
+      "directAccessGrantsEnabled": false,
+      "serviceAccountsEnabled": false,
+      "publicClient": true,
+      "frontchannelLogout": false,
+      "protocol": "openid-connect",
+      "attributes": {
+        "backchannel.logout.session.required": "true",
+        "client_credentials.use_refresh_token": "false",
+        "display.on.consent.screen": "false",
+        "oauth2.device.authorization.grant.enabled": "false",
+        "backchannel.logout.revoke.offline.tokens": "false",
+        "use.refresh.tokens": "true",
+        "exclude.session.state.from.auth.response": "false"
+      },
+      "authenticationFlowBindingOverrides": {},
+      "fullScopeAllowed": true,
+      "nodeReRegistrationTimeout": -1,
+      "protocolMappers": [
+        {
+          "id": "7dbf2a6a-ac9f-4b83-a53d-c9f9e29d63f1",
+          "name": "group membership",
+          "protocol": "openid-connect",
+          "protocolMapper": "oidc-group-membership-mapper",
+          "consentRequired": false,
+          "config": {
+            "full.path": "true",
+            "id.token.claim": "true",
+            "access.token.claim": "true",
+            "claim.name": "x_grp",
+            "userinfo.token.claim": "true"
+          }
+        },
+        {
+          "id": "fc846426-5c63-45db-9517-591944820c3e",
+          "name": "phone number",
+          "protocol": "openid-connect",
+          "protocolMapper": "oidc-usermodel-attribute-mapper",
+          "consentRequired": false,
+          "config": {
+            "aggregate.attrs": "false",
+            "multivalued": "false",
+            "userinfo.token.claim": "true",
+            "user.attribute": "phone",
+            "id.token.claim": "true",
+            "access.token.claim": "true",
+            "claim.name": "phone_number",
+            "jsonType.label": "String"
+          }
+        }
+      ],
+      "defaultClientScopes": [
+        "web-origins",
+        "phone",
+        "roles",
+        "profile",
+        "email"
+      ],
+      "optionalClientScopes": [
+        "address",
+        "offline_access",
+        "microprofile-jwt"
+      ]
+    },
+    {
+      "id" : "dccafa50-3fa1-4575-b2db-9096e63a9c13",
+      "clientId" : "Recorder",
+      "name" : "Opentalk Session Recorder",
+      "description" : "",
+      "surrogateAuthRequired" : false,
+      "enabled" : true,
+      "alwaysDisplayInConsole" : false,
+      "clientAuthenticatorType" : "client-secret",
+      "secret" : "DCC8hjn763ygE1knxwmu9De48PbbJCgQ",
+      "redirectUris" : [ ],
+      "webOrigins" : [ ],
+      "notBefore" : 0,
+      "bearerOnly" : false,
+      "consentRequired" : false,
+      "standardFlowEnabled" : false,
+      "implicitFlowEnabled" : false,
+      "directAccessGrantsEnabled" : false,
+      "serviceAccountsEnabled" : true,
+      "publicClient" : false,
+      "frontchannelLogout" : true,
+      "protocol" : "openid-connect",
+      "attributes" : {
+        "oidc.ciba.grant.enabled" : "false",
+        "oauth2.device.authorization.grant.enabled" : "false",
+        "client.secret.creation.time" : "1669034343",
+        "backchannel.logout.session.required" : "true",
+        "backchannel.logout.revoke.offline.tokens" : "false"
+      },
+      "authenticationFlowBindingOverrides" : { },
+      "fullScopeAllowed" : true,
+      "nodeReRegistrationTimeout" : -1,
+      "protocolMappers" : [ {
+        "id" : "854a8a9e-dfb4-40af-8dd7-2f6fb9469fd6",
+        "name" : "Client IP Address",
+        "protocol" : "openid-connect",
+        "protocolMapper" : "oidc-usersessionmodel-note-mapper",
+        "consentRequired" : false,
+        "config" : {
+          "user.session.note" : "clientAddress",
+          "id.token.claim" : "true",
+          "access.token.claim" : "true",
+          "claim.name" : "clientAddress",
+          "jsonType.label" : "String"
+        }
+      }, {
+        "id" : "edda8204-c05a-4250-ab4c-7992af3cddfe",
+        "name" : "Client ID",
+        "protocol" : "openid-connect",
+        "protocolMapper" : "oidc-usersessionmodel-note-mapper",
+        "consentRequired" : false,
+        "config" : {
+          "user.session.note" : "clientId",
+          "id.token.claim" : "true",
+          "access.token.claim" : "true",
+          "claim.name" : "clientId",
+          "jsonType.label" : "String"
+        }
+      }, {
+        "id" : "3f049503-b66d-4917-b137-d69d804be2dd",
+        "name" : "Client Host",
+        "protocol" : "openid-connect",
+        "protocolMapper" : "oidc-usersessionmodel-note-mapper",
+        "consentRequired" : false,
+        "config" : {
+          "user.session.note" : "clientHost",
+          "id.token.claim" : "true",
+          "access.token.claim" : "true",
+          "claim.name" : "clientHost",
+          "jsonType.label" : "String"
+        }
+      } ],
+      "defaultClientScopes" : [ "web-origins", "acr", "profile", "roles", "email" ],
+      "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ]
+    },
+    {
+      "id" : "ba65d269-cb6b-4b73-9b0a-d98ed054ca7c",
+      "clientId" : "Obelisk",
+      "name" : "SIP Call-In (Obelisk)",
+      "description" : "",
+      "surrogateAuthRequired" : false,
+      "enabled" : true,
+      "alwaysDisplayInConsole" : false,
+      "clientAuthenticatorType" : "client-secret",
+      "secret" : "PEDpx1CsM0ZYGidenPCGGr2kGWrOD6P8",
+      "redirectUris" : [ ],
+      "webOrigins" : [ ],
+      "notBefore" : 0,
+      "bearerOnly" : false,
+      "consentRequired" : false,
+      "standardFlowEnabled" : false,
+      "implicitFlowEnabled" : false,
+      "directAccessGrantsEnabled" : false,
+      "serviceAccountsEnabled" : true,
+      "publicClient" : false,
+      "frontchannelLogout" : true,
+      "protocol" : "openid-connect",
+      "attributes" : {
+        "oidc.ciba.grant.enabled" : "false",
+        "oauth2.device.authorization.grant.enabled" : "false",
+        "client.secret.creation.time" : "1668685370",
+        "backchannel.logout.session.required" : "true",
+        "backchannel.logout.revoke.offline.tokens" : "false"
+      },
+      "authenticationFlowBindingOverrides" : { },
+      "fullScopeAllowed" : true,
+      "nodeReRegistrationTimeout" : -1,
+      "protocolMappers" : [ {
+        "id" : "405cba01-259f-43d1-9ed2-1938e9dc0a19",
+        "name" : "Client Host",
+        "protocol" : "openid-connect",
+        "protocolMapper" : "oidc-usersessionmodel-note-mapper",
+        "consentRequired" : false,
+        "config" : {
+          "user.session.note" : "clientHost",
+          "id.token.claim" : "true",
+          "access.token.claim" : "true",
+          "claim.name" : "clientHost",
+          "jsonType.label" : "String"
+        }
+      }, {
+        "id" : "15e90aaa-74e8-4b51-aef0-5131a2242c3d",
+        "name" : "Client IP Address",
+        "protocol" : "openid-connect",
+        "protocolMapper" : "oidc-usersessionmodel-note-mapper",
+        "consentRequired" : false,
+        "config" : {
+          "user.session.note" : "clientAddress",
+          "id.token.claim" : "true",
+          "access.token.claim" : "true",
+          "claim.name" : "clientAddress",
+          "jsonType.label" : "String"
+        }
+      }, {
+        "id" : "91ac5b4b-22d8-4bad-9518-23a2991aee76",
+        "name" : "Client ID",
+        "protocol" : "openid-connect",
+        "protocolMapper" : "oidc-usersessionmodel-note-mapper",
+        "consentRequired" : false,
+        "config" : {
+          "user.session.note" : "clientId",
+          "id.token.claim" : "true",
+          "access.token.claim" : "true",
+          "claim.name" : "clientId",
+          "jsonType.label" : "String"
+        }
+      } ],
+      "defaultClientScopes" : [ "web-origins", "acr", "profile", "roles", "email" ],
+      "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ]
+    },
+    {
+      "id": "55f21e46-0b32-4132-b54f-04c17f9c918f",
+      "clientId": "account",
+      "name": "${client_account}",
+      "rootUrl": "${authBaseUrl}",
+      "baseUrl": "/realms/${KC_REALM_NAME}/account/",
+      "surrogateAuthRequired": false,
+      "enabled": true,
+      "alwaysDisplayInConsole": false,
+      "clientAuthenticatorType": "client-secret",
+      "redirectUris": [
+        "/realms/${KC_REALM_NAME}/account/*"
+      ],
+      "webOrigins": [],
+      "notBefore": 0,
+      "bearerOnly": false,
+      "consentRequired": false,
+      "standardFlowEnabled": true,
+      "implicitFlowEnabled": false,
+      "directAccessGrantsEnabled": false,
+      "serviceAccountsEnabled": false,
+      "publicClient": true,
+      "frontchannelLogout": false,
+      "protocol": "openid-connect",
+      "attributes": {},
+      "authenticationFlowBindingOverrides": {},
+      "fullScopeAllowed": false,
+      "nodeReRegistrationTimeout": 0,
+      "defaultClientScopes": [
+        "web-origins",
+        "acr",
+        "roles",
+        "profile",
+        "email"
+      ],
+      "optionalClientScopes": [
+        "address",
+        "phone",
+        "offline_access",
+        "microprofile-jwt"
+      ]
+    },
+    {
+      "id": "0cc26ca6-bd23-458e-9672-69d76026e506",
+      "clientId": "account-console",
+      "name": "${client_account-console}",
+      "rootUrl": "${authBaseUrl}",
+      "baseUrl": "/realms/${KC_REALM_NAME}/account/",
+      "surrogateAuthRequired": false,
+      "enabled": true,
+      "alwaysDisplayInConsole": false,
+      "clientAuthenticatorType": "client-secret",
+      "redirectUris": [
+        "/realms/${KC_REALM_NAME}/account/*"
+      ],
+      "webOrigins": [],
+      "notBefore": 0,
+      "bearerOnly": false,
+      "consentRequired": false,
+      "standardFlowEnabled": true,
+      "implicitFlowEnabled": false,
+      "directAccessGrantsEnabled": false,
+      "serviceAccountsEnabled": false,
+      "publicClient": true,
+      "frontchannelLogout": false,
+      "protocol": "openid-connect",
+      "attributes": {
+        "pkce.code.challenge.method": "S256"
+      },
+      "authenticationFlowBindingOverrides": {},
+      "fullScopeAllowed": false,
+      "nodeReRegistrationTimeout": 0,
+      "protocolMappers": [
+        {
+          "id": "ab7f0d1d-b2bf-463e-9d20-6f73e78c278d",
+          "name": "audience resolve",
+          "protocol": "openid-connect",
+          "protocolMapper": "oidc-audience-resolve-mapper",
+          "consentRequired": false,
+          "config": {}
+        }
+      ],
+      "defaultClientScopes": [
+        "web-origins",
+        "acr",
+        "roles",
+        "profile",
+        "email"
+      ],
+      "optionalClientScopes": [
+        "address",
+        "phone",
+        "offline_access",
+        "microprofile-jwt"
+      ]
+    },
+    {
+      "id": "4b49af14-b1c2-4441-95c3-73ed18ec4239",
+      "clientId": "admin-cli",
+      "name": "${client_admin-cli}",
+      "surrogateAuthRequired": false,
+      "enabled": true,
+      "alwaysDisplayInConsole": false,
+      "clientAuthenticatorType": "client-secret",
+      "redirectUris": [],
+      "webOrigins": [],
+      "notBefore": 0,
+      "bearerOnly": false,
+      "consentRequired": false,
+      "standardFlowEnabled": false,
+      "implicitFlowEnabled": false,
+      "directAccessGrantsEnabled": true,
+      "serviceAccountsEnabled": false,
+      "publicClient": true,
+      "frontchannelLogout": false,
+      "protocol": "openid-connect",
+      "attributes": {},
+      "authenticationFlowBindingOverrides": {},
+      "fullScopeAllowed": false,
+      "nodeReRegistrationTimeout": 0,
+      "defaultClientScopes": [
+        "web-origins",
+        "acr",
+        "roles",
+        "profile",
+        "email"
+      ],
+      "optionalClientScopes": [
+        "address",
+        "phone",
+        "offline_access",
+        "microprofile-jwt"
+      ]
+    },
+    {
+      "id": "43b53d8e-7af3-4876-b058-b8a29d60eb85",
+      "clientId": "broker",
+      "name": "${client_broker}",
+      "surrogateAuthRequired": false,
+      "enabled": true,
+      "alwaysDisplayInConsole": false,
+      "clientAuthenticatorType": "client-secret",
+      "redirectUris": [],
+      "webOrigins": [],
+      "notBefore": 0,
+      "bearerOnly": true,
+      "consentRequired": false,
+      "standardFlowEnabled": true,
+      "implicitFlowEnabled": false,
+      "directAccessGrantsEnabled": false,
+      "serviceAccountsEnabled": false,
+      "publicClient": false,
+      "frontchannelLogout": false,
+      "protocol": "openid-connect",
+      "attributes": {},
+      "authenticationFlowBindingOverrides": {},
+      "fullScopeAllowed": false,
+      "nodeReRegistrationTimeout": 0,
+      "defaultClientScopes": [
+        "web-origins",
+        "acr",
+        "roles",
+        "profile",
+        "email"
+      ],
+      "optionalClientScopes": [
+        "address",
+        "phone",
+        "offline_access",
+        "microprofile-jwt"
+      ]
+    },
+    {
+      "id": "cad91a15-3c4d-4893-9897-ebc6dde8aef9",
+      "clientId": "realm-management",
+      "name": "${client_realm-management}",
+      "surrogateAuthRequired": false,
+      "enabled": true,
+      "alwaysDisplayInConsole": false,
+      "clientAuthenticatorType": "client-secret",
+      "redirectUris": [],
+      "webOrigins": [],
+      "notBefore": 0,
+      "bearerOnly": true,
+      "consentRequired": false,
+      "standardFlowEnabled": true,
+      "implicitFlowEnabled": false,
+      "directAccessGrantsEnabled": false,
+      "serviceAccountsEnabled": false,
+      "publicClient": false,
+      "frontchannelLogout": false,
+      "protocol": "openid-connect",
+      "attributes": {},
+      "authenticationFlowBindingOverrides": {},
+      "fullScopeAllowed": false,
+      "nodeReRegistrationTimeout": 0,
+      "defaultClientScopes": [
+        "web-origins",
+        "acr",
+        "roles",
+        "profile",
+        "email"
+      ],
+      "optionalClientScopes": [
+        "address",
+        "phone",
+        "offline_access",
+        "microprofile-jwt"
+      ]
+    },
+    {
+      "id": "5370e090-0184-4a3d-97e7-f5f0dbc5b0c2",
+      "clientId": "security-admin-console",
+      "name": "${client_security-admin-console}",
+      "rootUrl": "${authAdminUrl}",
+      "baseUrl": "/admin/${KC_REALM_NAME}/console/",
+      "surrogateAuthRequired": false,
+      "enabled": true,
+      "alwaysDisplayInConsole": false,
+      "clientAuthenticatorType": "client-secret",
+      "redirectUris": [
+        "/admin/${KC_REALM_NAME}/console/*"
+      ],
+      "webOrigins": [
+        "+"
+      ],
+      "notBefore": 0,
+      "bearerOnly": false,
+      "consentRequired": false,
+      "standardFlowEnabled": true,
+      "implicitFlowEnabled": false,
+      "directAccessGrantsEnabled": false,
+      "serviceAccountsEnabled": false,
+      "publicClient": true,
+      "frontchannelLogout": false,
+      "protocol": "openid-connect",
+      "attributes": {
+        "pkce.code.challenge.method": "S256"
+      },
+      "authenticationFlowBindingOverrides": {},
+      "fullScopeAllowed": false,
+      "nodeReRegistrationTimeout": 0,
+      "protocolMappers": [
+        {
+          "id": "b3cae095-caaa-44f8-ac92-4150b6c1345e",
+          "name": "locale",
+          "protocol": "openid-connect",
+          "protocolMapper": "oidc-usermodel-attribute-mapper",
+          "consentRequired": false,
+          "config": {
+            "userinfo.token.claim": "true",
+            "user.attribute": "locale",
+            "id.token.claim": "true",
+            "access.token.claim": "true",
+            "claim.name": "locale",
+            "jsonType.label": "String"
+          }
+        }
+      ],
+      "defaultClientScopes": [
+        "web-origins",
+        "acr",
+        "roles",
+        "profile",
+        "email"
+      ],
+      "optionalClientScopes": [
+        "address",
+        "phone",
+        "offline_access",
+        "microprofile-jwt"
+      ]
+    }
+  ],
+  "clientScopes": [
+    {
+      "id": "aded001f-245c-415e-9c28-1478cbd57af6",
+      "name": "phone",
+      "description": "OpenID Connect built-in scope: phone",
+      "protocol": "openid-connect",
+      "attributes": {
+        "include.in.token.scope": "true",
+        "display.on.consent.screen": "true",
+        "consent.screen.text": "${phoneScopeConsentText}"
+      },
+      "protocolMappers": [
+        {
+          "id": "a7f6b452-fc35-48cd-b04e-49c88c8eaaa6",
+          "name": "phone number verified",
+          "protocol": "openid-connect",
+          "protocolMapper": "oidc-usermodel-attribute-mapper",
+          "consentRequired": false,
+          "config": {
+            "userinfo.token.claim": "true",
+            "user.attribute": "phoneNumberVerified",
+            "id.token.claim": "true",
+            "access.token.claim": "true",
+            "claim.name": "phone_number_verified",
+            "jsonType.label": "boolean"
+          }
+        },
+        {
+          "id": "f4362c5f-1436-4caf-959a-6a016c99e248",
+          "name": "phone number",
+          "protocol": "openid-connect",
+          "protocolMapper": "oidc-usermodel-attribute-mapper",
+          "consentRequired": false,
+          "config": {
+            "userinfo.token.claim": "true",
+            "user.attribute": "phoneNumber",
+            "id.token.claim": "true",
+            "access.token.claim": "true",
+            "claim.name": "phone_number",
+            "jsonType.label": "String"
+          }
+        }
+      ]
+    },
+    {
+      "id": "60bc5153-cb88-47a0-9943-b72a52675411",
+      "name": "role_list",
+      "description": "SAML role list",
+      "protocol": "saml",
+      "attributes": {
+        "consent.screen.text": "${samlRoleListScopeConsentText}",
+        "display.on.consent.screen": "true"
+      },
+      "protocolMappers": [
+        {
+          "id": "5bdea3dc-32db-4c80-8fbc-c442e869bf89",
+          "name": "role list",
+          "protocol": "saml",
+          "protocolMapper": "saml-role-list-mapper",
+          "consentRequired": false,
+          "config": {
+            "single": "false",
+            "attribute.nameformat": "Basic",
+            "attribute.name": "Role"
+          }
+        }
+      ]
+    },
+    {
+      "id": "a31c53a7-947d-4dca-9495-31b7eed515ba",
+      "name": "offline_access",
+      "description": "OpenID Connect built-in scope: offline_access",
+      "protocol": "openid-connect",
+      "attributes": {
+        "consent.screen.text": "${offlineAccessScopeConsentText}",
+        "display.on.consent.screen": "true"
+      }
+    },
+    {
+      "id": "e54da585-0daa-40ec-8776-a67374a22e15",
+      "name": "roles",
+      "description": "OpenID Connect scope for add user roles to the access token",
+      "protocol": "openid-connect",
+      "attributes": {
+        "include.in.token.scope": "false",
+        "display.on.consent.screen": "true",
+        "consent.screen.text": "${rolesScopeConsentText}"
+      },
+      "protocolMappers": [
+        {
+          "id": "31f62439-c5c0-4511-8b4d-577c86aea3d7",
+          "name": "realm roles",
+          "protocol": "openid-connect",
+          "protocolMapper": "oidc-usermodel-realm-role-mapper",
+          "consentRequired": false,
+          "config": {
+            "user.attribute": "foo",
+            "access.token.claim": "true",
+            "claim.name": "realm_access.roles",
+            "jsonType.label": "String",
+            "multivalued": "true"
+          }
+        },
+        {
+          "id": "eaa3d6c9-28c5-43fd-9963-306d302c6157",
+          "name": "audience resolve",
+          "protocol": "openid-connect",
+          "protocolMapper": "oidc-audience-resolve-mapper",
+          "consentRequired": false,
+          "config": {}
+        },
+        {
+          "id": "13246ed7-64a7-4797-91cc-5390df6cc72f",
+          "name": "client roles",
+          "protocol": "openid-connect",
+          "protocolMapper": "oidc-usermodel-client-role-mapper",
+          "consentRequired": false,
+          "config": {
+            "user.attribute": "foo",
+            "access.token.claim": "true",
+            "claim.name": "resource_access.${client_id}.roles",
+            "jsonType.label": "String",
+            "multivalued": "true"
+          }
+        }
+      ]
+    },
+    {
+      "id": "f38b1c66-1841-4043-a5ef-36fce3154e90",
+      "name": "profile",
+      "description": "OpenID Connect built-in scope: profile",
+      "protocol": "openid-connect",
+      "attributes": {
+        "include.in.token.scope": "true",
+        "display.on.consent.screen": "true",
+        "consent.screen.text": "${profileScopeConsentText}"
+      },
+      "protocolMappers": [
+        {
+          "id": "9eb054ab-936e-42bc-a2d9-91302040cd62",
+          "name": "family name",
+          "protocol": "openid-connect",
+          "protocolMapper": "oidc-usermodel-property-mapper",
+          "consentRequired": false,
+          "config": {
+            "userinfo.token.claim": "true",
+            "user.attribute": "lastName",
+            "id.token.claim": "true",
+            "access.token.claim": "true",
+            "claim.name": "family_name",
+            "jsonType.label": "String"
+          }
+        },
+        {
+          "id": "418d88ec-1dca-4327-96b5-df0b8690ed8d",
+          "name": "website",
+          "protocol": "openid-connect",
+          "protocolMapper": "oidc-usermodel-attribute-mapper",
+          "consentRequired": false,
+          "config": {
+            "userinfo.token.claim": "true",
+            "user.attribute": "website",
+            "id.token.claim": "true",
+            "access.token.claim": "true",
+            "claim.name": "website",
+            "jsonType.label": "String"
+          }
+        },
+        {
+          "id": "eb914257-f774-4b7b-a930-5100e5dbc540",
+          "name": "updated at",
+          "protocol": "openid-connect",
+          "protocolMapper": "oidc-usermodel-attribute-mapper",
+          "consentRequired": false,
+          "config": {
+            "userinfo.token.claim": "true",
+            "user.attribute": "updatedAt",
+            "id.token.claim": "true",
+            "access.token.claim": "true",
+            "claim.name": "updated_at",
+            "jsonType.label": "long"
+          }
+        },
+        {
+          "id": "ec998163-b0c1-4369-b68f-60a7e82dd6f5",
+          "name": "middle name",
+          "protocol": "openid-connect",
+          "protocolMapper": "oidc-usermodel-attribute-mapper",
+          "consentRequired": false,
+          "config": {
+            "userinfo.token.claim": "true",
+            "user.attribute": "middleName",
+            "id.token.claim": "true",
+            "access.token.claim": "true",
+            "claim.name": "middle_name",
+            "jsonType.label": "String"
+          }
+        },
+        {
+          "id": "a7ebfcce-9c1b-4077-b28e-c465784dda20",
+          "name": "username",
+          "protocol": "openid-connect",
+          "protocolMapper": "oidc-usermodel-property-mapper",
+          "consentRequired": false,
+          "config": {
+            "userinfo.token.claim": "true",
+            "user.attribute": "username",
+            "id.token.claim": "true",
+            "access.token.claim": "true",
+            "claim.name": "preferred_username",
+            "jsonType.label": "String"
+          }
+        },
+        {
+          "id": "54dbb006-6b58-40a7-b3a3-6740666cee68",
+          "name": "full name",
+          "protocol": "openid-connect",
+          "protocolMapper": "oidc-full-name-mapper",
+          "consentRequired": false,
+          "config": {
+            "id.token.claim": "true",
+            "access.token.claim": "true",
+            "userinfo.token.claim": "true"
+          }
+        },
+        {
+          "id": "fce80472-7ac5-465d-a095-f3995266b2f2",
+          "name": "zoneinfo",
+          "protocol": "openid-connect",
+          "protocolMapper": "oidc-usermodel-attribute-mapper",
+          "consentRequired": false,
+          "config": {
+            "userinfo.token.claim": "true",
+            "user.attribute": "zoneinfo",
+            "id.token.claim": "true",
+            "access.token.claim": "true",
+            "claim.name": "zoneinfo",
+            "jsonType.label": "String"
+          }
+        },
+        {
+          "id": "41824076-a285-4d72-a329-dc85ed2a4e27",
+          "name": "picture",
+          "protocol": "openid-connect",
+          "protocolMapper": "oidc-usermodel-attribute-mapper",
+          "consentRequired": false,
+          "config": {
+            "userinfo.token.claim": "true",
+            "user.attribute": "picture",
+            "id.token.claim": "true",
+            "access.token.claim": "true",
+            "claim.name": "picture",
+            "jsonType.label": "String"
+          }
+        },
+        {
+          "id": "620b5851-db1e-4327-9af8-3ee9eeb24b03",
+          "name": "profile",
+          "protocol": "openid-connect",
+          "protocolMapper": "oidc-usermodel-attribute-mapper",
+          "consentRequired": false,
+          "config": {
+            "userinfo.token.claim": "true",
+            "user.attribute": "profile",
+            "id.token.claim": "true",
+            "access.token.claim": "true",
+            "claim.name": "profile",
+            "jsonType.label": "String"
+          }
+        },
+        {
+          "id": "bd3f0f06-76bf-43b7-887c-dc054f86c019",
+          "name": "locale",
+          "protocol": "openid-connect",
+          "protocolMapper": "oidc-usermodel-attribute-mapper",
+          "consentRequired": false,
+          "config": {
+            "userinfo.token.claim": "true",
+            "user.attribute": "locale",
+            "id.token.claim": "true",
+            "access.token.claim": "true",
+            "claim.name": "locale",
+            "jsonType.label": "String"
+          }
+        },
+        {
+          "id": "97764e94-76c2-4ceb-bafe-c4a3e275aa81",
+          "name": "gender",
+          "protocol": "openid-connect",
+          "protocolMapper": "oidc-usermodel-attribute-mapper",
+          "consentRequired": false,
+          "config": {
+            "userinfo.token.claim": "true",
+            "user.attribute": "gender",
+            "id.token.claim": "true",
+            "access.token.claim": "true",
+            "claim.name": "gender",
+            "jsonType.label": "String"
+          }
+        },
+        {
+          "id": "46f11e73-adfb-4b6d-99d0-9f9bf263c33a",
+          "name": "given name",
+          "protocol": "openid-connect",
+          "protocolMapper": "oidc-usermodel-property-mapper",
+          "consentRequired": false,
+          "config": {
+            "userinfo.token.claim": "true",
+            "user.attribute": "firstName",
+            "id.token.claim": "true",
+            "access.token.claim": "true",
+            "claim.name": "given_name",
+            "jsonType.label": "String"
+          }
+        },
+        {
+          "id": "fa7ca5f7-3063-44fe-a3c0-e5bb4e9a70d0",
+          "name": "birthdate",
+          "protocol": "openid-connect",
+          "protocolMapper": "oidc-usermodel-attribute-mapper",
+          "consentRequired": false,
+          "config": {
+            "userinfo.token.claim": "true",
+            "user.attribute": "birthdate",
+            "id.token.claim": "true",
+            "access.token.claim": "true",
+            "claim.name": "birthdate",
+            "jsonType.label": "String"
+          }
+        },
+        {
+          "id": "cc225dde-18f2-452c-acc3-24b6ca92fdda",
+          "name": "nickname",
+          "protocol": "openid-connect",
+          "protocolMapper": "oidc-usermodel-attribute-mapper",
+          "consentRequired": false,
+          "config": {
+            "userinfo.token.claim": "true",
+            "user.attribute": "nickname",
+            "id.token.claim": "true",
+            "access.token.claim": "true",
+            "claim.name": "nickname",
+            "jsonType.label": "String"
+          }
+        }
+      ]
+    },
+    {
+      "id": "44e0050c-c159-4450-8d73-5c3efef25bf2",
+      "name": "address",
+      "description": "OpenID Connect built-in scope: address",
+      "protocol": "openid-connect",
+      "attributes": {
+        "include.in.token.scope": "true",
+        "display.on.consent.screen": "true",
+        "consent.screen.text": "${addressScopeConsentText}"
+      },
+      "protocolMappers": [
+        {
+          "id": "f667b250-d9a5-4f5e-8b56-e85b865a472e",
+          "name": "address",
+          "protocol": "openid-connect",
+          "protocolMapper": "oidc-address-mapper",
+          "consentRequired": false,
+          "config": {
+            "user.attribute.formatted": "formatted",
+            "user.attribute.country": "country",
+            "user.attribute.postal_code": "postal_code",
+            "userinfo.token.claim": "true",
+            "user.attribute.street": "street",
+            "id.token.claim": "true",
+            "user.attribute.region": "region",
+            "access.token.claim": "true",
+            "user.attribute.locality": "locality"
+          }
+        }
+      ]
+    },
+    {
+      "id": "5a6bef20-7c3d-4859-8c6f-981d07f22aa0",
+      "name": "acr",
+      "description": "OpenID Connect scope for add acr (authentication context class reference) to the token",
+      "protocol": "openid-connect",
+      "attributes": {
+        "include.in.token.scope": "false",
+        "display.on.consent.screen": "false"
+      },
+      "protocolMappers": [
+        {
+          "id": "e1cba4cc-131c-4a64-b124-6d68607ff28e",
+          "name": "acr loa level",
+          "protocol": "openid-connect",
+          "protocolMapper": "oidc-acr-mapper",
+          "consentRequired": false,
+          "config": {
+            "id.token.claim": "true",
+            "access.token.claim": "true"
+          }
+        }
+      ]
+    },
+    {
+      "id": "e0e149a9-a1ae-4895-9a9b-460cd9e94ef6",
+      "name": "email",
+      "description": "OpenID Connect built-in scope: email",
+      "protocol": "openid-connect",
+      "attributes": {
+        "include.in.token.scope": "true",
+        "display.on.consent.screen": "true",
+        "consent.screen.text": "${emailScopeConsentText}"
+      },
+      "protocolMappers": [
+        {
+          "id": "99c12568-e357-4ee4-94a6-17d65beedd1e",
+          "name": "email",
+          "protocol": "openid-connect",
+          "protocolMapper": "oidc-usermodel-property-mapper",
+          "consentRequired": false,
+          "config": {
+            "userinfo.token.claim": "true",
+            "user.attribute": "email",
+            "id.token.claim": "true",
+            "access.token.claim": "true",
+            "claim.name": "email",
+            "jsonType.label": "String"
+          }
+        },
+        {
+          "id": "e4a52ea1-05f1-4077-8af9-2d2927494349",
+          "name": "email verified",
+          "protocol": "openid-connect",
+          "protocolMapper": "oidc-usermodel-property-mapper",
+          "consentRequired": false,
+          "config": {
+            "userinfo.token.claim": "true",
+            "user.attribute": "emailVerified",
+            "id.token.claim": "true",
+            "access.token.claim": "true",
+            "claim.name": "email_verified",
+            "jsonType.label": "boolean"
+          }
+        }
+      ]
+    },
+    {
+      "id": "4bb74939-dc35-4d81-928d-f3c28f21983f",
+      "name": "microprofile-jwt",
+      "description": "Microprofile - JWT built-in scope",
+      "protocol": "openid-connect",
+      "attributes": {
+        "include.in.token.scope": "true",
+        "display.on.consent.screen": "false"
+      },
+      "protocolMappers": [
+        {
+          "id": "cdd94e9d-0345-401f-867a-a304fa07eef0",
+          "name": "groups",
+          "protocol": "openid-connect",
+          "protocolMapper": "oidc-usermodel-realm-role-mapper",
+          "consentRequired": false,
+          "config": {
+            "multivalued": "true",
+            "user.attribute": "foo",
+            "id.token.claim": "true",
+            "access.token.claim": "true",
+            "claim.name": "groups",
+            "jsonType.label": "String"
+          }
+        },
+        {
+          "id": "aed7f2ba-4100-4327-8fe9-502e8e5d52d0",
+          "name": "upn",
+          "protocol": "openid-connect",
+          "protocolMapper": "oidc-usermodel-property-mapper",
+          "consentRequired": false,
+          "config": {
+            "userinfo.token.claim": "true",
+            "user.attribute": "username",
+            "id.token.claim": "true",
+            "access.token.claim": "true",
+            "claim.name": "upn",
+            "jsonType.label": "String"
+          }
+        }
+      ]
+    },
+    {
+      "id": "398008e8-7c2b-4b48-9ed3-89f4f684f848",
+      "name": "web-origins",
+      "description": "OpenID Connect scope for add allowed web origins to the access token",
+      "protocol": "openid-connect",
+      "attributes": {
+        "include.in.token.scope": "false",
+        "display.on.consent.screen": "false",
+        "consent.screen.text": ""
+      },
+      "protocolMappers": [
+        {
+          "id": "6d1a2167-ba3d-4961-acd8-4cebe9603047",
+          "name": "allowed web origins",
+          "protocol": "openid-connect",
+          "protocolMapper": "oidc-allowed-origins-mapper",
+          "consentRequired": false,
+          "config": {}
+        }
+      ]
+    }
+  ],
+  "defaultDefaultClientScopes": [
+    "role_list",
+    "profile",
+    "email",
+    "roles",
+    "web-origins",
+    "acr"
+  ],
+  "defaultOptionalClientScopes": [
+    "offline_access",
+    "address",
+    "phone",
+    "microprofile-jwt"
+  ],
+  "browserSecurityHeaders": {
+    "contentSecurityPolicyReportOnly": "",
+    "xContentTypeOptions": "nosniff",
+    "xRobotsTag": "none",
+    "xFrameOptions": "DENY",
+    "contentSecurityPolicy": "frame-src 'self'; frame-ancestors 'self'; object-src 'none';",
+    "xXSSProtection": "1; mode=block",
+    "strictTransportSecurity": "max-age=31536000; includeSubDomains"
+  },
+  "smtpServer": {},
+  "eventsEnabled": true,
+  "eventsExpiration": 7889238,
+  "eventsListeners": [
+    "jboss-logging"
+  ],
+  "enabledEventTypes": [],
+  "adminEventsEnabled": true,
+  "adminEventsDetailsEnabled": true,
+  "identityProviders": [],
+  "identityProviderMappers": [],
+  "components": {
+    "org.keycloak.services.clientregistration.policy.ClientRegistrationPolicy": [
+      {
+        "id": "599676e9-4d60-45b6-9b06-9dddb8d1ae92",
+        "name": "Trusted Hosts",
+        "providerId": "trusted-hosts",
+        "subType": "anonymous",
+        "subComponents": {},
+        "config": {
+          "host-sending-registration-request-must-match": [
+            "true"
+          ],
+          "client-uris-must-match": [
+            "true"
+          ]
+        }
+      },
+      {
+        "id": "a8a11706-3cb2-4113-9838-14edf72e0f75",
+        "name": "Consent Required",
+        "providerId": "consent-required",
+        "subType": "anonymous",
+        "subComponents": {},
+        "config": {}
+      },
+      {
+        "id": "b58d2693-0b6a-472f-9be3-7b85b87a61e8",
+        "name": "Allowed Client Scopes",
+        "providerId": "allowed-client-templates",
+        "subType": "authenticated",
+        "subComponents": {},
+        "config": {
+          "allow-default-scopes": [
+            "true"
+          ]
+        }
+      },
+      {
+        "id": "31265691-298d-4f9d-b808-3827b6fed9db",
+        "name": "Full Scope Disabled",
+        "providerId": "scope",
+        "subType": "anonymous",
+        "subComponents": {},
+        "config": {}
+      },
+      {
+        "id": "1d4c21cd-4366-4fe4-8270-a22e0071a010",
+        "name": "Max Clients Limit",
+        "providerId": "max-clients",
+        "subType": "anonymous",
+        "subComponents": {},
+        "config": {
+          "max-clients": [
+            "200"
+          ]
+        }
+      },
+      {
+        "id": "e37c518b-f42b-4967-8b95-49f0ec8ae805",
+        "name": "Allowed Protocol Mapper Types",
+        "providerId": "allowed-protocol-mappers",
+        "subType": "anonymous",
+        "subComponents": {},
+        "config": {
+          "allowed-protocol-mapper-types": [
+            "saml-user-attribute-mapper",
+            "oidc-usermodel-attribute-mapper",
+            "oidc-sha256-pairwise-sub-mapper",
+            "saml-role-list-mapper",
+            "oidc-full-name-mapper",
+            "oidc-usermodel-property-mapper",
+            "saml-user-property-mapper",
+            "oidc-address-mapper"
+          ]
+        }
+      },
+      {
+        "id": "b1d4baf2-2387-4988-865b-caa3134da216",
+        "name": "Allowed Client Scopes",
+        "providerId": "allowed-client-templates",
+        "subType": "anonymous",
+        "subComponents": {},
+        "config": {
+          "allow-default-scopes": [
+            "true"
+          ]
+        }
+      },
+      {
+        "id": "bbf7fd57-8d4e-404d-b6a2-72676ab087ec",
+        "name": "Allowed Protocol Mapper Types",
+        "providerId": "allowed-protocol-mappers",
+        "subType": "authenticated",
+        "subComponents": {},
+        "config": {
+          "allowed-protocol-mapper-types": [
+            "oidc-usermodel-attribute-mapper",
+            "saml-role-list-mapper",
+            "saml-user-attribute-mapper",
+            "oidc-sha256-pairwise-sub-mapper",
+            "oidc-usermodel-property-mapper",
+            "oidc-address-mapper",
+            "saml-user-property-mapper",
+            "oidc-full-name-mapper"
+          ]
+        }
+      }
+    ],
+    "org.keycloak.userprofile.UserProfileProvider": [
+      {
+        "id": "af291d4f-34b2-4403-b3c2-4b2cca4c540c",
+        "providerId": "declarative-user-profile",
+        "subComponents": {},
+        "config": {}
+      }
+    ],
+    "org.keycloak.keys.KeyProvider": [
+      {
+        "id": "bda4e1f0-9eb3-4ef9-9538-909ab5c7cf99",
+        "name": "rsa-generated",
+        "providerId": "rsa-generated",
+        "subComponents": {},
+        "config": {
+          "priority": [
+            "100"
+          ]
+        }
+      },
+      {
+        "id": "e4d0764e-9f3d-4385-887d-caf428e2001f",
+        "name": "rsa-enc-generated",
+        "providerId": "rsa-enc-generated",
+        "subComponents": {},
+        "config": {
+          "priority": [
+            "100"
+          ],
+          "algorithm": [
+            "RSA-OAEP"
+          ]
+        }
+      },
+      {
+        "id": "d24882c0-eabe-49a5-98ed-0b2a0b1a6555",
+        "name": "hmac-generated",
+        "providerId": "hmac-generated",
+        "subComponents": {},
+        "config": {
+          "priority": [
+            "100"
+          ],
+          "algorithm": [
+            "HS256"
+          ]
+        }
+      },
+      {
+        "id": "eff5081d-7e1d-41bf-a466-e17fe3c6ec16",
+        "name": "aes-generated",
+        "providerId": "aes-generated",
+        "subComponents": {},
+        "config": {
+          "priority": [
+            "100"
+          ]
+        }
+      }
+    ]
+  },
+  "internationalizationEnabled": false,
+  "supportedLocales": [],
+  "defaultLocale": "",
+  "authenticationFlows": [
+    {
+      "id": "e76bd55b-d7d4-4247-a434-7a489968392a",
+      "alias": "2FA subflow",
+      "description": "",
+      "providerId": "basic-flow",
+      "topLevel": false,
+      "builtIn": false,
+      "authenticationExecutions": [
+        {
+          "authenticator": "webauthn-authenticator",
+          "authenticatorFlow": false,
+          "requirement": "ALTERNATIVE",
+          "priority": 0,
+          "autheticatorFlow": false,
+          "userSetupAllowed": false
+        },
+        {
+          "authenticator": "auth-otp-form",
+          "authenticatorFlow": false,
+          "requirement": "ALTERNATIVE",
+          "priority": 1,
+          "autheticatorFlow": false,
+          "userSetupAllowed": false
+        },
+        {
+          "authenticatorFlow": true,
+          "requirement": "ALTERNATIVE",
+          "priority": 2,
+          "autheticatorFlow": true,
+          "flowAlias": "OTP Default Subflow",
+          "userSetupAllowed": false
+        }
+      ]
+    },
+    {
+      "id": "d0dc06cc-d215-4827-8ec5-2e2bfde8e7fc",
+      "alias": "Account verification options",
+      "description": "Method with which to verity the existing account",
+      "providerId": "basic-flow",
+      "topLevel": false,
+      "builtIn": true,
+      "authenticationExecutions": [
+        {
+          "authenticator": "idp-email-verification",
+          "authenticatorFlow": false,
+          "requirement": "ALTERNATIVE",
+          "priority": 10,
+          "autheticatorFlow": false,
+          "userSetupAllowed": false
+        },
+        {
+          "authenticatorFlow": true,
+          "requirement": "ALTERNATIVE",
+          "priority": 20,
+          "autheticatorFlow": true,
+          "flowAlias": "Verify Existing Account by Re-authentication",
+          "userSetupAllowed": false
+        }
+      ]
+    },
+    {
+      "id": "02c1aa9c-d8b9-4cae-a1ab-2512ea30f194",
+      "alias": "Authentication Options",
+      "description": "Authentication options.",
+      "providerId": "basic-flow",
+      "topLevel": false,
+      "builtIn": true,
+      "authenticationExecutions": [
+        {
+          "authenticator": "basic-auth",
+          "authenticatorFlow": false,
+          "requirement": "REQUIRED",
+          "priority": 10,
+          "autheticatorFlow": false,
+          "userSetupAllowed": false
+        },
+        {
+          "authenticator": "basic-auth-otp",
+          "authenticatorFlow": false,
+          "requirement": "DISABLED",
+          "priority": 20,
+          "autheticatorFlow": false,
+          "userSetupAllowed": false
+        },
+        {
+          "authenticator": "auth-spnego",
+          "authenticatorFlow": false,
+          "requirement": "DISABLED",
+          "priority": 30,
+          "autheticatorFlow": false,
+          "userSetupAllowed": false
+        }
+      ]
+    },
+    {
+      "id": "46cd1d35-303a-4e59-8198-b3809a788bd9",
+      "alias": "Browser - Conditional OTP",
+      "description": "Flow to determine if the OTP is required for the authentication",
+      "providerId": "basic-flow",
+      "topLevel": false,
+      "builtIn": true,
+      "authenticationExecutions": [
+        {
+          "authenticator": "conditional-user-configured",
+          "authenticatorFlow": false,
+          "requirement": "REQUIRED",
+          "priority": 10,
+          "autheticatorFlow": false,
+          "userSetupAllowed": false
+        },
+        {
+          "authenticator": "auth-otp-form",
+          "authenticatorFlow": false,
+          "requirement": "REQUIRED",
+          "priority": 20,
+          "autheticatorFlow": false,
+          "userSetupAllowed": false
+        }
+      ]
+    },
+    {
+      "id": "a6810147-9978-454a-8150-94ef7c2f937d",
+      "alias": "Conditional Reset Credentials 2FA Subflow",
+      "description": "",
+      "providerId": "basic-flow",
+      "topLevel": false,
+      "builtIn": false,
+      "authenticationExecutions": [
+        {
+          "authenticator": "conditional-user-configured",
+          "authenticatorFlow": false,
+          "requirement": "REQUIRED",
+          "priority": 0,
+          "autheticatorFlow": false,
+          "userSetupAllowed": false
+        },
+        {
+          "authenticatorFlow": true,
+          "requirement": "REQUIRED",
+          "priority": 1,
+          "autheticatorFlow": true,
+          "flowAlias": "Reset Credentials 2FA Subflow",
+          "userSetupAllowed": false
+        }
+      ]
+    },
+    {
+      "id": "49f4733d-810c-4ccc-bd27-f950e9fbf283",
+      "alias": "Direct Grant - Conditional OTP",
+      "description": "Flow to determine if the OTP is required for the authentication",
+      "providerId": "basic-flow",
+      "topLevel": false,
+      "builtIn": true,
+      "authenticationExecutions": [
+        {
+          "authenticator": "conditional-user-configured",
+          "authenticatorFlow": false,
+          "requirement": "REQUIRED",
+          "priority": 10,
+          "autheticatorFlow": false,
+          "userSetupAllowed": false
+        },
+        {
+          "authenticator": "direct-grant-validate-otp",
+          "authenticatorFlow": false,
+          "requirement": "REQUIRED",
+          "priority": 20,
+          "autheticatorFlow": false,
+          "userSetupAllowed": false
+        }
+      ]
+    },
+    {
+      "id": "638e36fd-c80d-4d75-9682-c0edd096ce01",
+      "alias": "First broker login - Conditional OTP",
+      "description": "Flow to determine if the OTP is required for the authentication",
+      "providerId": "basic-flow",
+      "topLevel": false,
+      "builtIn": true,
+      "authenticationExecutions": [
+        {
+          "authenticator": "conditional-user-configured",
+          "authenticatorFlow": false,
+          "requirement": "REQUIRED",
+          "priority": 10,
+          "autheticatorFlow": false,
+          "userSetupAllowed": false
+        },
+        {
+          "authenticator": "auth-otp-form",
+          "authenticatorFlow": false,
+          "requirement": "REQUIRED",
+          "priority": 20,
+          "autheticatorFlow": false,
+          "userSetupAllowed": false
+        }
+      ]
+    },
+    {
+      "id": "0ad1c8a1-43eb-4a46-b08c-702b70aa1a33",
+      "alias": "Handle Existing Account",
+      "description": "Handle what to do if there is existing account with same email/username like authenticated identity provider",
+      "providerId": "basic-flow",
+      "topLevel": false,
+      "builtIn": true,
+      "authenticationExecutions": [
+        {
+          "authenticator": "idp-confirm-link",
+          "authenticatorFlow": false,
+          "requirement": "REQUIRED",
+          "priority": 10,
+          "autheticatorFlow": false,
+          "userSetupAllowed": false
+        },
+        {
+          "authenticatorFlow": true,
+          "requirement": "REQUIRED",
+          "priority": 20,
+          "autheticatorFlow": true,
+          "flowAlias": "Account verification options",
+          "userSetupAllowed": false
+        }
+      ]
+    },
+    {
+      "id": "14dbe097-ff2e-4a67-930e-6fc8c337ca34",
+      "alias": "IPR OTP Default Subflow",
+      "description": "",
+      "providerId": "basic-flow",
+      "topLevel": false,
+      "builtIn": false,
+      "authenticationExecutions": [
+        {
+          "authenticator": "auth-otp-form",
+          "authenticatorFlow": false,
+          "requirement": "REQUIRED",
+          "priority": 0,
+          "autheticatorFlow": false,
+          "userSetupAllowed": false
+        }
+      ]
+    },
+    {
+      "id": "da448f24-7d5b-418e-b234-c7d3561596dd",
+      "alias": "OTP Default Subflow",
+      "description": "",
+      "providerId": "basic-flow",
+      "topLevel": false,
+      "builtIn": false,
+      "authenticationExecutions": [
+        {
+          "authenticator": "auth-otp-form",
+          "authenticatorFlow": false,
+          "requirement": "REQUIRED",
+          "priority": 0,
+          "autheticatorFlow": false,
+          "userSetupAllowed": false
+        }
+      ]
+    },
+    {
+      "id": "8a1a4ebf-3acd-4191-b17f-4fee16d9369f",
+      "alias": "Password and 2FA subflow",
+      "description": "",
+      "providerId": "basic-flow",
+      "topLevel": false,
+      "builtIn": false,
+      "authenticationExecutions": [
+        {
+          "authenticator": "auth-username-password-form",
+          "authenticatorFlow": false,
+          "requirement": "REQUIRED",
+          "priority": 0,
+          "autheticatorFlow": false,
+          "userSetupAllowed": false
+        },
+        {
+          "authenticatorFlow": true,
+          "requirement": "DISABLED",
+          "priority": 1,
+          "autheticatorFlow": true,
+          "flowAlias": "2FA subflow",
+          "userSetupAllowed": false
+        }
+      ]
+    },
+    {
+      "id": "9733bc35-ef92-4e70-9199-d3610d4cd1dc",
+      "alias": "Reset - Conditional OTP",
+      "description": "Flow to determine if the OTP should be reset or not. Set to REQUIRED to force.",
+      "providerId": "basic-flow",
+      "topLevel": false,
+      "builtIn": true,
+      "authenticationExecutions": [
+        {
+          "authenticator": "conditional-user-configured",
+          "authenticatorFlow": false,
+          "requirement": "REQUIRED",
+          "priority": 10,
+          "autheticatorFlow": false,
+          "userSetupAllowed": false
+        },
+        {
+          "authenticator": "reset-otp",
+          "authenticatorFlow": false,
+          "requirement": "REQUIRED",
+          "priority": 20,
+          "autheticatorFlow": false,
+          "userSetupAllowed": false
+        }
+      ]
+    },
+    {
+      "id": "aa6d8098-5df5-4a96-8dc6-8d20f4402748",
+      "alias": "Reset Credentials 2FA Subflow",
+      "description": "",
+      "providerId": "basic-flow",
+      "topLevel": false,
+      "builtIn": false,
+      "authenticationExecutions": [
+        {
+          "authenticator": "webauthn-authenticator",
+          "authenticatorFlow": false,
+          "requirement": "ALTERNATIVE",
+          "priority": 0,
+          "autheticatorFlow": false,
+          "userSetupAllowed": false
+        },
+        {
+          "authenticator": "auth-otp-form",
+          "authenticatorFlow": false,
+          "requirement": "ALTERNATIVE",
+          "priority": 1,
+          "autheticatorFlow": false,
+          "userSetupAllowed": false
+        },
+        {
+          "authenticatorFlow": true,
+          "requirement": "ALTERNATIVE",
+          "priority": 2,
+          "autheticatorFlow": true,
+          "flowAlias": "Reset Credentials OTP Default Subflow",
+          "userSetupAllowed": false
+        }
+      ]
+    },
+    {
+      "id": "2918853c-2161-48a7-8235-4ab97df38be2",
+      "alias": "Reset Credentials OTP Default Subflow",
+      "description": "",
+      "providerId": "basic-flow",
+      "topLevel": false,
+      "builtIn": false,
+      "authenticationExecutions": [
+        {
+          "authenticator": "auth-otp-form",
+          "authenticatorFlow": false,
+          "requirement": "REQUIRED",
+          "priority": 0,
+          "autheticatorFlow": false,
+          "userSetupAllowed": false
+        }
+      ]
+    },
+    {
+      "id": "1866b461-79ec-4043-b89d-3f45ac4b4593",
+      "alias": "User creation or linking",
+      "description": "Flow for the existing/non-existing user alternatives",
+      "providerId": "basic-flow",
+      "topLevel": false,
+      "builtIn": true,
+      "authenticationExecutions": [
+        {
+          "authenticatorConfig": "create unique user config",
+          "authenticator": "idp-create-user-if-unique",
+          "authenticatorFlow": false,
+          "requirement": "ALTERNATIVE",
+          "priority": 10,
+          "autheticatorFlow": false,
+          "userSetupAllowed": false
+        },
+        {
+          "authenticatorFlow": true,
+          "requirement": "ALTERNATIVE",
+          "priority": 20,
+          "autheticatorFlow": true,
+          "flowAlias": "Handle Existing Account",
+          "userSetupAllowed": false
+        }
+      ]
+    },
+    {
+      "id": "8c876db3-7d8f-4898-86e0-69bcf9d3086c",
+      "alias": "Verify Existing Account by Re-authentication",
+      "description": "Reauthentication of existing account",
+      "providerId": "basic-flow",
+      "topLevel": false,
+      "builtIn": true,
+      "authenticationExecutions": [
+        {
+          "authenticator": "idp-username-password-form",
+          "authenticatorFlow": false,
+          "requirement": "REQUIRED",
+          "priority": 10,
+          "autheticatorFlow": false,
+          "userSetupAllowed": false
+        },
+        {
+          "authenticatorFlow": true,
+          "requirement": "CONDITIONAL",
+          "priority": 20,
+          "autheticatorFlow": true,
+          "flowAlias": "First broker login - Conditional OTP",
+          "userSetupAllowed": false
+        }
+      ]
+    },
+    {
+      "id": "11f8664a-5663-484f-8e26-9655cd54280d",
+      "alias": "browser",
+      "description": "browser based authentication",
+      "providerId": "basic-flow",
+      "topLevel": true,
+      "builtIn": true,
+      "authenticationExecutions": [
+        {
+          "authenticator": "auth-cookie",
+          "authenticatorFlow": false,
+          "requirement": "ALTERNATIVE",
+          "priority": 10,
+          "autheticatorFlow": false,
+          "userSetupAllowed": false
+        },
+        {
+          "authenticator": "auth-spnego",
+          "authenticatorFlow": false,
+          "requirement": "DISABLED",
+          "priority": 20,
+          "autheticatorFlow": false,
+          "userSetupAllowed": false
+        },
+        {
+          "authenticator": "identity-provider-redirector",
+          "authenticatorFlow": false,
+          "requirement": "ALTERNATIVE",
+          "priority": 25,
+          "autheticatorFlow": false,
+          "userSetupAllowed": false
+        },
+        {
+          "authenticatorFlow": true,
+          "requirement": "ALTERNATIVE",
+          "priority": 30,
+          "autheticatorFlow": true,
+          "flowAlias": "forms",
+          "userSetupAllowed": false
+        }
+      ]
+    },
+    {
+      "id": "b4d963e9-ecac-44cb-b9e3-f47bc2236dbf",
+      "alias": "clients",
+      "description": "Base authentication for clients",
+      "providerId": "client-flow",
+      "topLevel": true,
+      "builtIn": true,
+      "authenticationExecutions": [
+        {
+          "authenticator": "client-secret",
+          "authenticatorFlow": false,
+          "requirement": "ALTERNATIVE",
+          "priority": 10,
+          "autheticatorFlow": false,
+          "userSetupAllowed": false
+        },
+        {
+          "authenticator": "client-jwt",
+          "authenticatorFlow": false,
+          "requirement": "ALTERNATIVE",
+          "priority": 20,
+          "autheticatorFlow": false,
+          "userSetupAllowed": false
+        },
+        {
+          "authenticator": "client-secret-jwt",
+          "authenticatorFlow": false,
+          "requirement": "ALTERNATIVE",
+          "priority": 30,
+          "autheticatorFlow": false,
+          "userSetupAllowed": false
+        },
+        {
+          "authenticator": "client-x509",
+          "authenticatorFlow": false,
+          "requirement": "ALTERNATIVE",
+          "priority": 40,
+          "autheticatorFlow": false,
+          "userSetupAllowed": false
+        }
+      ]
+    },
+    {
+      "id": "e0112b3a-0378-43d0-b1df-ff0410399011",
+      "alias": "direct grant",
+      "description": "OpenID Connect Resource Owner Grant",
+      "providerId": "basic-flow",
+      "topLevel": true,
+      "builtIn": true,
+      "authenticationExecutions": [
+        {
+          "authenticator": "direct-grant-validate-username",
+          "authenticatorFlow": false,
+          "requirement": "REQUIRED",
+          "priority": 10,
+          "autheticatorFlow": false,
+          "userSetupAllowed": false
+        },
+        {
+          "authenticator": "direct-grant-validate-password",
+          "authenticatorFlow": false,
+          "requirement": "REQUIRED",
+          "priority": 20,
+          "autheticatorFlow": false,
+          "userSetupAllowed": false
+        },
+        {
+          "authenticatorFlow": true,
+          "requirement": "CONDITIONAL",
+          "priority": 30,
+          "autheticatorFlow": true,
+          "flowAlias": "Direct Grant - Conditional OTP",
+          "userSetupAllowed": false
+        }
+      ]
+    },
+    {
+      "id": "22c8a6da-a990-4f5f-a855-42f0c6369449",
+      "alias": "docker auth",
+      "description": "Used by Docker clients to authenticate against the IDP",
+      "providerId": "basic-flow",
+      "topLevel": true,
+      "builtIn": true,
+      "authenticationExecutions": [
+        {
+          "authenticator": "docker-http-basic-authenticator",
+          "authenticatorFlow": false,
+          "requirement": "REQUIRED",
+          "priority": 10,
+          "autheticatorFlow": false,
+          "userSetupAllowed": false
+        }
+      ]
+    },
+    {
+      "id": "78d84dd6-09a1-4498-ad32-c30ac64cfeba",
+      "alias": "first broker login",
+      "description": "Actions taken after first broker login with identity provider account, which is not yet linked to any Keycloak account",
+      "providerId": "basic-flow",
+      "topLevel": true,
+      "builtIn": true,
+      "authenticationExecutions": [
+        {
+          "authenticatorConfig": "review profile config",
+          "authenticator": "idp-review-profile",
+          "authenticatorFlow": false,
+          "requirement": "REQUIRED",
+          "priority": 10,
+          "autheticatorFlow": false,
+          "userSetupAllowed": false
+        },
+        {
+          "authenticatorFlow": true,
+          "requirement": "REQUIRED",
+          "priority": 20,
+          "autheticatorFlow": true,
+          "flowAlias": "User creation or linking",
+          "userSetupAllowed": false
+        }
+      ]
+    },
+    {
+      "id": "f647c182-2368-4cdc-969e-8f6c4251b891",
+      "alias": "forms",
+      "description": "Username, password, otp and other auth forms.",
+      "providerId": "basic-flow",
+      "topLevel": false,
+      "builtIn": true,
+      "authenticationExecutions": [
+        {
+          "authenticator": "auth-username-password-form",
+          "authenticatorFlow": false,
+          "requirement": "REQUIRED",
+          "priority": 10,
+          "autheticatorFlow": false,
+          "userSetupAllowed": false
+        },
+        {
+          "authenticatorFlow": true,
+          "requirement": "CONDITIONAL",
+          "priority": 20,
+          "autheticatorFlow": true,
+          "flowAlias": "Browser - Conditional OTP",
+          "userSetupAllowed": false
+        }
+      ]
+    },
+    {
+      "id": "f9fcc526-f0c1-4d24-bd07-d3e7a38bc5d8",
+      "alias": "http challenge",
+      "description": "An authentication flow based on challenge-response HTTP Authentication Schemes",
+      "providerId": "basic-flow",
+      "topLevel": true,
+      "builtIn": true,
+      "authenticationExecutions": [
+        {
+          "authenticator": "no-cookie-redirect",
+          "authenticatorFlow": false,
+          "requirement": "REQUIRED",
+          "priority": 10,
+          "autheticatorFlow": false,
+          "userSetupAllowed": false
+        },
+        {
+          "authenticatorFlow": true,
+          "requirement": "REQUIRED",
+          "priority": 20,
+          "autheticatorFlow": true,
+          "flowAlias": "Authentication Options",
+          "userSetupAllowed": false
+        }
+      ]
+    },
+    {
+      "id": "5fb34ba4-53a4-46da-a7f9-4a3eb88765e5",
+      "alias": "registration",
+      "description": "registration flow",
+      "providerId": "basic-flow",
+      "topLevel": true,
+      "builtIn": true,
+      "authenticationExecutions": [
+        {
+          "authenticator": "registration-page-form",
+          "authenticatorFlow": true,
+          "requirement": "REQUIRED",
+          "priority": 10,
+          "autheticatorFlow": true,
+          "flowAlias": "registration form",
+          "userSetupAllowed": false
+        }
+      ]
+    },
+    {
+      "id": "47d8ca43-5eae-458e-a7d5-cefcf0b19bb1",
+      "alias": "registration form",
+      "description": "registration form",
+      "providerId": "form-flow",
+      "topLevel": false,
+      "builtIn": true,
+      "authenticationExecutions": [
+        {
+          "authenticator": "registration-user-creation",
+          "authenticatorFlow": false,
+          "requirement": "REQUIRED",
+          "priority": 20,
+          "autheticatorFlow": false,
+          "userSetupAllowed": false
+        },
+        {
+          "authenticator": "registration-profile-action",
+          "authenticatorFlow": false,
+          "requirement": "REQUIRED",
+          "priority": 40,
+          "autheticatorFlow": false,
+          "userSetupAllowed": false
+        },
+        {
+          "authenticator": "registration-password-action",
+          "authenticatorFlow": false,
+          "requirement": "REQUIRED",
+          "priority": 50,
+          "autheticatorFlow": false,
+          "userSetupAllowed": false
+        },
+        {
+          "authenticator": "registration-recaptcha-action",
+          "authenticatorFlow": false,
+          "requirement": "DISABLED",
+          "priority": 60,
+          "autheticatorFlow": false,
+          "userSetupAllowed": false
+        }
+      ]
+    },
+    {
+      "id": "479210af-fb85-492c-9c0f-bcb3055b57f2",
+      "alias": "reset credentials",
+      "description": "Reset credentials for a user if they forgot their password or something",
+      "providerId": "basic-flow",
+      "topLevel": true,
+      "builtIn": true,
+      "authenticationExecutions": [
+        {
+          "authenticator": "reset-credentials-choose-user",
+          "authenticatorFlow": false,
+          "requirement": "REQUIRED",
+          "priority": 10,
+          "autheticatorFlow": false,
+          "userSetupAllowed": false
+        },
+        {
+          "authenticator": "reset-credential-email",
+          "authenticatorFlow": false,
+          "requirement": "REQUIRED",
+          "priority": 20,
+          "autheticatorFlow": false,
+          "userSetupAllowed": false
+        },
+        {
+          "authenticator": "reset-password",
+          "authenticatorFlow": false,
+          "requirement": "REQUIRED",
+          "priority": 30,
+          "autheticatorFlow": false,
+          "userSetupAllowed": false
+        },
+        {
+          "authenticatorFlow": true,
+          "requirement": "CONDITIONAL",
+          "priority": 40,
+          "autheticatorFlow": true,
+          "flowAlias": "Reset - Conditional OTP",
+          "userSetupAllowed": false
+        }
+      ]
+    },
+    {
+      "id": "d994ca24-38b9-464f-8788-4df42533fcdd",
+      "alias": "saml ecp",
+      "description": "SAML ECP Profile Authentication Flow",
+      "providerId": "basic-flow",
+      "topLevel": true,
+      "builtIn": true,
+      "authenticationExecutions": [
+        {
+          "authenticator": "http-basic-authenticator",
+          "authenticatorFlow": false,
+          "requirement": "REQUIRED",
+          "priority": 10,
+          "autheticatorFlow": false,
+          "userSetupAllowed": false
+        }
+      ]
+    },
+    {
+      "id": "b8993ca4-e567-4495-a777-c6af97b871d6",
+      "alias": "${KC_DOMAIN} Browser",
+      "description": "Customized Browser flow that forces 2FA.",
+      "providerId": "basic-flow",
+      "topLevel": true,
+      "builtIn": false,
+      "authenticationExecutions": [
+        {
+          "authenticator": "auth-cookie",
+          "authenticatorFlow": false,
+          "requirement": "ALTERNATIVE",
+          "priority": 0,
+          "autheticatorFlow": false,
+          "userSetupAllowed": false
+        },
+        {
+          "authenticator": "identity-provider-redirector",
+          "authenticatorFlow": false,
+          "requirement": "ALTERNATIVE",
+          "priority": 1,
+          "autheticatorFlow": false,
+          "userSetupAllowed": false
+        },
+        {
+          "authenticatorFlow": true,
+          "requirement": "ALTERNATIVE",
+          "priority": 2,
+          "autheticatorFlow": true,
+          "flowAlias": "Password and 2FA subflow",
+          "userSetupAllowed": false
+        }
+      ]
+    },
+    {
+      "id": "a807b502-d773-423d-b169-287437d45737",
+      "alias": "${KC_DOMAIN} Post IPR Flow",
+      "description": "Post IPR login flow that forces 2FA.",
+      "providerId": "basic-flow",
+      "topLevel": true,
+      "builtIn": false,
+      "authenticationExecutions": [
+        {
+          "authenticator": "webauthn-authenticator",
+          "authenticatorFlow": false,
+          "requirement": "ALTERNATIVE",
+          "priority": 0,
+          "autheticatorFlow": false,
+          "userSetupAllowed": false
+        },
+        {
+          "authenticator": "auth-otp-form",
+          "authenticatorFlow": false,
+          "requirement": "ALTERNATIVE",
+          "priority": 1,
+          "autheticatorFlow": false,
+          "userSetupAllowed": false
+        },
+        {
+          "authenticatorFlow": true,
+          "requirement": "ALTERNATIVE",
+          "priority": 2,
+          "autheticatorFlow": true,
+          "flowAlias": "IPR OTP Default Subflow",
+          "userSetupAllowed": false
+        }
+      ]
+    },
+    {
+      "id": "e2822599-7110-4ba5-a2a5-7fa4c7e11f7c",
+      "alias": "${KC_DOMAIN} Reset Credentials",
+      "description": "Reset credentials flow that forces 2FA verification before password reset.",
+      "providerId": "basic-flow",
+      "topLevel": true,
+      "builtIn": false,
+      "authenticationExecutions": [
+        {
+          "authenticator": "reset-credentials-choose-user",
+          "authenticatorFlow": false,
+          "requirement": "REQUIRED",
+          "priority": 0,
+          "autheticatorFlow": false,
+          "userSetupAllowed": false
+        },
+        {
+          "authenticatorFlow": true,
+          "requirement": "CONDITIONAL",
+          "priority": 1,
+          "autheticatorFlow": true,
+          "flowAlias": "Conditional Reset Credentials 2FA Subflow",
+          "userSetupAllowed": false
+        },
+        {
+          "authenticator": "reset-credential-email",
+          "authenticatorFlow": false,
+          "requirement": "REQUIRED",
+          "priority": 2,
+          "autheticatorFlow": false,
+          "userSetupAllowed": false
+        },
+        {
+          "authenticator": "reset-password",
+          "authenticatorFlow": false,
+          "requirement": "REQUIRED",
+          "priority": 3,
+          "autheticatorFlow": false,
+          "userSetupAllowed": false
+        }
+      ]
+    }
+  ],
+  "authenticatorConfig": [
+    {
+      "id": "dab50222-913e-458c-9580-7f56b616fe52",
+      "alias": "create unique user config",
+      "config": {
+        "require.password.update.after.registration": "false"
+      }
+    },
+    {
+      "id": "1e5fa012-b4c0-45b1-95eb-4fec75b1fdda",
+      "alias": "review profile config",
+      "config": {
+        "update.profile.on.first.login": "missing"
+      }
+    }
+  ],
+  "requiredActions": [
+    {
+      "alias": "CONFIGURE_TOTP",
+      "name": "Configure OTP",
+      "providerId": "CONFIGURE_TOTP",
+      "enabled": true,
+      "defaultAction": false,
+      "priority": 0,
+      "config": {}
+    },
+    {
+      "alias": "terms_and_conditions",
+      "name": "Terms and Conditions",
+      "providerId": "terms_and_conditions",
+      "enabled": false,
+      "defaultAction": false,
+      "priority": 20,
+      "config": {}
+    },
+    {
+      "alias": "UPDATE_PASSWORD",
+      "name": "Update Password",
+      "providerId": "UPDATE_PASSWORD",
+      "enabled": true,
+      "defaultAction": false,
+      "priority": 20,
+      "config": {}
+    },
+    {
+      "alias": "UPDATE_PROFILE",
+      "name": "Update Profile",
+      "providerId": "UPDATE_PROFILE",
+      "enabled": true,
+      "defaultAction": false,
+      "priority": 30,
+      "config": {}
+    },
+    {
+      "alias": "VERIFY_EMAIL",
+      "name": "Verify Email",
+      "providerId": "VERIFY_EMAIL",
+      "enabled": false,
+      "defaultAction": false,
+      "priority": 40,
+      "config": {}
+    },
+    {
+      "alias": "update_user_locale",
+      "name": "Update User Locale",
+      "providerId": "update_user_locale",
+      "enabled": true,
+      "defaultAction": false,
+      "priority": 50,
+      "config": {}
+    },
+    {
+      "alias": "delete_account",
+      "name": "Delete Account",
+      "providerId": "delete_account",
+      "enabled": false,
+      "defaultAction": false,
+      "priority": 60,
+      "config": {}
+    },
+    {
+      "alias": "webauthn-register",
+      "name": "Webauthn Register",
+      "providerId": "webauthn-register",
+      "enabled": true,
+      "defaultAction": false,
+      "priority": 60,
+      "config": {}
+    }
+  ],
+  "browserFlow": "${KC_DOMAIN} Browser",
+  "registrationFlow": "registration",
+  "directGrantFlow": "direct grant",
+  "resetCredentialsFlow": "${KC_DOMAIN} Reset Credentials",
+  "clientAuthenticationFlow": "clients",
+  "dockerAuthenticationFlow": "docker auth",
+  "attributes": {
+    "cibaBackchannelTokenDeliveryMode": "poll",
+    "cibaExpiresIn": "120",
+    "cibaAuthRequestedUserHint": "login_hint",
+    "oauth2DeviceCodeLifespan": "600",
+    "oauth2DevicePollingInterval": "5",
+    "parRequestUriLifespan": "60",
+    "cibaInterval": "5"
+  },
+  "keycloakVersion": "18.0.2",
+  "userManagedAccessAllowed": false,
+  "clientProfiles": {
+    "profiles": []
+  },
+  "clientPolicies": {
+    "policies": []
+  }
+}
diff --git a/data/minio/s3_bucket/.gitkeep b/data/minio/s3_bucket/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/docker-compose.yaml b/docker-compose.yaml
new file mode 100644
index 0000000..265f90c
--- /dev/null
+++ b/docker-compose.yaml
@@ -0,0 +1,248 @@
+---
+version: "3.9"
+services:
+  # *** KEYCLOAK ***
+  keycloak:
+    image: quay.io/keycloak/keycloak:${KC_IMAGE_TAG:-22.0}
+    profiles: ["core", "keycloak", "controller"]
+    restart: always
+    environment:
+      KEYCLOAK_ADMIN: ${KEYCLOAK_ADMIN:-admin}
+      KEYCLOAK_ADMIN_PASSWORD: ${KEYCLOAK_ADMIN_PASSWORD}
+      KC_REALM_ID: ${KC_REALM_ID:-opentalk}
+      KC_REALM_NAME: ${KC_REALM_NAME:-opentalk}
+      KC_REALM_DISPLAYNAME: ${KC_REALM_DISPLAYNAME:-opentalk}
+      KC_CLIENT_SECRET: ${KC_CLIENT_SECRET}
+      KC_DOMAIN: ${OT_DOMAIN:-opentalk.example.com}
+      KC_HOSTNAME: "accounts.${OT_DOMAIN:-opentalk.example.com}"
+      KC_HTTP_RELATIVE_PATH: ${KC_HTTP_RELATIVE_PATH:-/auth}
+      KC_PROXY: ${KC_PROXY:-edge}
+      KC_TESTUSER_ENABLE: ${KC_TESTUSER_ENABLE:-false}
+    entrypoint: []
+    command:
+      - /bin/sh
+      - -c
+      - |
+          /opt/keycloak/bin/kc.sh build --health-enabled=true
+          /opt/keycloak/bin/kc.sh start --import-realm --optimized
+    user: 0:0
+    volumes:
+      - ${KC_HOST_DATA_DIR:-./data/kc_data}:/opt/keycloak/data/:Z
+      - ${KC_HOST_POVIDER_DIR:-./data/kc_provider}:/opt/keycloak/providers:Z
+    ports:
+      - ${KC_EXP_PORT:-8087}:8080
+    healthcheck:
+      test: curl -fsS http://keycloak:8080/auth/health/ready -o - | grep UP
+      interval: 20s
+      timeout: 120s
+      retries: 10
+ 
+  # *** POSTGRES ***
+  postgres:
+    image: postgres:${POSTGRES_IMAGE_TAG:-15-alpine}
+    profiles: ["core", "postgres", "controller"]
+    volumes:
+      - ${POSTGRES_HOST_DATA_DIR:-./data/pg_data}:/var/lib/postgresql/data
+    restart: always
+    # ports:
+    #  - ${POSTGRES_EXP_PORT:-5432}:5432
+    environment:
+      POSTGRES_DB: ${POSTGRES_DB:-k3k}
+      POSTGRES_USER: ${POSTGRES_USER:-ot}
+      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
+ 
+  # *** AUTOHEAL ***
+  autoheal:
+    image: willfarrell/autoheal:${AUTOHEAL_IMAGE_TAG:-latest}
+    profiles: ["core", "keycloak", "postgres", "rabbit", "web-frontend", "controller", "janus"]
+    restart: always
+    environment:
+      AUTOHEAL_CONTAINER_LABEL: all
+    volumes:
+      - /var/run/docker.sock:/var/run/docker.sock
+
+  # *** RabbitMQ ***
+  rabbit:
+    image: rabbitmq:${RABBITMQ_IMAGE_TAG:-3.13-management-alpine}
+    profiles: ["core", "rabbit", "controller", "obelisk", "mail-worker", "recorder"]
+    restart: always
+    ports:
+      - ${RABBITMQ_EXP_NODE_PORT:-5672}:5672
+    # - ${RABBITMQ_EXP_UI_PORT:-15672}:15672
+    environment:
+      RABBITMQ_SERVER_ADDITIONAL_ERL_ARGS: -rabbit consumer_timeout 30000
+    healthcheck:
+      test: rabbitmq-diagnostics -q check_running && rabbitmq-diagnostics -q check_local_alarms
+      interval: 10s
+      timeout: 15s
+      retries: 5
+ 
+  # *** Redis ***
+  redis:
+    image: redis:${REDIS_IMAGE_TAG:-7-alpine}
+    profiles: ["core", "redis", "controller"]
+    restart: always
+    # ports:
+    #  - ${REDIS_EXP_PORT:-6379}:${REDIS_EXP_PORT:-6379}
+ 
+  # *** Web-Frontend
+  web-frontend:
+    image: ${OT_FRONTEND_IMAGE_SRC:-registry.opencode.de/opentalk/web-frontend}:${OT_FRONTEND_IMAGE_TAG:-v1.5.0}
+    profiles: ["core", "web-frontend"]
+    restart: always
+    ports:
+      - ${OT_FRONTEND_EXP_PORT:-8080}:80
+    environment:
+      CONTROLLER_HOST: controller.${OT_DOMAIN:-opentalk.example.com}
+      BASE_URL: https://${OT_DOMAIN:-opentalk.example.com}
+      OIDC_ISSUER: https://accounts.${OT_DOMAIN:-opentalk.example.com}/auth/realms/${KC_REALM_ID:-opentalk}
+      OIDC_CLIENT_ID: ${OIDC_CLIENT_ID:-OtFrontend}
+      NDT_SERVER: ${NDT_SERVER:-ndt.example.com}
+      CHANGE_PASSWORD_URL: https://accounts.${OT_DOMAIN:-opentalk.example.com}/auth/realms/${KC_REALM_ID:-opentalk}/account/
+      ERROR_REPORT_ADDRESS: ${ERROR_REPORT_ADDRESS:-reports@example.com}
+      LIBRAVATAR_DEFAULT_IMAGE: ${LIBRAVATAR_DEFAULT_IMAGE:-identicon}
+      VIDEO_BACKGROUNDS: >-
+        [{
+          altText: 'OpenTalk',
+          url: '/assets/videoBackgrounds/elevate-bg.png',
+          thumb: '/assets/videoBackgrounds/thumbs/elevate-bg-thumb.png',
+        }]
+      IS_BETA_RELEASE: ${IS_BETA_RELEASE:-false}
+      FEATURE_USER_SEARCH: ${FEATURE_USER_SEARCH:-false}
+      FEATURE_TIMER: ${FEATURE_TIMER:-true}
+      FEATURE_WHITEBOARD: ${FEATURE_WHITEBOARD:-false}
+      FEATURE_PROTOCOL: ${FEATURE_PROTOCOL:-false}
+      FEATURE_RECORDING: ${FEATURE_RECORDING:-false}
+
+  # *** controller ***
+  controller:
+    image: ${OT_CONTROLLER_IMAGE_SRC:-registry.opencode.de/opentalk/controller}:${OT_CONTROLLER_IMAGE_TAG:-v0.5.0}
+    profiles: ["core", "controller"]
+    restart: always
+    depends_on:
+      keycloak:
+        condition: service_healthy
+      rabbit:
+        condition: service_healthy
+      janus:
+        condition: service_healthy
+      minio:
+        condition: service_healthy
+    ports:
+      - ${OT_CONTROLLER_EXP_PORT:-8090}:11311
+    volumes:
+      - ${OT_CONTROLLER_CONFIG_FILE:-./config/controller.toml}:/controller/config.toml
+
+  # *** minio ***
+  minio:
+    image: minio/minio:${MINIO_IMAGE_TAG:-RELEASE.2023-07-21T21-12-44Z}
+    profiles: ["core", "minio", "controller"]
+    restart: always
+    command: minio server /data
+    volumes:
+      - ./data/minio:/data
+    healthcheck:
+      test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
+      interval: 30s
+      timeout: 20s
+      retries: 3
+    environment:
+      MINIO_ROOT_USER: ${MINIO_ROOT_USER:-minioadmin}
+      MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD:-minioadmin}
+
+  # *** janus gateway***
+  janus:
+    image: ${JANUS_IMAGE_SRC:-registry.opencode.de/opentalk/janus-gateway}:${JANUS_IMAGE_TAG:-v1.1.4}
+    profiles: ["core", "janus"]
+    restart: always
+    network_mode: host
+    depends_on:
+      - rabbit
+    command:
+      - janus
+    environment:
+      WAITTIMEOUT: ${JANUS_WAITTIMEOUT:-30}
+      RABBITMQ_HOST: ${RABBITMQ_HOST:-rabbit}
+      RABBITMQ_PORT: ${RABBITMQ_EXP_NODE_PORT:-5672}
+      JANUS_DISABLE_WEBSOCKET: ${JANUS_DISABLE_WEBSOCKET:-true}
+      JANUS_DISABLE_HTTP: ${JANUS_DISABLE_HTTP:-true}
+      JANUS_EXCHANGE: ${JANUS_EXCHANGE:-janus-exchange}
+      JANUS_QUEUE_NAME: ${JANUS_QUEUE_NAME:-janus-gateway}
+      JANUS_EXCHANGE_TYPE: ${JANUS_EXCHANGE_TYPE:-topic}
+      JANUS_QUEUE_INCOMING: ${JANUS_QUEUE_INCOMING:-to-janus}
+      JANUS_ROUTING_KEY_OUTGOING: ${JANUS_ROUTING_KEY_OUTGOING:-from-janus}
+      JANUS_ICE_IF: ${JANUS_ICE_IF:-eth0}
+      JANUS_UDP_PORT_RANGE: ${JANUS_UDP_PORT_RANGE:-20000-25000}
+      JANUS_ICE_LITE: ${JANUS_ICE_LITE:-true}
+      JANUS_EVENT_LOOPS: ${JANUS_EVENT_LOOPS:-8}
+      JANUS_IGNORE_MDNS: ${JANUS_IGNORE_MDNS:-true}
+
+  # *** obelisk ***
+  obelisk:
+    image: ${OT_OBELISK_IMAGE_SRC:-registry.opencode.de/opentalk/obelisk}:${OT_OBELISK_IMAGE_TAG:-v0.3.0}
+    profiles: ["obelisk"]
+    network_mode: host
+    restart: always
+    depends_on:
+      rabbit:
+        condition: service_healthy
+      janus:
+        condition: service_healthy
+    environment:
+      RUST_LOG: ${RUST_LOG:-info}
+      GST_DEBUG: ${GST_DEBUG:-2}
+      CONTROLLER_DOMAIN: ${CONTROLLER_DOMAIN:-controller.$OT_DOMAIN}
+      SIP_ADDR: "${SIP_ADDR:-0.0.0.0}"
+      SIP_PORT: "${SIP_PORT:-5060}"
+      SIP_USER: "${SIP_USER:-mysipuser}"
+      SIP_PASSWORD: "${SIP_PASSWORD:-mysippw}"
+      SIP_REALM: "${SIP_REALM:-SIP_REALM}"
+      SIP_REGISTRAR: "${SIP_REGISTRAR:-sip:yoursipprovider.com}"
+      SIP_STUN_SERVER: "${SIP_STUN_SERVER:-stun.yoursipprovider.com:3478}"
+      SIP_ENFORCE_QOP: "${SIP_ENFORCE_QOP:-true}"
+      SIP_RTP_PORT_RANGE_START: "${SIP_RTP_PORT_RANGE_START:-40000}"
+      SIP_RTP_PORT_RANGE_END: "${SIP_RTP_PORT_RANGE_END:-49999}"
+
+  # *** mail worker ***
+  mail-worker:
+    image: ${OT_MAIL_WORKER_IMAGE_SRC:-registry.opencode.de/opentalk/smtp-mailer}:${OT_MAIL_WORKER_IMAGE_TAG:-v0.3.0}
+    profiles: ["mail-worker"]
+    restart: always
+    depends_on:
+      rabbit:
+        condition: service_healthy
+    #volumes:
+    #  - ${OT_MAIL_WORKER_CONFIG_FILE:-./config/mail-worker.toml}:/opt/smtp-mailer/config.toml
+    environment:
+      RUST_LOG: ${RUST_LOG:-info}
+      MAILER_SMTP__SERVER: "${SMTP_SERVER:-}"
+      MAILER_FRONTEND__BASE_URL: "https://$OT_DOMAIN"
+      MAILER_LANGUAGES__DEFAULT_LANGUAGE: "${LANGUAGES_DEFAULT_LANGUAGE:-de-DE}"
+      MAILER_RABBITMQ__MAIL_TASK_QUEUE: "${RABBITMQ_MAIL_TASK_QUEUE:-opentalk_mailer}"
+      MAILER_RABBITMQ__URL: "${RABBITMQ_URL:-amqp://rabbit/%2F}"
+
+  # *** spacedeck ***
+  spacedeck:
+    image: ${SD_IMAGE_SRC:-registry.opencode.de/opentalk/spacedeck}:${SD_IMAGE_TAG:-latest}
+    profiles: ["spacedeck"]
+    restart: always
+    environment:
+      SD_HOST: ${SD_HOST:-0.0.0.0}
+      SD_PORT: ${SD_PORT:-9666}
+      SD_ENDPOINT: ${SD_ENDPOINT:-}
+      SD_API_TOKEN: ${SD_API_TOKEN:-}
+      SD_INVITE_CODE: ${SD_INVITE_CODE:-}
+    ports:
+      - "${SD_EXP_PORT:-9666}:${SD_PORT:-9666}"
+
+  # *** etherpad ***
+  etherpad:
+    image: ${EP_IMAGE_SRC:-registry.opencode.de/opentalk/etherpad}:${EP_IMAGE_TAG:-latest}
+    profiles: ["etherpad"]
+    restart: always
+    environment:
+      EP_APIKEY: ${EP_APIKEY:-}
+      TRUST_PROXY: ${TRUST_PROXY:-true}
+    ports:
+      - "${EP_EXP_PORT:-9001}:${EP_PORT:-9001}"
+
diff --git a/env.sample b/env.sample
new file mode 100644
index 0000000..b57e5f9
--- /dev/null
+++ b/env.sample
@@ -0,0 +1,135 @@
+###---> Common variables
+# Domain name on wich you want to access the frontend
+OT_DOMAIN="example.com"
+POSTGRES_PASSWORD="<mydbpassword>"
+KEYCLOAK_ADMIN_PASSWORD="<mykeycloakadminpassword>"
+KC_CLIENT_SECRET="<mykeycloakclientsecret>"
+# If janus is running in "docker host mode" it needs a local host interface for rabbitmq to connect.
+# !!! DO NOT USE YOUR PUBLIC IP ADRESS !!!
+RABBITMQ_HOST="10.20.30.40"
+###<---
+
+COMPOSE_PROJECT_NAME="opentalk"
+COMPOSE_PROFILES="core"
+
+### Keycloak
+# KC_REALM_NAME="opentalk"
+# KC_REALM_ID="$KC_REALM_NAME"
+# KC_DOMAIN="$OT_DOMAIN"
+# KC_HOSTNAME="accounts.$OT_DOMAIN"
+# KC_REALM_DISPLAYNAME="$OT_DOMAIN"
+# KC_EXP_PORT=8087
+# KEYCLOAK_ADMIN="admin"
+# KC_HOST_DATA_DIR="./data/kc_data"
+# KC_HOST_POVIDER_DIR="./data/kc_provider"
+# KC_IMAGE_TAG="20.0.0"
+# KC_SPI_TRUSTSTORE_FILE_FILE="/opt/keycloak/cacerts"
+# KC_SPI_TRUSTSTORE_FILE_PASSWORD="changeit"
+# KC_HTTP_RELATIVE_PATH="/auth"
+# KC_PROXY="edge"
+
+### PostgreSQL 
+# POSTGRES_DB="k3k"
+# POSTGRES_USER="ot"
+# POSTGRES_IMAGE_TAG=13-alpine
+# POSTGRES_HOST_DATA_DIR="./data/pg_data"
+# POSTGRES_EXP_PORT="5432"
+
+### autoheal
+# AUTOHEAL_IMAGE_TAG="latest"
+
+### RabbitMQ
+# RABBITMQ_IMAGE_TAG=3.10-management-alpine
+# RABBITMQ_EXP_NODE_PORT="5672"
+# RABBITMQ_EXP_UI_PORT="15672"
+
+### Redis
+# REDIS_IMAGE_TAG="alpine"
+# REDIS_EXP_PORT="6379"
+
+### OpenTalk WEB frontend
+# OT_FRONTEND_IMAGE_SRC=git.opentalk.dev:5050/opentalk/k3k-web-frontend
+# OT_FRONTEND_IMAGE_TAG="v1"
+# OT_FRONTEND_EXP_PORT="8080"
+# OIDC_CLIENT_ID="OtFrontend"
+# NDT_SERVER="ndt.example.com"
+# ERROR_REPORT_ADDRESS="reports@example.com"
+# LIBRAVATAR_DEFAULT_IMAGE="identicon"
+# IS_BETA_RELEASE="false"
+# FEATURE_USER_SEARCH="false"
+# FEATURE_TIMER="true"
+
+### Controller
+# OT_CONTROLLER_IMAGE_SRC=git.opentalk.dev:5050/opentalk/controller-enterprise
+# OT_CONTROLLER_IMAGE_TAG="v0.1"
+# OT_CONTROLLER_EXP_PORT="8090"
+# OT_CONTROLLER_CONFIG_FILE="./config/controller.toml"
+# KC_CLIENT_ID="OtBackend"
+
+### minio
+# MINIO_ROOT_USER=minioadmin
+# MINIO_ROOT_PASSWORD=minioadmin
+
+### Janus
+# JANUS_IMAGE_SRC="git.opentalk.dev:5050/opentalk/ot-janus-gateway"
+# JANUS_IMAGE_TAG="latest"
+# JANUS_WAITTIMEOUT="30"
+# JANUS_DISABLE_WEBSOCKET="true"
+# JANUS_DISABLE_HTTP="true"
+# JANUS_EXCHANGE="janus-exchange"
+# JANUS_QUEUE_NAME="janus-gateway"
+# JANUS_EXCHANGE_TYPE="topic"
+# JANUS_QUEUE_INCOMING="to-janus"
+# JANUS_ROUTING_KEY_OUTGOING="from-janus"
+# JANUS_ICE_IF="eth0"
+# JANUS_UDP_PORT_RANGE="20000-25000"
+# JANUS_ICE_LITE="true"
+# JANUS_EVENT_LOOPS="32"
+# JANUS_IGNORE_MDNS="true"
+
+### Obelisk
+# OT_OBELISK_IMAGE_SRC=git.heinlein-video.de:5050/heinlein-video/k3k-obelisk
+# OT_OBELISK_IMAGE_TAG=latest
+# OT_OBELISK_CONFIG_FILE="./config/obelisk.toml"
+# RUST_LOG: info
+# GST_DEBUG: 2
+# CONTROLLER_DOMAIN="controller.$OT_DOMAIN"
+# SIP_ADDR="0.0.0.0"
+# SIP_PORT="5060"
+# SIP_USER="mysipuser"
+# SIP_PASSWORD="mysippw"
+# SIP_REALM="SIP_REALM"
+# SIP_REGISTRAR="sip:yoursipprovider.com"
+# SIP_STUN_SERVER="stun.yoursipprovider.com:3478"
+# SIP_ENFORCE_QOP="true"
+# SIP_RTP_PORT_RANGE_START="40000"
+# SIP_RTP_PORT_RANGE_END="49999"
+
+### mail-worker
+# OT_MAIL_WORKER_IMAGE_SRC=git.opentalk.dev:5050/opentalk/smtp-mailer
+# OT_MAIL_WORKER_IMAGE_TAG=latest
+# OT_MAIL_WORKER_CONFIG_FILE="./config/mail-worker.toml"
+# RUST_LOG="" ${RUST_LOG:-info}
+# SMTP_SERVER=""
+# FRONTEND_BASE_URL="https://$OT_DOMAIN"
+# LANGUAGES_DEFAULT_LANGUAGE="de-DE"
+# RABBITMQ_MAIL_TASK_QUEUE="opentalk_mailer"
+# RABBITMQ_URL="amqp://rabbit/%2F}"
+
+### spacedeck
+# SD_IMAGE_SRC=git.opentalk.dev:5050/opentalk/ot-spacedeck
+# SD_IMAGE_TAG=latest
+# SD_HOST=0.0.0.0
+# SD_PORT=9666
+# SD_EXP_PORT=9666
+# SD_ENDPOINT=
+# SD_API_TOKEN=
+# SD_INVITE_CODE=
+
+### etherpad
+# EP_IMAGE_SRC=git.opentalk.dev:5050/opentalk/backend/ot-etherpad
+# EP_IMAGE_TAG=latest
+# EP_APIKEY=
+# TRUST_PROXY=true
+# EP_PORT=9001
+# EP_EXP_PORT=9001
\ No newline at end of file
diff --git a/extras/gen-common-params.sh b/extras/gen-common-params.sh
new file mode 100755
index 0000000..59796d3
--- /dev/null
+++ b/extras/gen-common-params.sh
@@ -0,0 +1,23 @@
+#!/bin/bash
+
+# a simple shell script, to quickly generate commonly used config options
+
+if type "pwgen" > /dev/null; then
+  echo "###---> Common variables"
+  # print hostname
+  echo "# Domain name on wich you want to access the frontend"
+  echo "OT_DOMAIN=$(hostnamectl hostname)"
+  # gen secrets for postgresm keycloak admin and keycloak client
+  echo -e "\nPOSTGRES_PASSWORD=$(pwgen 24)\nKEYCLOAK_ADMIN_PASSWORD=$(pwgen 24)\nKC_CLIENT_SECRET=$(pwgen 24) \n"
+  # print ip adresses to use for rabbitmq connection
+  echo "# If janus is running in docker host mode it needs a local host interface for rabbitmq to connect."
+  echo "# Use only a SINGLE line/interface and uncomment it."
+  echo "# !!! DO NOT CHOOSE YOUR PUBLIC IP ADDRESS!!!"
+  for IP in $(ip -o -4 addr show | awk '{ split($4, ip_addr, "/"); print ip_addr[1] }'| grep -v '127.0.0.1'); do
+     echo "# RABBITMQ_HOST=${IP}"
+  done
+  echo "###<---"
+else
+  echo "the utility 'pwgen' needs to be installed."
+  exit 1  
+fi
\ No newline at end of file
diff --git a/extras/nginx-samples/controller.conf.sample b/extras/nginx-samples/controller.conf.sample
new file mode 100644
index 0000000..145d1c3
--- /dev/null
+++ b/extras/nginx-samples/controller.conf.sample
@@ -0,0 +1,50 @@
+upstream controller {
+    server localhost:8090;
+}
+
+map $http_upgrade $connection_upgrade {
+        default upgrade;
+        ''      close;
+}
+
+server {
+    listen       80;
+    listen       [::]:80;
+    server_name  controller.example.com;
+
+    include snippets/letsencrypt.conf;
+
+    location / {
+        access_log off;
+        return 301 https://$server_name$request_uri;
+    }
+}
+
+server {
+    listen       443 ssl http2;
+    listen       [::]:443 ssl http2;
+    server_name  controller.example.com;
+
+    ssl_certificate         /etc/ssl/letsencrypt/crt/fullchain_controller.example.com.crt;
+    ssl_certificate_key     /etc/ssl/letsencrypt/key/controller.example.com.key;
+    ssl_trusted_certificate /etc/ssl/letsencrypt/crt/controller.example.com-intermediate.crt;
+
+    root controller.example.com;
+
+    include /etc/nginx/snippets/sslsettings.conf;
+
+    access_log  /var/log/nginx/https-access_controller.example.com.log;
+    error_log  /var/log/nginx/https-error_controller.example.com.log;
+
+    client_max_body_size 1G;
+
+    location / {
+        proxy_set_header X-Forwarded-For    $remote_addr;
+        proxy_set_header Upgrade            $http_upgrade;
+        proxy_set_header Connection         $connection_upgrade;
+        proxy_buffers                       8 8k;
+        proxy_buffer_size                   8k;
+
+        proxy_pass                          http://controller;
+    }
+}
diff --git a/extras/nginx-samples/frontend.conf.sample b/extras/nginx-samples/frontend.conf.sample
new file mode 100644
index 0000000..66f36a9
--- /dev/null
+++ b/extras/nginx-samples/frontend.conf.sample
@@ -0,0 +1,50 @@
+upstream web-frontend {
+    server localhost:8080;
+}
+
+map $http_upgrade $connection_upgrade {
+        default upgrade;
+        ''      close;
+}
+
+server {
+    listen       80;
+    listen       [::]:80;
+    server_name  example.com;
+
+    include snippets/letsencrypt.conf;
+
+    location / {
+        access_log off;
+        return 301 https://$server_name$request_uri;
+    }
+}
+
+server {
+    listen       443 ssl http2;
+    listen       [::]:443 ssl http2;
+    server_name  example.com;
+
+    ssl_certificate         /etc/ssl/letsencrypt/crt/fullchain_example.com.crt;
+    ssl_certificate_key     /etc/ssl/letsencrypt/key/example.com.key;
+    ssl_trusted_certificate /etc/ssl/letsencrypt/crt/example.com-intermediate.crt;
+
+    root example.com;
+
+    include /etc/nginx/snippets/sslsettings.conf;
+
+    access_log  /var/log/nginx/https-access_example.com.log;
+    error_log  /var/log/nginx/https-error_example.com.log;
+
+
+    location / {
+        proxy_set_header X-Forwarded-For    $remote_addr;
+        proxy_set_header Upgrade            $http_upgrade;
+        proxy_set_header Connection         $connection_upgrade;
+        proxy_buffers                       8 8k;
+        proxy_buffer_size                   8k;
+
+        proxy_pass                          http://web-frontend;
+    }
+}
+
diff --git a/extras/nginx-samples/keycloak.conf.sample b/extras/nginx-samples/keycloak.conf.sample
new file mode 100644
index 0000000..b2f27d1
--- /dev/null
+++ b/extras/nginx-samples/keycloak.conf.sample
@@ -0,0 +1,53 @@
+upstream keycloak {
+    server localhost:8087;
+}
+
+map $http_upgrade $connection_upgrade {
+        default upgrade;
+        ''      close;
+}
+
+server {
+    listen       80;
+    listen       [::]:80;
+    server_name  accounts.example.com;
+
+    include snippets/letsencrypt.conf;
+
+    location / {
+        access_log off;
+        return 301 https://$server_name$request_uri;
+    }
+}
+
+server {
+    listen       443 ssl http2;
+    listen       [::]:443 ssl http2;
+    server_name  accounts.example.com;
+
+    ssl_certificate         /etc/ssl/letsencrypt/crt/fullchain_accounts.example.com.crt;
+    ssl_certificate_key     /etc/ssl/letsencrypt/key/accounts.example.com.key;
+    ssl_trusted_certificate /etc/ssl/letsencrypt/crt/accounts.example.com-intermediate.crt;
+
+    root accounts.example.com;
+
+    include /etc/nginx/snippets/sslsettings.conf;
+
+    access_log  /var/log/nginx/https-access_accounts.example.com.log;
+    error_log  /var/log/nginx/https-error_accounts.example.com.log;
+
+
+    location / {
+        proxy_set_header Host               $host;
+        proxy_set_header X-Real-IP          $remote_addr;
+        proxy_set_header X-Forwarded-Proto  $scheme;
+        proxy_set_header X-Forwarded-For    $remote_addr;
+        proxy_set_header Upgrade            $http_upgrade;
+        proxy_set_header Connection         $connection_upgrade;
+        proxy_buffers                       8 8k;
+        proxy_buffer_size                   8k;
+
+        proxy_pass                          http://keycloak;
+    }
+}
+
diff --git a/extras/nginx-samples/snippets/letsencrypt.conf.sample b/extras/nginx-samples/snippets/letsencrypt.conf.sample
new file mode 100644
index 0000000..e3f3819
--- /dev/null
+++ b/extras/nginx-samples/snippets/letsencrypt.conf.sample
@@ -0,0 +1,6 @@
+location /.well-known/acme-challenge {
+    root /var/lib/letsencrypt;
+    default_type "text/plain";
+    try_files $uri =404;
+}
+
diff --git a/extras/nginx-samples/snippets/sslsettings.conf.sample b/extras/nginx-samples/snippets/sslsettings.conf.sample
new file mode 100644
index 0000000..afbf1dc
--- /dev/null
+++ b/extras/nginx-samples/snippets/sslsettings.conf.sample
@@ -0,0 +1,15 @@
+ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
+
+ssl_protocols TLSv1.2 TLSv1.3;
+ssl_prefer_server_ciphers off;
+
+
+ssl_session_timeout 1d;
+ssl_session_cache shared:SSL:50m;
+ssl_session_tickets off;
+
+ssl_stapling on;
+ssl_stapling_verify on;
+
+add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
+
-- 
GitLab