From f52ae93cac56bd053488c68b827b59d3371db79c Mon Sep 17 00:00:00 2001
From: Markus Scheidgen <markus.scheidgen@gmail.com>
Date: Thu, 16 Jun 2022 10:59:18 +0200
Subject: [PATCH] Fixed docker-compose oasis to support north.

---
 .dockerignore                                 |    1 -
 .gitignore                                    |    2 +-
 docs/oasis.md                                 |   91 +-
 generate_docs_artifacts.sh                    |    3 +-
 nomad/config.py                               |   35 +-
 .../nomad-realm.json                          | 1766 -----------------
 ops/docker-compose/nomad-oasis/.gitignore     |   14 +
 .../.volumes/fs/north/shared/.empty           |    0
 .../.volumes/fs/north/users/.empty            |    0
 .../nomad-oasis/.volumes/fs/public/.empty     |    0
 .../nomad-oasis/.volumes/fs/staging/.empty    |    0
 .../nomad-oasis/.volumes/fs/tmp/.empty        |    0
 .../nomad-oasis/.volumes/mongo/.empty         |    0
 .../docker-compose-with-keycloak.yaml}        |   10 +-
 .../nomad-oasis/docker-compose.yaml           |   17 +-
 .../nginx-with-keycloak.conf}                 |    0
 ops/docker-compose/nomad-oasis/nginx.conf     |    4 +-
 .../nomad-with-keycloak.yaml}                 |    1 +
 ops/docker-compose/nomad-oasis/nomad.yaml     |    6 +-
 19 files changed, 94 insertions(+), 1856 deletions(-)
 delete mode 100644 ops/docker-compose/nomad-oasis-with-keycloak/nomad-realm.json
 create mode 100644 ops/docker-compose/nomad-oasis/.gitignore
 create mode 100644 ops/docker-compose/nomad-oasis/.volumes/fs/north/shared/.empty
 create mode 100644 ops/docker-compose/nomad-oasis/.volumes/fs/north/users/.empty
 create mode 100644 ops/docker-compose/nomad-oasis/.volumes/fs/public/.empty
 create mode 100644 ops/docker-compose/nomad-oasis/.volumes/fs/staging/.empty
 create mode 100644 ops/docker-compose/nomad-oasis/.volumes/fs/tmp/.empty
 create mode 100644 ops/docker-compose/nomad-oasis/.volumes/mongo/.empty
 rename ops/docker-compose/{nomad-oasis-with-keycloak/docker-compose.yml => nomad-oasis/docker-compose-with-keycloak.yaml} (96%)
 rename ops/docker-compose/{nomad-oasis-with-keycloak/nginx.conf => nomad-oasis/nginx-with-keycloak.conf} (100%)
 rename ops/docker-compose/{nomad-oasis-with-keycloak/nomad.yaml => nomad-oasis/nomad-with-keycloak.yaml} (95%)

diff --git a/.dockerignore b/.dockerignore
index e7aab0aca7..7268d7a948 100644
--- a/.dockerignore
+++ b/.dockerignore
@@ -12,7 +12,6 @@
 .git/
 .coverage
 **/.ipynb_checkpoints
-**/.volumes
 
 nomad_lab.egg-info/
 
diff --git a/.gitignore b/.gitignore
index 01ef733dda..b09db3aca3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -11,7 +11,7 @@ __pycache__
 *.pyc
 *.egg-info/
 /data/
-.volumes/
+/.volumes
 .pytest_cache/
 .coverage*
 htmlcov
diff --git a/docs/oasis.md b/docs/oasis.md
index 86dbbc76a0..e5d21e6e86 100644
--- a/docs/oasis.md
+++ b/docs/oasis.md
@@ -9,18 +9,27 @@ central NOMAD installation.
 ## Quick-start
 
 - Find a linux computer.
