Add basic Keycloak setup
diff --git a/docker-compose.yml b/docker-compose.yml
index 148b0c3..65dccaf 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -14,6 +14,7 @@
       - "80:80"
       - "443:443"
     networks:
+      - kcnet
       - simpleidnet
       - gerritnet
     volumes:
@@ -34,6 +35,30 @@
       - ./postgres/init.sh:/docker-entrypoint-initdb.d/init.sh:ro
       - ./postgres/data/:/var/lib/postgresql/data/:rw
       - ./postgres/passwd/:/tmp/passwd/:rw
+  keycloak:
+    build:
+      context: ./keycloak/docker/
+      args:
+        - KC_DB=postgres
+    networks:
+      - kcnet
+      - dbnet
+    env_file: environment
+    environment:
+      - KC_PROXY=edge
+      - KC_HOSTNAME_DEBUG=true
+      - KC_HOSTNAME_STRICT=true
+      - KC_HOSTNAME_STRICT_BACKCHANNEL=true
+      - KC_HOSTNAME_URL=https://id.${SA_PUBLIC_DOMAIN_NAME}/
+      - KC_HOSTNAME_ADMIN_URL=https://id.${SA_PUBLIC_DOMAIN_NAME}/
+      - KC_DB_USERNAME=keycloak
+      - KC_DB_URL_HOST=postgres
+      - KC_DB_URL=jdbc:postgresql://postgres/keycloak
+      - KC_DB_POOL_MAX_SIZE=16
+      - KEYCLOAK_ADMIN=deusarcadia
+      - KEYCLOAK_ADMIN_PASSWORD=arcanumhomini
+    volumes:
+      - ./postgres/passwd/keycloak/:/tmp/passwd/db/:ro
   simpleid:
     build:
       context: .
@@ -88,6 +113,7 @@
       - "993:993"  # IMAP4 (implicit TLS)
     networks:
       - gerritnet
+      - kcnet
     volumes:
       - ./logs/mail-supervisor/:/var/log/supervisor/:rw
       - ./logs/mail/:/var/log/mail/:rw
@@ -123,3 +149,8 @@
     ipam:
       config:
         - subnet: 10.12.14.40/29
+  kcnet:
+    driver: bridge
+    ipam:
+      config:
+        - subnet: 10.12.14.48/29
diff --git a/keycloak/docker/Dockerfile b/keycloak/docker/Dockerfile
new file mode 100644
index 0000000..84c07dd
--- /dev/null
+++ b/keycloak/docker/Dockerfile
@@ -0,0 +1,27 @@
+ARG KC_TAG=22.0
+FROM quay.io/keycloak/keycloak:${KC_TAG} as builder
+
+# Enable health and metrics support
+ENV KC_HEALTH_ENABLED=true
+ENV KC_METRICS_ENABLED=true
+
+ARG KC_DB=
+RUN test "${KC_DB}" || { echo \${KC_DB} must be set!; exit 1; }
+
+WORKDIR /opt/keycloak
+# for demonstration purposes only, please make sure to use proper certificates in production instead
+RUN keytool -genkeypair -storepass password -storetype PKCS12 -keyalg RSA -keysize 2048 -dname "CN=server" -alias server -ext "SAN:c=DNS:idm.test.hfh-it.de,IP:192.168.44.11" -keystore conf/server.keystore
+RUN /opt/keycloak/bin/kc.sh build
+
+
+FROM quay.io/keycloak/keycloak:${KC_TAG}
+
+COPY --from=builder /opt/keycloak/ /opt/keycloak/
+
+USER root
+COPY entrypoint /sa-entrypoint
+RUN chmod 544 /sa-entrypoint
+
+USER keycloak
+ENTRYPOINT ["/bin/sh", "/sa-entrypoint"]
+CMD ["start", "--optimized"]
diff --git a/keycloak/docker/entrypoint b/keycloak/docker/entrypoint
new file mode 100644
index 0000000..772add0
--- /dev/null
+++ b/keycloak/docker/entrypoint
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+set -e
+
+{
+    db_secret=/tmp/passwd/db/secret
+
+    i=0
+    while [ -z "$(cat ${db_secret} 2>/dev/null)" ]; do
+        if [ ${i} -eq 10 ]; then
+            echo "ERROR: No password file after ${i}s."
+            exit 1
+        fi
+        sleep 1
+        i=$((i+1))
+    done
+
+    export KC_DB_PASSWORD=$(cat ${db_secret})
+}
+
+exec /opt/keycloak/bin/kc.sh "$@"
diff --git a/nginx/sa.conf b/nginx/sa.conf
index 0a20f36..4022254 100644
--- a/nginx/sa.conf
+++ b/nginx/sa.conf
@@ -30,6 +30,16 @@
         fastcgi_index index.php;
         fastcgi_param SCRIPT_FILENAME /var/www/html$fastcgi_script_name;
     }
+
+    location /auth/ {   # Gerrit adds this prefix for Keycloak...
+        rewrite ^/auth(.*)$ $1 last;
+    }
+
+    location / {
+        proxy_pass          http://keycloak:8080;
+        proxy_set_header    X-Forwarded-For $remote_addr;
+        proxy_set_header    Host $host;
+    }
 }
 
 server {
diff --git a/postgres/docker/entrypoint b/postgres/docker/entrypoint
index 311a019..1782d31 100644
--- a/postgres/docker/entrypoint
+++ b/postgres/docker/entrypoint
@@ -11,7 +11,7 @@
         echo $(mktemp -u XXXXXXXXXXXXXXXX) >${kc_secret}
     fi
     chown root:postgres ${kc_secret}
-    chmod 440 ${kc_secret}
+    chmod 444 ${kc_secret}
 }
 
 exec docker-entrypoint.sh "$@"
diff --git a/postgres/init.sh b/postgres/init.sh
index dc0d510..6ef8e46 100755
--- a/postgres/init.sh
+++ b/postgres/init.sh
@@ -7,8 +7,7 @@
     kc_password=$(cat ${kc_secret})
 
     psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL
-	CREATE USER keycloak WITH PASSWORD '${kc_password}';
-	CREATE DATABASE keycloak;
-	GRANT ALL PRIVILEGES ON DATABASE keycloak TO keycloak;
+	CREATE USER keycloak WITH ENCRYPTED PASSWORD '${kc_password}';
+	CREATE DATABASE keycloak WITH ENCODING='UTF8' OWNER keycloak;
 EOSQL
 }