-- Make sure you have [docker](https://docs.docker.com/engine/install/) and [docker-compose](https://docs.docker.com/compose/install/) installed. You have the necessary rights to run docker.
+- Make sure you have [docker](https://docs.docker.com/engine/install/) and [docker-compose](https://docs.docker.com/compose/install/) installed.
 - Download our basic configuration files [nomad-oasis.zip](assets/nomad-oasis.zip)
 - Run the following commands
+
 ```sh
 unzip nomad-oasis.zip
 cd nomad-oasis
+sudo chown -R 1000 .volumes
 docker-compose pull
 docker-compose up -d
 curl localhost/nomad-oasis/alive
 ```
+
 - Open [http://localhost/nomad-oasis](http://localhost/nomad-oasis) in your browser.
 
+To run NORTH (the NOMAD Remote Tools Hub), the `hub` container needs to run docker and
+the container has to be run under the docker group. You need to replace the default group
+id `991` in the `docker-compose.yaml`'s `hub` section with your systems docker group id.
+Run `id` if you are a docker user, or `getent group | grep docker` to find our your
+systems docker gid. The user id 1000 is used as the nomad user inside all containers.
+
 This is good as a quick test. We strongly recommend to read the following instructions
 carefully and adapt the configuration files accordingly. The following might also
 include meaningful help, if you run into problems.
@@ -132,8 +141,14 @@ A few things to notice:
 - The NOMAD images are pulled from our gitlab at MPCDF, the other services use images from a public registry (*dockerhub*).
 - The NOMAD images tag determines the image version or `stable`, `latest`, or specific development branches of NOMAD.
 - All container will be named `nomad_oasis_*`. These names can be used later to reference the container with the `docker` cmd.
-- The services are setup to restart `always`, you might want to change this to `no` while debugging errors to prevent
-indefinite restarts.
+- The services are setup to restart `always`, you might want to change this to `no` while debugging errors to prevent indefinite restarts.
+- Make sure that the `PWD` environment variable is set. NORTH needs to create bind mounts that require absolute paths and we need to pass the current working directory to the configuration from the PWD variable (see hub service in the `docker-compose.yaml`).
+- The `hub` serves needs to run docker containers. We have to use the systems docker group as a group. You might need to replace `991` with your
+systems docker group id.
+- The `hub` and all containers it starts are connected to the `nomad_oasis_north_network` docker network.
+By default the docker [bridge network driver](https://docs.docker.com/network/) is used. NORTH tools
+(and their users) will have access to this network.
+
 
 #### nomad.yaml
 
@@ -254,85 +269,48 @@ If you want to report problems with your OASIS. Please provide the logs for
 
 ### Provide and connect your own user management
 
-You can download a basic configuration [here](assets/nomad-oasis-with-keycloak.zip).
-
 NOMAD uses [keycloak](https://www.keycloak.org/) for its user management. NOMAD uses
 keycloak in two way. First, the user authentication uses the OpenID Connect/OAuth interfaces provided by keycloak.
-Second, NOMD uses the keycloak realm-management API to get a list of existing users. Keycloak is highly customizable and numerous options to
-connect keycloak to existing identity providers exist.
+Second, NOMD uses the keycloak realm-management API to get a list of existing users.
+Keycloak is highly customizable and numerous options to connect keycloak to existing
+identity providers exist.
 
 This tutorial assumes that you have a some understanding about what keycloak is and
 how it works.
 
-In the following, we provide basic installation steps for running your own keycloak in
-the NOMAD Oasis docker-compose. First, add a keycloak service to the `docker-compose.yaml`:
-
-```yaml
-services:
-    # keycloak user management
-    keycloak:
-        restart: always
-        image: jboss/keycloak:16.1.1
-        container_name: nomad_oasis_keycloak
-        environment:
-            - PROXY_ADDRESS_FORWARDING=true
-            - KEYCLOAK_FRONTEND_URL=http://<your-host>/keycloak/auth
-        volumes:
-            - keycloak:/opt/jboss/keycloak/standalone/data
-        # Uncomment to get access to the admin console.
-        # ports:
-        #   - 8080:8080
-```
+Start with the regular docker-compose installation above. Now you need to modify the
+`docker-compose.yaml` to add a keycloak service. You need to modify the `nginx.conf` to add
+another location for keycloak. You need to modify the `nomad.yaml` to tell nomad to
+use your and not the official NOMAD keycloak.
 
-Also add links to the `keycloak` service in the `app` and `worker` service:
 ```yaml
-services:
-    app:
-        links:
-            - keycloak
-    worker:
-        links:
-            - keycloak
+--8<-- "ops/docker-compose/nomad-oasis/docker-compose-with-keycloak.yaml"
 ```
 
 A few notes:
-- You have to replace `<your-host>` with a hostname usable by your users.
-- The environment variables on the keycloak service allow to use keycloak behind the nginx proxy with a path prefix `keycloak`.
+
+- You have to change the `KEYCLOAK_FRONTEND_URL` variable to match you host and set a path prefix.
+- The environment variables on the keycloak service allow to use keycloak behind the nginx proxy with a path prefix, e.g. `keycloak`.
 - By default, keycloak will use a simple H2 file database stored in the given volume. Keycloak offers many other options to connect SQL databases.
 - We will use keycloak with our nginx proxy here, but you can also host-bind the port `8080` to access keycloak directly.
 
 Second, we add a keycloak location to the nginx config:
 ```nginx
-location /keycloak {
-    proxy_set_header X-Forwarded-Proto $scheme;
-    proxy_set_header Host $host;
-    proxy_set_header X-Real-IP $remote_addr;
-    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
-
-    rewrite /keycloak/(.*) /$1 break;
-    proxy_pass http://keycloak:8080;
-}
+--8<-- "ops/docker-compose/nomad-oasis/nginx-with-keycloak.conf"
 ```
 
 A few notes:
+
 - Again, we are using `keycloak` as a path prefix. We configure the headers to allow
 keycloak to pick up the rewritten url.
 
 Third, we modify the keycloak configuration in the `nomad.yaml`:
 ```yaml
-services:
-    admin_user_id: 'a9e97ae9-7568-4b44-bb9f-7a7c6be898e8'
-
-keycloak:
-    server_url: 'http://keycloak:8080/auth'
-    public_server_url: 'http://<your-host>/keycloak/auth'
-    realm_name: nomad
-    username: 'admin'
-    password: 'password'
-    oasis: true
+--8<-- "ops/docker-compose/nomad-oasis/nomad-with-keycloak.yaml"
 ```
 
 A few notes:
+
 - There are two urls to configure for keycloak. The `server_url` is used by the nomad
 services to directly communicate with keycloak within the docker network. The `public_server_url`
 is used by the UI for perform the authentication flow.
@@ -362,6 +340,7 @@ select the realm file that you can find [in this .zip](assets/nomad-oasis-with-k
 to import our example configuration.
 
 A few notes on the realm configuration:
+
 - Realm and client settings are almost all default keycloak settings.
 - You should change the password of the admin user in the nomad realm.
 - The admin user in the nomad realm has the additional `view-users` client role for `realm-management`
@@ -380,7 +359,7 @@ current working directory of your installation/docker-compose. This directory ca
 To backup the mongodb, please refer to the official [mongodb documentation](https://docs.mongodb.com/manual/core/backups/). We suggest a simple mongodump export that is backed up alongside your files. The default configuration mounts `.volumes/mongo` into the mongodb container (as `/backup`) for this purpose. You can use this to export the NOMAD mongo database. Combine this with rsync on the `.volumes` directory and everything should be set. To create a new mongodump run:
 
 ```sh
-docker exec nomad_oasis_mongo mongodump -d nomad_v1 -o /backup
+docker exec nomad_oasis_mongo mongodump -d nomad_oasis_v1 -o /backup
 ```
 
 The elasticsearch contents can be reproduced with the information in the files and the mongodb.
diff --git a/generate_docs_artifacts.sh b/generate_docs_artifacts.sh
index 468c85ee92..7151b246fd 100755
--- a/generate_docs_artifacts.sh
+++ b/generate_docs_artifacts.sh
@@ -1,6 +1,5 @@
 #!/bin/sh
 rm -rf docs/assets/nomad-oasis*
 cd ops/docker-compose
-zip -r ../../docs/assets/nomad-oasis.zip nomad-oasis -x "nomad-oasis/.volumes**"
-zip -r ../../docs/assets/nomad-oasis-with-keycloak.zip nomad-oasis-with-keycloak -x "nomad-oasis-with-keycloak/.volumes/\*"
+zip -r ../../docs/assets/nomad-oasis.zip nomad-oasis -x "**-with-keycloak**" -x "**.empty"
 cd ../..
\ No newline at end of file
diff --git a/nomad/config.py b/nomad/config.py
index ce2467f363..f51b76015b 100644
--- a/nomad/config.py
+++ b/nomad/config.py
@@ -131,15 +131,10 @@ fs = NomadConfig(
     local_tmp='/tmp',
     prefix_size=2,
     archive_version_suffix='v1',
-    working_directory=os.getcwd()
+    working_directory=os.getcwd(),
+    external_working_directory=None
 )
 
-try:
-    fs.staging_external = os.path.abspath(fs.staging)
-    fs.public_external = os.path.abspath(fs.public)
-except Exception:
-    pass
-
 elastic = NomadConfig(
     host='localhost',
     port=9200,
@@ -256,17 +251,27 @@ def _check_config():
     if keycloak.public_server_url is None:
         keycloak.public_server_url = keycloak.server_url
 
-    if fs.staging_external is None:
-        fs.staging_external = fs.staging
+    def set_external_path(source_obj, source_key, target_obj, target_key, overwrite=False):
+        source_value = getattr(source_obj, source_key)
+        target_value = getattr(target_obj, target_key)
+
+        if target_value and not overwrite:
+            return
 
-    if fs.staging_external is not None and not os.path.isabs(fs.staging_external):
-        fs.staging_external = os.path.abspath(fs.staging_external)
+        if not source_value:
+            return
+
+        if fs.external_working_directory and not os.path.isabs(source_value):
+            target_value = os.path.join(fs.external_working_directory, source_value)
+        else:
+            target_value = source_value
 
-    if north.users_fs is not None and not os.path.isabs(north.users_fs):
-        north.users_fs = os.path.abspath(north.users_fs)
+        setattr(target_obj, target_key, target_value)
 
-    if north.shared_fs is not None and not os.path.isabs(north.shared_fs):
-        north.shared_fs = os.path.abspath(north.shared_fs)
+    set_external_path(fs, 'staging', fs, 'staging_external')
+    set_external_path(fs, 'public', fs, 'public_external')
+    set_external_path(north, 'users_fs', north, 'users_fs', overwrite=True)
+    set_external_path(north, 'shared_fs', north, 'shared_fs', overwrite=True)
 
 
 mail = NomadConfig(
diff --git a/ops/docker-compose/nomad-oasis-with-keycloak/nomad-realm.json b/ops/docker-compose/nomad-oasis-with-keycloak/nomad-realm.json
deleted file mode 100644
index 6c891437bc..0000000000
--- a/ops/docker-compose/nomad-oasis-with-keycloak/nomad-realm.json
+++ /dev/null
@@ -1,1766 +0,0 @@
-{
-  "id" : "nomad",
-  "realm" : "nomad",
-  "notBefore" : 0,
-  "defaultSignatureAlgorithm" : "RS256",
-  "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" : false,
-  "verifyEmail" : false,
-  "loginWithEmailAllowed" : true,
-  "duplicateEmailsAllowed" : false,
-  "resetPasswordAllowed" : false,
-  "editUsernameAllowed" : false,
-  "bruteForceProtected" : false,
-  "permanentLockout" : false,
-  "maxFailureWaitSeconds" : 900,
-  "minimumQuickLoginWaitSeconds" : 60,
-  "waitIncrementSeconds" : 60,
-  "quickLoginCheckMilliSeconds" : 1000,
-  "maxDeltaTimeSeconds" : 43200,
-  "failureFactor" : 30,
-  "roles" : {
-    "realm" : [ {
-      "id" : "e381187b-ddc2-46d5-84bf-0c7c3441d5dc",
-      "name" : "offline_access",
-      "description" : "${role_offline-access}",
-      "composite" : false,
-      "clientRole" : false,
-      "containerId" : "nomad",
-      "attributes" : { }
-    }, {
-      "id" : "5dc61a81-2ecd-4db7-b804-393fd76a086d",
-      "name" : "uma_authorization",
-      "description" : "${role_uma_authorization}",
-      "composite" : false,
-      "clientRole" : false,
-      "containerId" : "nomad",
-      "attributes" : { }
-    }, {
-      "id" : "afed8081-9dfb-4c66-af28-0d026fc26a3b",
-      "name" : "default-roles-nomad",
-      "description" : "${role_default-roles}",
-      "composite" : true,
-      "composites" : {
-        "realm" : [ "offline_access", "uma_authorization" ]
-      },
-      "clientRole" : false,
-      "containerId" : "nomad",
-      "attributes" : { }
-    } ],
-    "client" : {
-      "realm-management" : [ {
-        "id" : "f6867dc5-043f-4a89-9425-860d21adb43c",
-        "name" : "query-users",
-        "description" : "${role_query-users}",
-        "composite" : false,
-        "clientRole" : true,
-        "containerId" : "2a6ce415-cba7-44ad-bbb3-92f7eb3319b0",
-        "attributes" : { }
-      }, {
-        "id" : "78a6bba6-97a5-4450-a43d-f8c3c9ff0d88",
-        "name" : "query-clients",
-        "description" : "${role_query-clients}",
-        "composite" : false,
-        "clientRole" : true,
-        "containerId" : "2a6ce415-cba7-44ad-bbb3-92f7eb3319b0",
-        "attributes" : { }
-      }, {
-        "id" : "9b50c728-81c5-48ea-8a14-074cc5dda73c",
-        "name" : "view-clients",
-        "description" : "${role_view-clients}",
-        "composite" : true,
-        "composites" : {
-          "client" : {
-            "realm-management" : [ "query-clients" ]
-          }
-        },
-        "clientRole" : true,
-        "containerId" : "2a6ce415-cba7-44ad-bbb3-92f7eb3319b0",
-        "attributes" : { }
-      }, {
-        "id" : "e6cf8f34-f7f4-4927-933d-688b20456a16",
-        "name" : "view-identity-providers",
-        "description" : "${role_view-identity-providers}",
-        "composite" : false,
-        "clientRole" : true,
-        "containerId" : "2a6ce415-cba7-44ad-bbb3-92f7eb3319b0",
-        "attributes" : { }
-      }, {
-        "id" : "63046ea1-9e2c-4228-a335-758c991c7b12",
-        "name" : "view-users",
-        "description" : "${role_view-users}",
-        "composite" : true,
-        "composites" : {
-          "client" : {
-            "realm-management" : [ "query-users", "query-groups" ]
-          }
-        },
-        "clientRole" : true,
-        "containerId" : "2a6ce415-cba7-44ad-bbb3-92f7eb3319b0",
-        "attributes" : { }
-      }, {
-        "id" : "99494699-9300-49c1-99e4-11560cc7da02",
-        "name" : "manage-identity-providers",
-        "description" : "${role_manage-identity-providers}",
-        "composite" : false,
-        "clientRole" : true,
-        "containerId" : "2a6ce415-cba7-44ad-bbb3-92f7eb3319b0",
-        "attributes" : { }
-      }, {
-        "id" : "ae41e691-f07c-42cc-b80f-eba326f4a2cc",
-        "name" : "query-groups",
-        "description" : "${role_query-groups}",
-        "composite" : false,
-        "clientRole" : true,
-        "containerId" : "2a6ce415-cba7-44ad-bbb3-92f7eb3319b0",
-        "attributes" : { }
-      }, {
-        "id" : "cabfdce1-375b-47e0-b105-801249feed0f",
-        "name" : "manage-authorization",
-        "description" : "${role_manage-authorization}",
-        "composite" : false,
-        "clientRole" : true,
-        "containerId" : "2a6ce415-cba7-44ad-bbb3-92f7eb3319b0",
-        "attributes" : { }
-      }, {
-        "id" : "8ad3d036-d201-4381-ad8d-b147823d2018",
-        "name" : "impersonation",
-        "description" : "${role_impersonation}",
-        "composite" : false,
-        "clientRole" : true,
-        "containerId" : "2a6ce415-cba7-44ad-bbb3-92f7eb3319b0",
-        "attributes" : { }
-      }, {
-        "id" : "dfcc4cf0-d60a-4a6f-9565-28b308d939d7",
-        "name" : "manage-users",
-        "description" : "${role_manage-users}",
-        "composite" : false,
-        "clientRole" : true,
-        "containerId" : "2a6ce415-cba7-44ad-bbb3-92f7eb3319b0",
-        "attributes" : { }
-      }, {
-        "id" : "91871ac3-7b9f-4121-a607-866bb5f92d0e",
-        "name" : "view-realm",
-        "description" : "${role_view-realm}",
-        "composite" : false,
-        "clientRole" : true,
-        "containerId" : "2a6ce415-cba7-44ad-bbb3-92f7eb3319b0",
-        "attributes" : { }
-      }, {
-        "id" : "2163319d-74ee-4bcb-abf3-687d976d64b5",
-        "name" : "create-client",
-        "description" : "${role_create-client}",
-        "composite" : false,
-        "clientRole" : true,
-        "containerId" : "2a6ce415-cba7-44ad-bbb3-92f7eb3319b0",
-        "attributes" : { }
-      }, {
-        "id" : "7b29f0ac-a495-4c7a-80b1-96d6204432e7",
-        "name" : "query-realms",
-        "description" : "${role_query-realms}",
-        "composite" : false,
-        "clientRole" : true,
-        "containerId" : "2a6ce415-cba7-44ad-bbb3-92f7eb3319b0",
-        "attributes" : { }
-      }, {
-        "id" : "d3dd5dd0-9260-4878-98a2-197289296dc1",
-        "name" : "manage-clients",
-        "description" : "${role_manage-clients}",
-        "composite" : false,
-        "clientRole" : true,
-        "containerId" : "2a6ce415-cba7-44ad-bbb3-92f7eb3319b0",
-        "attributes" : { }
-      }, {
-        "id" : "fa4d9aca-addc-4773-8ace-c7d859290bfd",
-        "name" : "view-events",
-        "description" : "${role_view-events}",
-        "composite" : false,
-        "clientRole" : true,
-        "containerId" : "2a6ce415-cba7-44ad-bbb3-92f7eb3319b0",
-        "attributes" : { }
-      }, {
-        "id" : "253ce1cd-9978-4391-9ac7-3405981fe2d5",
-        "name" : "manage-realm",
-        "description" : "${role_manage-realm}",
-        "composite" : false,
-        "clientRole" : true,
-        "containerId" : "2a6ce415-cba7-44ad-bbb3-92f7eb3319b0",
-        "attributes" : { }
-      }, {
-        "id" : "84334fee-627c-4faf-a21a-9c2757cf7030",
-        "name" : "view-authorization",
-        "description" : "${role_view-authorization}",
-        "composite" : false,
-        "clientRole" : true,
-        "containerId" : "2a6ce415-cba7-44ad-bbb3-92f7eb3319b0",
-        "attributes" : { }
-      }, {
-        "id" : "cbbb61b3-61d8-4d7a-9883-657956eabe20",
-        "name" : "realm-admin",
-        "description" : "${role_realm-admin}",
-        "composite" : true,
-        "composites" : {
-          "client" : {
-            "realm-management" : [ "query-users", "query-clients", "view-clients", "view-identity-providers", "view-users", "manage-identity-providers", "query-groups", "manage-authorization", "impersonation", "view-realm", "manage-users", "create-client", "query-realms", "manage-clients", "view-events", "manage-realm", "view-authorization", "manage-events" ]
-          }
-        },
-        "clientRole" : true,
-        "containerId" : "2a6ce415-cba7-44ad-bbb3-92f7eb3319b0",
-        "attributes" : { }
-      }, {
-        "id" : "2ccc6fe5-6d03-4471-8b64-2e4ea99204bd",
-        "name" : "manage-events",
-        "description" : "${role_manage-events}",
-        "composite" : false,
-        "clientRole" : true,
-        "containerId" : "2a6ce415-cba7-44ad-bbb3-92f7eb3319b0",
-        "attributes" : { }
-      } ],
-      "security-admin-console" : [ ],
-      "admin-cli" : [ ],
-      "account-console" : [ ],
-      "broker" : [ ],
-      "nomad_public" : [ ],
-      "account" : [ {
-        "id" : "65cfacb6-d2ef-4e29-9d3b-d7aee90c89b0",
-        "name" : "manage-account",
-        "composite" : false,
-        "clientRole" : true,
-        "containerId" : "862a3def-d459-4637-a782-36cdb33e30d0",
-        "attributes" : { }
-      }, {
-        "id" : "b267a8ae-4a72-44f0-aa5b-b30a97eb8a00",
-        "name" : "delete-account",
-        "description" : "${role_delete-account}",
-        "composite" : false,
-        "clientRole" : true,
-        "containerId" : "862a3def-d459-4637-a782-36cdb33e30d0",
-        "attributes" : { }
-      } ]
-    }
-  },
-  "groups" : [ ],
-  "defaultRole" : {
-    "id" : "afed8081-9dfb-4c66-af28-0d026fc26a3b",
-    "name" : "default-roles-nomad",
-    "description" : "${role_default-roles}",
-    "composite" : true,
-    "clientRole" : false,
-    "containerId" : "nomad"
-  },
-  "requiredCredentials" : [ "password" ],
-  "otpPolicyType" : "totp",
-  "otpPolicyAlgorithm" : "HmacSHA1",
-  "otpPolicyInitialCounter" : 0,
-  "otpPolicyDigits" : 6,
-  "otpPolicyLookAheadWindow" : 1,
-  "otpPolicyPeriod" : 30,
-  "otpSupportedApplications" : [ "FreeOTP", "Google Authenticator" ],
-  "webAuthnPolicyRpEntityName" : "keycloak",
-  "webAuthnPolicySignatureAlgorithms" : [ "ES256" ],
-  "webAuthnPolicyRpId" : "",
-  "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" : "a9e97ae9-7568-4b44-bb9f-7a7c6be898e8",
-    "createdTimestamp" : 1646122967909,
-    "username" : "admin",
-    "enabled" : true,
-    "totp" : false,
-    "emailVerified" : true,
-    "firstName" : "Admin",
-    "lastName" : "Administrator",
-    "credentials" : [ {
-      "id" : "8a67ac2a-98e8-4a70-93cb-40efeef12454",
-      "type" : "password",
-      "createdDate" : 1646122987134,
-      "secretData" : "{\"value\":\"dBfgf/1z8FS+GOvWaaoIXV2mf8AfUTMWM9dUHF3msvwFM8Ypy78fo0fp+5pc/40Pce0YdqHghAarvJwBQWkylw==\",\"salt\":\"7Utui336SDaMh9KDXk56hg==\",\"additionalParameters\":{}}",
-      "credentialData" : "{\"hashIterations\":27500,\"algorithm\":\"pbkdf2-sha256\",\"additionalParameters\":{}}"
-    } ],
-    "disableableCredentialTypes" : [ ],
-    "requiredActions" : [ ],
-    "realmRoles" : [ "default-roles-nomad" ],
-    "clientRoles" : {
-      "realm-management" : [ "view-users" ]
-    },
-    "notBefore" : 0,
-    "groups" : [ ]
-  }, {
-    "id" : "fec95f93-4bde-4efa-8d47-8f9dbc170b94",
-    "createdTimestamp" : 1646120364248,
-    "username" : "test",
-    "enabled" : true,
-    "totp" : false,
-    "emailVerified" : true,
-    "firstName" : "Test",
-    "lastName" : "Tester",
-    "credentials" : [ {
-      "id" : "d504f921-40f2-49d8-8cb7-fb73d064607a",
-      "type" : "password",
-      "createdDate" : 1646120375623,
-      "secretData" : "{\"value\":\"2GRDpoQ3ZOwr/Pp+R5ZycokHvrmVwIQfE72GP9smQrrPNzxY+yVLyOmRjKpevrobfDSZdjiBDLV14OTSwHsjRA==\",\"salt\":\"4MnNMfVWtIrirLCY6QAFeg==\",\"additionalParameters\":{}}",
-      "credentialData" : "{\"hashIterations\":27500,\"algorithm\":\"pbkdf2-sha256\",\"additionalParameters\":{}}"
-    } ],
-    "disableableCredentialTypes" : [ ],
-    "requiredActions" : [ ],
-    "realmRoles" : [ "default-roles-nomad" ],
-    "notBefore" : 0,
-    "groups" : [ ]
-  } ],
-  "scopeMappings" : [ {
-    "clientScope" : "offline_access",
-    "roles" : [ "offline_access" ]
-  } ],
-  "clientScopeMappings" : {
-    "account" : [ {
-      "client" : "account-console",
-      "roles" : [ "manage-account" ]
-    } ]
-  },
-  "clients" : [ {
-    "id" : "862a3def-d459-4637-a782-36cdb33e30d0",
-    "clientId" : "account",
-    "name" : "${client_account}",
-    "rootUrl" : "${authBaseUrl}",
-    "baseUrl" : "/realms/nomad/account/",
-    "surrogateAuthRequired" : false,
-    "enabled" : true,
-    "alwaysDisplayInConsole" : false,
-    "clientAuthenticatorType" : "client-secret",
-    "redirectUris" : [ "/realms/nomad/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", "roles", "profile", "email" ],
-    "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ]
-  }, {
-    "id" : "2eb5d18c-e42f-469d-916e-083b05aed5f7",
-    "clientId" : "account-console",
-    "name" : "${client_account-console}",
-    "rootUrl" : "${authBaseUrl}",
-    "baseUrl" : "/realms/nomad/account/",
-    "surrogateAuthRequired" : false,
-    "enabled" : true,
-    "alwaysDisplayInConsole" : false,
-    "clientAuthenticatorType" : "client-secret",
-    "redirectUris" : [ "/realms/nomad/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" : "9573d615-bc37-400e-abec-afe3242f4a95",
-      "name" : "audience resolve",
-      "protocol" : "openid-connect",
-      "protocolMapper" : "oidc-audience-resolve-mapper",
-      "consentRequired" : false,
-      "config" : { }
-    } ],
-    "defaultClientScopes" : [ "web-origins", "roles", "profile", "email" ],
-    "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ]
-  }, {
-    "id" : "ddd86e52-3661-447a-8c90-5cf77f6f0510",
-    "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", "roles", "profile", "email" ],
-    "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ]
-  }, {
-    "id" : "c966ada9-c39c-4c64-91ca-4def358ef6c7",
-    "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", "roles", "profile", "email" ],
-    "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ]
-  }, {
-    "id" : "393e409f-5de9-44cf-8cdd-e76a2fab4f0f",
-    "clientId" : "nomad_public",
-    "surrogateAuthRequired" : false,
-    "enabled" : true,
-    "alwaysDisplayInConsole" : false,
-    "clientAuthenticatorType" : "client-secret",
-    "redirectUris" : [ "http://*", "https://*" ],
-    "webOrigins" : [ "*" ],
-    "notBefore" : 0,
-    "bearerOnly" : false,
-    "consentRequired" : false,
-    "standardFlowEnabled" : true,
-    "implicitFlowEnabled" : false,
-    "directAccessGrantsEnabled" : true,
-    "serviceAccountsEnabled" : false,
-    "publicClient" : true,
-    "frontchannelLogout" : false,
-    "protocol" : "openid-connect",
-    "attributes" : {
-      "id.token.as.detached.signature" : "false",
-      "saml.assertion.signature" : "false",
-      "saml.force.post.binding" : "false",
-      "saml.multivalued.roles" : "false",
-      "saml.encrypt" : "false",
-      "oauth2.device.authorization.grant.enabled" : "false",
-      "backchannel.logout.revoke.offline.tokens" : "false",
-      "saml.server.signature" : "false",
-      "saml.server.signature.keyinfo.ext" : "false",
-      "use.refresh.tokens" : "true",
-      "exclude.session.state.from.auth.response" : "false",
-      "oidc.ciba.grant.enabled" : "false",
-      "saml.artifact.binding" : "false",
-      "backchannel.logout.session.required" : "true",
-      "client_credentials.use_refresh_token" : "false",
-      "saml_force_name_id_format" : "false",
-      "require.pushed.authorization.requests" : "false",
-      "saml.client.signature" : "false",
-      "tls.client.certificate.bound.access.tokens" : "false",
-      "saml.authnstatement" : "false",
-      "display.on.consent.screen" : "false",
-      "saml.onetimeuse.condition" : "false"
-    },
-    "authenticationFlowBindingOverrides" : { },
-    "fullScopeAllowed" : true,
-    "nodeReRegistrationTimeout" : -1,
-    "defaultClientScopes" : [ "web-origins", "roles", "profile", "email" ],
-    "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ]
-  }, {
-    "id" : "2a6ce415-cba7-44ad-bbb3-92f7eb3319b0",
-    "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", "roles", "profile", "email" ],
-    "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ]
-  }, {
-    "id" : "463e0e93-45c8-400e-867b-9e848bbb1ec8",
-    "clientId" : "security-admin-console",
-    "name" : "${client_security-admin-console}",
-    "rootUrl" : "${authAdminUrl}",
-    "baseUrl" : "/admin/nomad/console/",
-    "surrogateAuthRequired" : false,
-    "enabled" : true,
-    "alwaysDisplayInConsole" : false,
-    "clientAuthenticatorType" : "client-secret",
-    "redirectUris" : [ "/admin/nomad/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" : "5d1f1be8-4a02-402a-9002-a20f20c6f15d",
-      "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", "roles", "profile", "email" ],
-    "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ]
-  } ],
-  "clientScopes" : [ {
-    "id" : "fd8c6e0d-e620-4744-9a84-b898dfadc357",
-    "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" : "54c44f64-5020-4da6-891e-e344189af038",
-      "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" : "d02b9b99-ccfd-461f-8a90-a6c7d3176eec",
-    "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" : "9257f22f-da61-4119-8764-7dcedff339ef",
-      "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" : "7329643d-714d-4aaa-bbfd-5f31c08872f3",
-      "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" : "dd239559-a3a6-40a0-9687-1d68c7213dd1",
-    "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" : "bc53433c-52e0-4225-ae35-db79e27a507b",
-      "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" : "1205e628-0f87-47da-8df2-b9fbf11957e4",
-      "name" : "groups",
-      "protocol" : "openid-connect",
-      "protocolMapper" : "oidc-usermodel-realm-role-mapper",
-      "consentRequired" : false,
-      "config" : {
-        "multivalued" : "true",
-        "userinfo.token.claim" : "true",
-        "user.attribute" : "foo",
-        "id.token.claim" : "true",
-        "access.token.claim" : "true",
-        "claim.name" : "groups",
-        "jsonType.label" : "String"
-      }
-    } ]
-  }, {
-    "id" : "a5874193-2a69-48b0-89ba-cab7f249f212",
-    "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" : "689f9eec-18fb-4fb0-a617-2eea10df7eac",
-      "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" : "ee411f23-e314-4c23-8f77-5a053edb5a25",
-      "name" : "audience resolve",
-      "protocol" : "openid-connect",
-      "protocolMapper" : "oidc-audience-resolve-mapper",
-      "consentRequired" : false,
-      "config" : { }
-    }, {
-      "id" : "73d5f256-f8d5-4116-848e-c4307dc8e573",
-      "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" : "73413190-a001-4eb3-9a43-0f6fd413849c",
-    "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" : "3d836e4c-d83a-4b05-9ccc-56bfb9544383",
-    "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" : "f94762eb-6f8d-42b7-83c9-8d778751e560",
-      "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" : "3da6e0c1-02d5-45a9-a47e-b2d15232abcb",
-      "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" : "0d3e896b-116f-4ee7-ac89-c23ea9191406",
-    "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" : "58901944-aa7c-40e2-b7a4-81bed8fd50a2",
-      "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" : "d4df7357-888f-4019-9eaf-411ad1ae042a",
-      "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" : "0e9ecf9d-2356-48c2-b736-a413d46fa443",
-      "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" : "9e632492-75d5-43e4-83e7-7f9c8a7d9bd3",
-      "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" : "bd7dca9d-a7a2-4313-b4fc-5d0451e28da3",
-      "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" : "686e761f-5a37-4708-847c-061323c1a4b4",
-      "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" : "b564b19d-afce-4123-864d-7080a1c9928a",
-      "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" : "5c39a140-1cf6-4d1a-a17d-d361e8845501",
-      "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" : "448471b7-4284-4a1f-8e96-2eceb5d2d8ef",
-      "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" : "bc299c67-c323-4b73-b3ca-59c6a2476c33",
-      "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" : "1599a6cc-43eb-4c5e-bb02-3777941e5599",
-      "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" : "f2b41acd-2b8a-42d2-aa86-27d4e6a6601e",
-      "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" : "String"
-      }
-    }, {
-      "id" : "d8da144c-ade1-440e-b29c-1bdb3e6fe2a8",
-      "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" : "1e58faf4-9a17-4e1f-9c10-2227a1654ca1",
-      "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" : "195f8258-092b-4496-a424-ba0cbe29b07a",
-    "name" : "role_list",
-    "description" : "SAML role list",
-    "protocol" : "saml",
-    "attributes" : {
-      "consent.screen.text" : "${samlRoleListScopeConsentText}",
-      "display.on.consent.screen" : "true"
-    },
-    "protocolMappers" : [ {
-      "id" : "9ac33624-3e70-4811-9690-02ab7f9df11c",
-      "name" : "role list",
-      "protocol" : "saml",
-      "protocolMapper" : "saml-role-list-mapper",
-      "consentRequired" : false,
-      "config" : {
-        "single" : "false",
-        "attribute.nameformat" : "Basic",
-        "attribute.name" : "Role"
-      }
-    } ]
-  }, {
-    "id" : "a7ffc72d-abf3-4ff2-8e30-138dbbf69daf",
-    "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" : "96fda695-d0c9-4c4d-8d10-d743db823171",
-      "name" : "allowed web origins",
-      "protocol" : "openid-connect",
-      "protocolMapper" : "oidc-allowed-origins-mapper",
-      "consentRequired" : false,
-      "config" : { }
-    } ]
-  } ],
-  "defaultDefaultClientScopes" : [ "profile", "role_list", "roles", "web-origins", "email" ],
-  "defaultOptionalClientScopes" : [ "phone", "offline_access", "microprofile-jwt", "address" ],
-  "browserSecurityHeaders" : {
-    "contentSecurityPolicyReportOnly" : "",
-    "xContentTypeOptions" : "nosniff",
-    "xRobotsTag" : "none",
-    "xFrameOptions" : "SAMEORIGIN",
-    "contentSecurityPolicy" : "frame-src 'self'; frame-ancestors 'self'; object-src 'none';",
-    "xXSSProtection" : "1; mode=block",
-    "strictTransportSecurity" : "max-age=31536000; includeSubDomains"
-  },
-  "smtpServer" : { },
-  "eventsEnabled" : false,
-  "eventsListeners" : [ "jboss-logging" ],
-  "enabledEventTypes" : [ ],
-  "adminEventsEnabled" : false,
-  "adminEventsDetailsEnabled" : false,
-  "identityProviders" : [ ],
-  "identityProviderMappers" : [ ],
-  "components" : {
-    "org.keycloak.services.clientregistration.policy.ClientRegistrationPolicy" : [ {
-      "id" : "1362d370-b308-44da-aafe-bd5b8596374f",
-      "name" : "Trusted Hosts",
-      "providerId" : "trusted-hosts",
-      "subType" : "anonymous",
-      "subComponents" : { },
-      "config" : {
-        "host-sending-registration-request-must-match" : [ "true" ],
-        "client-uris-must-match" : [ "true" ]
-      }
-    }, {
-      "id" : "178bef49-1704-45ae-8068-a4a0467b9576",
-      "name" : "Allowed Protocol Mapper Types",
-      "providerId" : "allowed-protocol-mappers",
-      "subType" : "authenticated",
-      "subComponents" : { },
-      "config" : {
-        "allowed-protocol-mapper-types" : [ "oidc-address-mapper", "oidc-sha256-pairwise-sub-mapper", "saml-user-attribute-mapper", "oidc-usermodel-property-mapper", "oidc-full-name-mapper", "saml-role-list-mapper", "oidc-usermodel-attribute-mapper", "saml-user-property-mapper" ]
-      }
-    }, {
-      "id" : "9f75353a-2e3b-4265-8398-86a7a18fc99b",
-      "name" : "Allowed Protocol Mapper Types",
-      "providerId" : "allowed-protocol-mappers",
-      "subType" : "anonymous",
-      "subComponents" : { },
-      "config" : {
-        "allowed-protocol-mapper-types" : [ "saml-role-list-mapper", "saml-user-property-mapper", "oidc-full-name-mapper", "saml-user-attribute-mapper", "oidc-sha256-pairwise-sub-mapper", "oidc-address-mapper", "oidc-usermodel-attribute-mapper", "oidc-usermodel-property-mapper" ]
-      }
-    }, {
-      "id" : "a99d6cf7-b503-43dc-bd5a-67098287083f",
-      "name" : "Allowed Client Scopes",
-      "providerId" : "allowed-client-templates",
-      "subType" : "authenticated",
-      "subComponents" : { },
-      "config" : {
-        "allow-default-scopes" : [ "true" ]
-      }
-    }, {
-      "id" : "2ef4d127-6000-4f34-8443-70ba9fdb195a",
-      "name" : "Full Scope Disabled",
-      "providerId" : "scope",
-      "subType" : "anonymous",
-      "subComponents" : { },
-      "config" : { }
-    }, {
-      "id" : "295701ce-c3a3-4966-a80c-b21e69ce40fb",
-      "name" : "Allowed Client Scopes",
-      "providerId" : "allowed-client-templates",
-      "subType" : "anonymous",
-      "subComponents" : { },
-      "config" : {
-        "allow-default-scopes" : [ "true" ]
-      }
-    }, {
-      "id" : "c5cc72ca-05b2-450f-bc98-e21fd47f26e5",
-      "name" : "Max Clients Limit",
-      "providerId" : "max-clients",
-      "subType" : "anonymous",
-      "subComponents" : { },
-      "config" : {
-        "max-clients" : [ "200" ]
-      }
-    }, {
-      "id" : "0501e34c-7022-4704-b684-13b421062bf5",
-      "name" : "Consent Required",
-      "providerId" : "consent-required",
-      "subType" : "anonymous",
-      "subComponents" : { },
-      "config" : { }
-    } ],
-    "org.keycloak.keys.KeyProvider" : [ {
-      "id" : "cdce0855-bfac-4c2e-92d3-acb5b5561db9",
-      "name" : "hmac-generated",
-      "providerId" : "hmac-generated",
-      "subComponents" : { },
-      "config" : {
-        "kid" : [ "2bfa7e0f-7b48-4021-aff1-f1c5f933e4d2" ],
-        "secret" : [ "zuA4826GqP_ewqBcuDSYPtuvLc2Yv7G_j4B3FcFoKuk_LThre6YWEr0joJSDMewtAFcLwY81_WUekf8OoGHwfA" ],
-        "priority" : [ "100" ],
-        "algorithm" : [ "HS256" ]
-      }
-    }, {
-      "id" : "8dfe077a-7cdd-4bd7-b057-6dca64b00fc8",
-      "name" : "rsa-generated",
-      "providerId" : "rsa-generated",
-      "subComponents" : { },
-      "config" : {
-        "privateKey" : [ "MIIEowIBAAKCAQEAjXiq7B4BtXCfyh3o+DJ7JjXDbTk1unIqUCrFV/ojjPUw70dfZ3oUoqiW1mcyXg0dlElCbgReZzKQf93MTyzkxapHJyHSEjppxafIkmYh9LS8WEHiGjuzDz2Gp0ITrl7OzBhtU3JYXnZbcmhiGh6V6FmCCX6vp2jAZmmcJmGD7EW26Rk6LkYQovPHYNzFCvst212mPpdLjuHhqyv1OcGWqSTWgxsf0jP//Pu5Y3kCSWut8aDvI/3rHHvk821MHTSWndweVLmgQKGDhLmKkiF0WBLgdl3cd5pDk3FfgUkchyvaZWKO2dW6FrUuciKuAngNdmLo3ZyzACnDrisx49noFwIDAQABAoIBAFOaMJ/SZ74abUNbA5bQ9jexY+jC+z5QQzMW44JHHwUozJ9KtVWILnOlX2YanAg6hfVgibJMQKGJnx0BLMDJTfSF2QCGGweMn38f1Qa29nAO8pLRdFV+XCWwfUeQY+MSwfCYqtq6YwCHvyjQCNFYq8wgQRltVU6AN9sNpCqGTBiuhLGDd0D7Qc6R+PR5ae80wH4SYLgC4lBxEBesK/JY+8L3EDowRhSxdDuFYTSRxk9o+B+/S2oUa4pZqRhMMXQ/qnW7UVC7V9TCIeEgMmiMJWyt2evPV8KEaWzJXcH9WOTYZOThEsnWjOIVYr/klmjrnbNp7I/80jEC0MxGQxLvaskCgYEAyvcgk3KR37rhhEivh9PwLH2UphWg9UtUbyooMGXJRiANyZT710IcsTek/Be9BeCzqxL/m8LUBKp+iMs+JMSr/6XjkLUCX59vXAgpQzr+nPTdX3drkZWzh1w0i9jnKROcnCyBB2QVJAQl+ylbFrtQGIEYzcO1wUZlEJ8lbAo2DpUCgYEAsnAMzoySKfr4i6tuv5tnu55R3N3QvlmUzq0P7xAMjcVtdlNTOtxIB98uFTq9dEYxV2nydMjAJ8YUyiQ/02pSAzmi7uIzqaz39/Bbj2Q1AzTkAuzJdWR5i2Eo6eyyVhyLDCLbRzsZZoW3tS0dS2ypRy/RM686E9PzXhe78x74LPsCgYAver4pH/0V7F7DFknRqXeewMXcUGT13OhklOUP5U+/UtJG3M5JHdMeddjnjBoQ3O7Kz0fyRRJaARRWpczkxwlBZaoleOKUQfTH/7S/YHadev6qTYJhbTaxLJWyPUxeJJNXSWXpt7TmVv4XkiYX3Duxb8nAoM7M5s3PpJsZeg4JPQKBgA6rf6ILlIi3BXAWLAi8sg6OuZQ6+Ept+vny6HhzDVUqghFUUGdqbNGY26ULK0A/9RaGs1Q+nO2oL1VfHZA4EX4KYwbYuf6dJdXQgPaM+n7E/mnvJbDtDcETv9VbjF3gAt6Ajx6QEUqIe839Y4cr687ac4yYP2IZ7swxj1YxmZ25AoGBALlyVn1DWAia3JekmcQhkPOOPEhLo9qHhdU5Bt8ZUQUXmiQGShw+2g6LjwEvXts09s2ElZCykvWuz/mYPRZAhNsikszqfQrdsZydfDc1BrwABgkjjZeVuCLDyLD9cV6oJiTSYLoaIDPpnxTWSawcduMZDrVYtC2BuOPAeQVSH/ME" ],
-        "certificate" : [ "MIICmTCCAYECBgF/QSDAnTANBgkqhkiG9w0BAQsFADAQMQ4wDAYDVQQDDAVub21hZDAeFw0yMjAyMjgxNjE3MTlaFw0zMjAyMjgxNjE4NTlaMBAxDjAMBgNVBAMMBW5vbWFkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAjXiq7B4BtXCfyh3o+DJ7JjXDbTk1unIqUCrFV/ojjPUw70dfZ3oUoqiW1mcyXg0dlElCbgReZzKQf93MTyzkxapHJyHSEjppxafIkmYh9LS8WEHiGjuzDz2Gp0ITrl7OzBhtU3JYXnZbcmhiGh6V6FmCCX6vp2jAZmmcJmGD7EW26Rk6LkYQovPHYNzFCvst212mPpdLjuHhqyv1OcGWqSTWgxsf0jP//Pu5Y3kCSWut8aDvI/3rHHvk821MHTSWndweVLmgQKGDhLmKkiF0WBLgdl3cd5pDk3FfgUkchyvaZWKO2dW6FrUuciKuAngNdmLo3ZyzACnDrisx49noFwIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQAjCDiS5p59kOKonyNsBKMBu+QNrvmtQP1oZ38pjErd9KorJOXg3fDp2at0nnwb/XhhHGDlptDZz3HjFZNy0ZEZZFvLshsOT8hrXUMaFe7lVChjCNuRbRRiDC0OzmDIxpVb7hytLhsn5Z7Ib9V0+itbifi0nE2i/DOZDyat1HbzhTV3bNWA1u4mQfLDAN7Rw2Cek/Iej/lTEjkyQ2HL6Bb04Xqdbf+Hyg4Juk2w05ndGYfQ9egMu/YjeqnEstGU5N3gL6wte6LnlRj5JHm6synYZIESIv6E2bI4z5uCBrnxw8R0LuavEZgQecmZWLVFkKfF//RSQHiyx7LzYDsPMMJg" ],
-        "priority" : [ "100" ]
-      }
-    }, {
-      "id" : "d1a2ce66-0873-40b3-a242-d9205bd573ba",
-      "name" : "rsa-enc-generated",
-      "providerId" : "rsa-enc-generated",
-      "subComponents" : { },
-      "config" : {
-        "privateKey" : [ "MIIEpAIBAAKCAQEApEVFqx8g1GFfYXcXY2Cx0cSEwelAjFAQG2qrbYJ9c+5Rjvilylb8JWXMB3J68uupSBXdULtHeTTsVHU5BGmx+SQauN01nT427HVB3uKd9LlK3xEIHZoYBnzq8p6maumCpPM+ULI3jmtFutCSfalIN80NW3+KVsAF9Va0CXhrhA62bZYaeZ28CN2/XTpZbCfVtfePggA28G9ooIe6O2V3Qb05M83gxBA7ySgkX6UEnc2x3L4nMN9kEzu7OpBM9wPSnQtaSCLIy+qrKzY3iAgieb6eC17MmvJXpJD9X/hnDJ5FmOAI7EtEBT29hYPkOuwlwIo1kTBwLaf6PZGIgOVJDQIDAQABAoIBAFfhq2zp4VFdqn5lDQEgeOElRnTLCbpHFubkAUQ73EvKQp2/TkrakFidhjKxvy74fn7PG7CWEJ26f3iLoe5HcWw9MYKW7Zjq8M09yfiouiJzgqel3/aeOp419CfKUnO96yO98iePwIMTxqEz9jr99mHL9IpvyB2y6z0enoC2iKaDrLeJjtveLRI94ZvhCY0vzU3qUSRLn11R54U+yko6Pw2WaqloskuauUz3EtEXsHG6TyYwxwDSL+nrMokgn+8imj9ZVRCnVcYSdmuDc3xVJ6siMkiVcfeqBrskSaDN+ib45SK/AjWJbRoQKhOgY4IBuoqWEyW9NKiYbFEe0VM4KGECgYEA+iRddfBrBEz+ogVKNNs9MWo6bhLy6AWz27/JkkgWPGW9/TBx4cg76ZWAkNFBXhE7YxWfNoS3XjZXof2Arkc962O3IkK1PLZMQE3SqiitqeHoNz6Gw8TkiT2RhF87pHSbt1Ik+VXd4z6J5TYwDCZbue3GOZFRX3gTlsM/JuSx4FUCgYEAqB4YoxgrciADReXrYumXaF+/cd0CBcUzXN56H56FFYyy2dorLDM4CCqN2sY/8wen3OJqJRBppNqCiCWXtpQ+BLU/L/P9JrMGLSM40PMysTFU9rkLRdjhMrl7yI1+Df11H66jXh6EMrMjwyMKR6UxFKmLM7vRd4RHZs2pK/NindkCgYEAmVI03xdv4QD4ioLHi0Jeba15BwMiVEk6hxU1Di6VQovyOgC5rPS4lGIInbtFX80cI42bOyV554tTh30EpM4SC/fgxmUxBXePoVKSL64jVB+d4E6498H1epF8YjClNBYtY947v4B8Ms+gYhgmtyvDyWEOwTZrNCM7jos6aDKBPMkCgYAmrl4O0JXWeWUnZQJmzMZIfpdG9Intl/T8bjf9JHUMg0X3eAos7k/7GQdwieLW4TEPUo0HoCIeiyQzfSrOGIe4f5ddSi86A0Dti8gb04kbWfVpmyPr2z3ddO31NBEH2QRk2MK/+heCrtMQp/RKjcigL25W5eUJMcdX8QP2l9Zd6QKBgQDZguHPF4QNIeTREiE3EUnjonahhX+lIk9vaH5LjPblsNqAyt2R6W4WkKfdUBG9wQDw2gc5NdbXA6vwpDZixNPivJFlnQc86ZsGc+S+OdMv+sZDUPWqcHHQW2ZZxNC/G/hiL5yRerN4qy1B0NRjTireUf35/F3UJW3eEAxT+YKgCw==" ],
-        "certificate" : [ "MIICmTCCAYECBgF/QSDBBTANBgkqhkiG9w0BAQsFADAQMQ4wDAYDVQQDDAVub21hZDAeFw0yMjAyMjgxNjE3MTlaFw0zMjAyMjgxNjE4NTlaMBAxDjAMBgNVBAMMBW5vbWFkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApEVFqx8g1GFfYXcXY2Cx0cSEwelAjFAQG2qrbYJ9c+5Rjvilylb8JWXMB3J68uupSBXdULtHeTTsVHU5BGmx+SQauN01nT427HVB3uKd9LlK3xEIHZoYBnzq8p6maumCpPM+ULI3jmtFutCSfalIN80NW3+KVsAF9Va0CXhrhA62bZYaeZ28CN2/XTpZbCfVtfePggA28G9ooIe6O2V3Qb05M83gxBA7ySgkX6UEnc2x3L4nMN9kEzu7OpBM9wPSnQtaSCLIy+qrKzY3iAgieb6eC17MmvJXpJD9X/hnDJ5FmOAI7EtEBT29hYPkOuwlwIo1kTBwLaf6PZGIgOVJDQIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQBXsiFpxSgZuinNZi+WFcrx9bAwwNeWm99xsvKMn0H6CaKzkI8g8rWE+6MYtPDRTEJS/pyF/ciDxuoj7clJRmkztic1lSXQDEsCvp6tOxJbB0Al7TqXWXvA7cIwcVVwexAacDMS8HGkaHljZQFLpcGqFChVAPClo1hasTzBJFqvmEH+wduE3WFVXnt09Svssm5Qffq5Zhbe6QjwPwQ6t5DnMfv1r9qexInbehJraW7yzSWNAxzgWJ+g1jTfwjU2aPhcs46AbY1Z+tlFkoGPbn3BjY9QKP9tDxOSGD6zWUhjUb6Sq3kpC2KBKRq5ct1U+Cj5ZtQAEIF9rJBBZH7o2jhb" ],
-        "priority" : [ "100" ],
-        "algorithm" : [ "RSA-OAEP" ]
-      }
-    }, {
-      "id" : "13eb673f-c2aa-4fac-abda-a198ef88d2ab",
-      "name" : "aes-generated",
-      "providerId" : "aes-generated",
-      "subComponents" : { },
-      "config" : {
-        "kid" : [ "ca6841b9-fd34-4871-b891-7a6b90cf91f9" ],
-        "secret" : [ "0zDqA_iJFKXPulZT-0Sc1A" ],
-        "priority" : [ "100" ]
-      }
-    } ]
-  },
-  "internationalizationEnabled" : false,
-  "supportedLocales" : [ ],
-  "authenticationFlows" : [ {
-    "id" : "84a1df97-5c7e-49af-a0fa-b09d9fa11a61",
-    "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,
-      "userSetupAllowed" : false,
-      "autheticatorFlow" : false
-    }, {
-      "authenticatorFlow" : true,
-      "requirement" : "ALTERNATIVE",
-      "priority" : 20,
-      "flowAlias" : "Verify Existing Account by Re-authentication",
-      "userSetupAllowed" : false,
-      "autheticatorFlow" : true
-    } ]
-  }, {
-    "id" : "b68325e8-161c-4f73-acdc-a5f1f85c4c5a",
-    "alias" : "Authentication Options",
-    "description" : "Authentication options.",
-    "providerId" : "basic-flow",
-    "topLevel" : false,
-    "builtIn" : true,
-    "authenticationExecutions" : [ {
-      "authenticator" : "basic-auth",
-      "authenticatorFlow" : false,
-      "requirement" : "REQUIRED",
-      "priority" : 10,
-      "userSetupAllowed" : false,
-      "autheticatorFlow" : false
-    }, {
-      "authenticator" : "basic-auth-otp",
-      "authenticatorFlow" : false,
-      "requirement" : "DISABLED",
-      "priority" : 20,
-      "userSetupAllowed" : false,
-      "autheticatorFlow" : false
-    }, {
-      "authenticator" : "auth-spnego",
-      "authenticatorFlow" : false,
-      "requirement" : "DISABLED",
-      "priority" : 30,
-      "userSetupAllowed" : false,
-      "autheticatorFlow" : false
-    } ]
-  }, {
-    "id" : "04aa1aff-cb73-43a0-95a0-e80c7016cc9a",
-    "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,
-      "userSetupAllowed" : false,
-      "autheticatorFlow" : false
-    }, {
-      "authenticator" : "auth-otp-form",
-      "authenticatorFlow" : false,
-      "requirement" : "REQUIRED",
-      "priority" : 20,
-      "userSetupAllowed" : false,
-      "autheticatorFlow" : false
-    } ]
-  }, {
-    "id" : "1404fe20-c960-474a-a336-32fbc15c1c8e",
-    "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,
-      "userSetupAllowed" : false,
-      "autheticatorFlow" : false
-    }, {
-      "authenticator" : "direct-grant-validate-otp",
-      "authenticatorFlow" : false,
-      "requirement" : "REQUIRED",
-      "priority" : 20,
-      "userSetupAllowed" : false,
-      "autheticatorFlow" : false
-    } ]
-  }, {
-    "id" : "66724cac-7ae8-4ea0-89f2-122092e9f937",
-    "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,
-      "userSetupAllowed" : false,
-      "autheticatorFlow" : false
-    }, {
-      "authenticator" : "auth-otp-form",
-      "authenticatorFlow" : false,
-      "requirement" : "REQUIRED",
-      "priority" : 20,
-      "userSetupAllowed" : false,
-      "autheticatorFlow" : false
-    } ]
-  }, {
-    "id" : "ac70d6b0-e66e-4e55-bde6-f27e644c79d4",
-    "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,
-      "userSetupAllowed" : false,
-      "autheticatorFlow" : false
-    }, {
-      "authenticatorFlow" : true,
-      "requirement" : "REQUIRED",
-      "priority" : 20,
-      "flowAlias" : "Account verification options",
-      "userSetupAllowed" : false,
-      "autheticatorFlow" : true
-    } ]
-  }, {
-    "id" : "eee7ba09-70c4-45f8-8e82-12ac52583845",
-    "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,
-      "userSetupAllowed" : false,
-      "autheticatorFlow" : false
-    }, {
-      "authenticator" : "reset-otp",
-      "authenticatorFlow" : false,
-      "requirement" : "REQUIRED",
-      "priority" : 20,
-      "userSetupAllowed" : false,
-      "autheticatorFlow" : false
-    } ]
-  }, {
-    "id" : "e656fb93-625e-475a-957c-7e2f09ed13b2",
-    "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,
-      "userSetupAllowed" : false,
-      "autheticatorFlow" : false
-    }, {
-      "authenticatorFlow" : true,
-      "requirement" : "ALTERNATIVE",
-      "priority" : 20,
-      "flowAlias" : "Handle Existing Account",
-      "userSetupAllowed" : false,
-      "autheticatorFlow" : true
-    } ]
-  }, {
-    "id" : "bcf932f5-b991-491f-94fd-21e8f3a2d9e9",
-    "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,
-      "userSetupAllowed" : false,
-      "autheticatorFlow" : false
-    }, {
-      "authenticatorFlow" : true,
-      "requirement" : "CONDITIONAL",
-      "priority" : 20,
-      "flowAlias" : "First broker login - Conditional OTP",
-      "userSetupAllowed" : false,
-      "autheticatorFlow" : true
-    } ]
-  }, {
-    "id" : "3c27f1b2-4de0-43fb-9dd6-b9cfc7ea261b",
-    "alias" : "browser",
-    "description" : "browser based authentication",
-    "providerId" : "basic-flow",
-    "topLevel" : true,
-    "builtIn" : true,
-    "authenticationExecutions" : [ {
-      "authenticator" : "auth-cookie",
-      "authenticatorFlow" : false,
-      "requirement" : "ALTERNATIVE",
-      "priority" : 10,
-      "userSetupAllowed" : false,
-      "autheticatorFlow" : false
-    }, {
-      "authenticator" : "auth-spnego",
-      "authenticatorFlow" : false,
-      "requirement" : "DISABLED",
-      "priority" : 20,
-      "userSetupAllowed" : false,
-      "autheticatorFlow" : false
-    }, {
-      "authenticator" : "identity-provider-redirector",
-      "authenticatorFlow" : false,
-      "requirement" : "ALTERNATIVE",
-      "priority" : 25,
-      "userSetupAllowed" : false,
-      "autheticatorFlow" : false
-    }, {
-      "authenticatorFlow" : true,
-      "requirement" : "ALTERNATIVE",
-      "priority" : 30,
-      "flowAlias" : "forms",
-      "userSetupAllowed" : false,
-      "autheticatorFlow" : true
-    } ]
-  }, {
-    "id" : "698ec8c5-6614-4c49-8a66-aff08c9e4e98",
-    "alias" : "clients",
-    "description" : "Base authentication for clients",
-    "providerId" : "client-flow",
-    "topLevel" : true,
-    "builtIn" : true,
-    "authenticationExecutions" : [ {
-      "authenticator" : "client-secret",
-      "authenticatorFlow" : false,
-      "requirement" : "ALTERNATIVE",
-      "priority" : 10,
-      "userSetupAllowed" : false,
-      "autheticatorFlow" : false
-    }, {
-      "authenticator" : "client-jwt",
-      "authenticatorFlow" : false,
-      "requirement" : "ALTERNATIVE",
-      "priority" : 20,
-      "userSetupAllowed" : false,
-      "autheticatorFlow" : false
-    }, {
-      "authenticator" : "client-secret-jwt",
-      "authenticatorFlow" : false,
-      "requirement" : "ALTERNATIVE",
-      "priority" : 30,
-      "userSetupAllowed" : false,
-      "autheticatorFlow" : false
-    }, {
-      "authenticator" : "client-x509",
-      "authenticatorFlow" : false,
-      "requirement" : "ALTERNATIVE",
-      "priority" : 40,
-      "userSetupAllowed" : false,
-      "autheticatorFlow" : false
-    } ]
-  }, {
-    "id" : "6f4d39fb-87d7-4f90-8fdf-4409e503abcc",
-    "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,
-      "userSetupAllowed" : false,
-      "autheticatorFlow" : false
-    }, {
-      "authenticator" : "direct-grant-validate-password",
-      "authenticatorFlow" : false,
-      "requirement" : "REQUIRED",
-      "priority" : 20,
-      "userSetupAllowed" : false,
-      "autheticatorFlow" : false
-    }, {
-      "authenticatorFlow" : true,
-      "requirement" : "CONDITIONAL",
-      "priority" : 30,
-      "flowAlias" : "Direct Grant - Conditional OTP",
-      "userSetupAllowed" : false,
-      "autheticatorFlow" : true
-    } ]
-  }, {
-    "id" : "c2f6d3b3-9601-4a57-9d08-8b8e8b041c16",
-    "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,
-      "userSetupAllowed" : false,
-      "autheticatorFlow" : false
-    } ]
-  }, {
-    "id" : "4b367e11-18d6-444d-b3f2-82d380db0380",
-    "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,
-      "userSetupAllowed" : false,
-      "autheticatorFlow" : false
-    }, {
-      "authenticatorFlow" : true,
-      "requirement" : "REQUIRED",
-      "priority" : 20,
-      "flowAlias" : "User creation or linking",
-      "userSetupAllowed" : false,
-      "autheticatorFlow" : true
-    } ]
-  }, {
-    "id" : "9100bd6f-54dd-49cf-8383-3261a225d860",
-    "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,
-      "userSetupAllowed" : false,
-      "autheticatorFlow" : false
-    }, {
-      "authenticatorFlow" : true,
-      "requirement" : "CONDITIONAL",
-      "priority" : 20,
-      "flowAlias" : "Browser - Conditional OTP",
-      "userSetupAllowed" : false,
-      "autheticatorFlow" : true
-    } ]
-  }, {
-    "id" : "e4628a1f-7766-45a5-9927-14c97f2453ab",
-    "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,
-      "userSetupAllowed" : false,
-      "autheticatorFlow" : false
-    }, {
-      "authenticatorFlow" : true,
-      "requirement" : "REQUIRED",
-      "priority" : 20,
-      "flowAlias" : "Authentication Options",
-      "userSetupAllowed" : false,
-      "autheticatorFlow" : true
-    } ]
-  }, {
-    "id" : "4d2291c7-6419-4e3c-924e-b9fa2126fed4",
-    "alias" : "registration",
-    "description" : "registration flow",
-    "providerId" : "basic-flow",
-    "topLevel" : true,
-    "builtIn" : true,
-    "authenticationExecutions" : [ {
-      "authenticator" : "registration-page-form",
-      "authenticatorFlow" : true,
-      "requirement" : "REQUIRED",
-      "priority" : 10,
-      "flowAlias" : "registration form",
-      "userSetupAllowed" : false,
-      "autheticatorFlow" : true
-    } ]
-  }, {
-    "id" : "4c65809b-958a-4896-bc43-fe6a61978ae0",
-    "alias" : "registration form",
-    "description" : "registration form",
-    "providerId" : "form-flow",
-    "topLevel" : false,
-    "builtIn" : true,
-    "authenticationExecutions" : [ {
-      "authenticator" : "registration-user-creation",
-      "authenticatorFlow" : false,
-      "requirement" : "REQUIRED",
-      "priority" : 20,
-      "userSetupAllowed" : false,
-      "autheticatorFlow" : false
-    }, {
-      "authenticator" : "registration-profile-action",
-      "authenticatorFlow" : false,
-      "requirement" : "REQUIRED",
-      "priority" : 40,
-      "userSetupAllowed" : false,
-      "autheticatorFlow" : false
-    }, {
-      "authenticator" : "registration-password-action",
-      "authenticatorFlow" : false,
-      "requirement" : "REQUIRED",
-      "priority" : 50,
-      "userSetupAllowed" : false,
-      "autheticatorFlow" : false
-    }, {
-      "authenticator" : "registration-recaptcha-action",
-      "authenticatorFlow" : false,
-      "requirement" : "DISABLED",
-      "priority" : 60,
-      "userSetupAllowed" : false,
-      "autheticatorFlow" : false
-    } ]
-  }, {
-    "id" : "47ba43c5-7234-45b8-acf7-5ef4e2d17ff1",
-    "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,
-      "userSetupAllowed" : false,
-      "autheticatorFlow" : false
-    }, {
-      "authenticator" : "reset-credential-email",
-      "authenticatorFlow" : false,
-      "requirement" : "REQUIRED",
-      "priority" : 20,
-      "userSetupAllowed" : false,
-      "autheticatorFlow" : false
-    }, {
-      "authenticator" : "reset-password",
-      "authenticatorFlow" : false,
-      "requirement" : "REQUIRED",
-      "priority" : 30,
-      "userSetupAllowed" : false,
-      "autheticatorFlow" : false
-    }, {
-      "authenticatorFlow" : true,
-      "requirement" : "CONDITIONAL",
-      "priority" : 40,
-      "flowAlias" : "Reset - Conditional OTP",
-      "userSetupAllowed" : false,
-      "autheticatorFlow" : true
-    } ]
-  }, {
-    "id" : "d9d46b17-fef3-44ba-ab2c-cd937b90c59e",
-    "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,
-      "userSetupAllowed" : false,
-      "autheticatorFlow" : false
-    } ]
-  } ],
-  "authenticatorConfig" : [ {
-    "id" : "2e3a90b3-e860-4d4f-9a4a-bff169e1a185",
-    "alias" : "create unique user config",
-    "config" : {
-      "require.password.update.after.registration" : "false"
-    }
-  }, {
-    "id" : "509b7231-830f-46ca-950f-2f38f4835b81",
-    "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" : 10,
-    "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" : 30,
-    "config" : { }
-  }, {
-    "alias" : "UPDATE_PROFILE",
-    "name" : "Update Profile",
-    "providerId" : "UPDATE_PROFILE",
-    "enabled" : true,
-    "defaultAction" : false,
-    "priority" : 40,
-    "config" : { }
-  }, {
-    "alias" : "VERIFY_EMAIL",
-    "name" : "Verify Email",
-    "providerId" : "VERIFY_EMAIL",
-    "enabled" : true,
-    "defaultAction" : false,
-    "priority" : 50,
-    "config" : { }
-  }, {
-    "alias" : "delete_account",
-    "name" : "Delete Account",
-    "providerId" : "delete_account",
-    "enabled" : false,
-    "defaultAction" : false,
-    "priority" : 60,
-    "config" : { }
-  }, {
-    "alias" : "update_user_locale",
-    "name" : "Update User Locale",
-    "providerId" : "update_user_locale",
-    "enabled" : true,
-    "defaultAction" : false,
-    "priority" : 1000,
-    "config" : { }
-  } ],
-  "browserFlow" : "browser",
-  "registrationFlow" : "registration",
-  "directGrantFlow" : "direct grant",
-  "resetCredentialsFlow" : "reset credentials",
-  "clientAuthenticationFlow" : "clients",
-  "dockerAuthenticationFlow" : "docker auth",
-  "attributes" : {
-    "cibaBackchannelTokenDeliveryMode" : "poll",
-    "cibaExpiresIn" : "120",
-    "cibaAuthRequestedUserHint" : "login_hint",
-    "oauth2DeviceCodeLifespan" : "600",
-    "clientOfflineSessionMaxLifespan" : "0",
-    "oauth2DevicePollingInterval" : "5",
-    "clientSessionIdleTimeout" : "0",
-    "parRequestUriLifespan" : "60",
-    "clientSessionMaxLifespan" : "0",
-    "clientOfflineSessionIdleTimeout" : "0",
-    "cibaInterval" : "5"
-  },
-  "keycloakVersion" : "16.1.1",
-  "userManagedAccessAllowed" : false,
-  "clientProfiles" : {
-    "profiles" : [ ]
-  },
-  "clientPolicies" : {
-    "policies" : [ ]
-  }
-}
\ No newline at end of file
diff --git a/ops/docker-compose/nomad-oasis/.gitignore b/ops/docker-compose/nomad-oasis/.gitignore
new file mode 100644
index 0000000000..2ad6b83594
--- /dev/null
+++ b/ops/docker-compose/nomad-oasis/.gitignore
@@ -0,0 +1,14 @@
+.volumes/fs/north/*/*
+!.volumes/fs/north/*/.empty
+
+.volumes/fs/public/*
+!.volumes/fs/public/.empty
+
+.volumes/fs/staging/*
+!.volumes/fs/staging/.empty
+
+.volumes/fs/tmp/*
+!.volumes/fs/tmp/.empty
+
+.volumes/mongo/*
+!.volumes/mongo/.empty
\ No newline at end of file
diff --git a/ops/docker-compose/nomad-oasis/.volumes/fs/north/shared/.empty b/ops/docker-compose/nomad-oasis/.volumes/fs/north/shared/.empty
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/ops/docker-compose/nomad-oasis/.volumes/fs/north/users/.empty b/ops/docker-compose/nomad-oasis/.volumes/fs/north/users/.empty
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/ops/docker-compose/nomad-oasis/.volumes/fs/public/.empty b/ops/docker-compose/nomad-oasis/.volumes/fs/public/.empty
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/ops/docker-compose/nomad-oasis/.volumes/fs/staging/.empty b/ops/docker-compose/nomad-oasis/.volumes/fs/staging/.empty
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/ops/docker-compose/nomad-oasis/.volumes/fs/tmp/.empty b/ops/docker-compose/nomad-oasis/.volumes/fs/tmp/.empty
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/ops/docker-compose/nomad-oasis/.volumes/mongo/.empty b/ops/docker-compose/nomad-oasis/.volumes/mongo/.empty
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/ops/docker-compose/nomad-oasis-with-keycloak/docker-compose.yml b/ops/docker-compose/nomad-oasis/docker-compose-with-keycloak.yaml
similarity index 96%
rename from ops/docker-compose/nomad-oasis-with-keycloak/docker-compose.yml
rename to ops/docker-compose/nomad-oasis/docker-compose-with-keycloak.yaml
index 587e77f53f..d4e9af56c2 100644
--- a/ops/docker-compose/nomad-oasis-with-keycloak/docker-compose.yml
+++ b/ops/docker-compose/nomad-oasis/docker-compose-with-keycloak.yaml
@@ -60,7 +60,7 @@ services:
     # nomad worker (processing)
     worker:
         restart: always
-        image: gitlab-registry.mpcdf.mpg.de/nomad-lab/nomad-fair:v1.1.0
+        image: gitlab-registry.mpcdf.mpg.de/nomad-lab/nomad-fair:v1.1.1
         container_name: nomad_oasis_worker
         environment:
             <<: *nomad_backend_env
@@ -78,12 +78,13 @@ services:
     # nomad app (api + gui)
     app:
         restart: always
-        image: gitlab-registry.mpcdf.mpg.de/nomad-lab/nomad-fair:v1.1.0
+        image: gitlab-registry.mpcdf.mpg.de/nomad-lab/nomad-fair:v1.1.1
         container_name: nomad_oasis_app
         environment:
             <<: *nomad_backend_env
             NOMAD_SERVICE: nomad_oasis_app
             NOMAD_SERVICES_API_PORT: 80
+            NOMAD_FS_EXTERNAL_WORKING_DIRECTORY: '$PWD'
         links:
             - rabbitmq
             - elastic
@@ -97,7 +98,7 @@ services:
     # nomad remote tools hub (JupyterHUB, e.g. for AI Toolkit)
     hub:
         restart: always
-        image: gitlab-registry.mpcdf.mpg.de/nomad-lab/nomad-fair:v1.1.0
+        image: gitlab-registry.mpcdf.mpg.de/nomad-lab/nomad-fair:v1.1.1
         container_name: nomad_oasis_hub
         environment:
             <<: *nomad_backend_env
@@ -107,6 +108,7 @@ services:
             NOMAD_NORTH_HUB_IP: '0.0.0.0'
             NOMAD_NORTH_HUB_HOST: 'hub'
             NOMAD_SERVICES_API_HOST: app
+            NOMAD_FS_EXTERNAL_WORKING_DIRECTORY: '$PWD'
         links:
             - app
         volumes:
@@ -114,7 +116,7 @@ services:
             - /var/run/docker.sock:/var/run/docker.sock
             - ./.volumes/fs:/app/.volumes/fs
         command: python -m nomad.cli admin run hub
-        user: "1000:991"
+        user: 1000:991
 
     # nomad gui (a reverse proxy for nomad)
     gui:
diff --git a/ops/docker-compose/nomad-oasis/docker-compose.yaml b/ops/docker-compose/nomad-oasis/docker-compose.yaml
index 3519cb71fb..f8d9024c37 100644
--- a/ops/docker-compose/nomad-oasis/docker-compose.yaml
+++ b/ops/docker-compose/nomad-oasis/docker-compose.yaml
@@ -46,7 +46,7 @@ services:
     # nomad worker (processing)
     worker:
         restart: always
-        image: gitlab-registry.mpcdf.mpg.de/nomad-lab/nomad-fair:v1.1.0
+        image: gitlab-registry.mpcdf.mpg.de/nomad-lab/nomad-fair:v1.1.1
         container_name: nomad_oasis_worker
         environment:
             <<: *nomad_backend_env
@@ -63,12 +63,13 @@ services:
     # nomad app (api + gui)
     app:
         restart: always
-        image: gitlab-registry.mpcdf.mpg.de/nomad-lab/nomad-fair:v1.1.0
+        image: gitlab-registry.mpcdf.mpg.de/nomad-lab/nomad-fair:v1.1.1
         container_name: nomad_oasis_app
         environment:
             <<: *nomad_backend_env
             NOMAD_SERVICE: nomad_oasis_app
             NOMAD_SERVICES_API_PORT: 80
+            NOMAD_FS_EXTERNAL_WORKING_DIRECTORY: '$PWD'
         links:
             - rabbitmq
             - elastic
@@ -81,24 +82,26 @@ services:
     # nomad remote tools hub (JupyterHUB, e.g. for AI Toolkit)
     hub:
         restart: always
-        image: gitlab-registry.mpcdf.mpg.de/nomad-lab/nomad-fair:v1.1.0
+        image: gitlab-registry.mpcdf.mpg.de/nomad-lab/nomad-fair:v1.1.1
         container_name: nomad_oasis_hub
         environment:
             <<: *nomad_backend_env
             NOMAD_SERVICE: nomad_oasis_hub
-            NOMAD_NORTH_DOCKER_NETWORK: nomad_oasis_network
+            NOMAD_NORTH_DOCKER_NETWORK: nomad_oasis_north_network
             NOMAD_NORTH_HUB_IP_CONNECT: hub
             NOMAD_NORTH_HUB_IP: '0.0.0.0'
             NOMAD_NORTH_HUB_HOST: 'hub'
             NOMAD_SERVICES_API_HOST: app
+            NOMAD_FS_EXTERNAL_WORKING_DIRECTORY: '$PWD'
         links:
             - app
         volumes:
             - ./nomad.yaml:/app/nomad.yaml
             - /var/run/docker.sock:/var/run/docker.sock
             - ./.volumes/fs:/app/.volumes/fs
+        networks: ['defautl', 'north']
         command: python -m nomad.cli admin run hub
-        user: "1000:991"
+        user: 1000:991
 
     # nomad gui (a reverse proxy for nomad)
     gui:
@@ -122,4 +125,6 @@ volumes:
 
 networks:
     default:
-        name: nomad_oasis_network
\ No newline at end of file
+        name: nomad_oasis_network
+    north:
+        name: nomad_oasis_north_network
diff --git a/ops/docker-compose/nomad-oasis-with-keycloak/nginx.conf b/ops/docker-compose/nomad-oasis/nginx-with-keycloak.conf
similarity index 100%
rename from ops/docker-compose/nomad-oasis-with-keycloak/nginx.conf
rename to ops/docker-compose/nomad-oasis/nginx-with-keycloak.conf
diff --git a/ops/docker-compose/nomad-oasis/nginx.conf b/ops/docker-compose/nomad-oasis/nginx.conf
index 6b321a1bff..407acc03e8 100644
--- a/ops/docker-compose/nomad-oasis/nginx.conf
+++ b/ops/docker-compose/nomad-oasis/nginx.conf
@@ -47,7 +47,7 @@ server {
         proxy_pass http://app:8000;
     }
 
-    location ~ /hub/ {
+    location ~ /north/ {
         proxy_pass http://hub:9000;
 
         proxy_set_header X-Real-IP $remote_addr;
@@ -62,4 +62,4 @@ server {
 
         proxy_buffering off;
     }
-}
\ No newline at end of file
+}
diff --git a/ops/docker-compose/nomad-oasis-with-keycloak/nomad.yaml b/ops/docker-compose/nomad-oasis/nomad-with-keycloak.yaml
similarity index 95%
rename from ops/docker-compose/nomad-oasis-with-keycloak/nomad.yaml
rename to ops/docker-compose/nomad-oasis/nomad-with-keycloak.yaml
index e99d50eae4..b4ea004017 100644
--- a/ops/docker-compose/nomad-oasis-with-keycloak/nomad.yaml
+++ b/ops/docker-compose/nomad-oasis/nomad-with-keycloak.yaml
@@ -8,6 +8,7 @@ oasis:
 
 north:
   jupyterhub_crypt_key: '978bfb2e13a8448a253c629d8dd84ff89587f30e635b753153960930cad9d36d'
+  hub_ip_connect: '172.17.0.1'
 
 keycloak:
   server_url: 'http://keycloak:8080/auth/'
diff --git a/ops/docker-compose/nomad-oasis/nomad.yaml b/ops/docker-compose/nomad-oasis/nomad.yaml
index 27cc366f2a..02156b446a 100644
--- a/ops/docker-compose/nomad-oasis/nomad.yaml
+++ b/ops/docker-compose/nomad-oasis/nomad.yaml
@@ -16,8 +16,8 @@ meta:
   maintainer_email: 'me@my-oasis.org'
 
 mongo:
-    db_name: nomad_v1
+    db_name: nomad_oasis_v1
 
 elastic:
-    entries_index: nomad_v1_entries
-    materials_index: nomad_v1_materials
\ No newline at end of file
+    entries_index: nomad_oasis_entries_v1
+    materials_index: nomad_oasis_materials_v1
\ No newline at end of file
-- 
GitLab