Use secret seed for internal database passwords

Getting root-only read permissions into the Postgres image would
be tricky due to its init script nature. But it isn't exposed to
the outside anyway.
diff --git a/.gitignore b/.gitignore
index c095bcb..343857e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -20,4 +20,3 @@
 /mail/rspamd-override.d/
 /mail/state/
 /postgres/data/
-/postgres/passwd/
diff --git a/docker-compose.yml b/docker-compose.yml
index 603fdca..c45cf79 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -28,18 +28,22 @@
   postgres:
     build:
       context: ./postgres/docker/
+    secrets:
+      - seed
     networks:
       - dbnet
     volumes:
       - ./postgres/postgres.conf:/etc/postgresql/postgresql.conf:ro
       - ./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
+    secrets:
+      - source : seed
+        mode: 0400
     networks:
       - kcnet
       - dbnet
@@ -57,8 +61,6 @@
       - KC_DB_POOL_MAX_SIZE=16
       - KEYCLOAK_ADMIN=deusarcadia
       - KEYCLOAK_ADMIN_PASSWORD=arcanumhomini
-    volumes:
-      - ./postgres/passwd/keycloak/:/tmp/passwd/db/:ro
   simpleid:
     build:
       context: .
diff --git a/keycloak/docker/Dockerfile b/keycloak/docker/Dockerfile
index 84c07dd..e38782f 100644
--- a/keycloak/docker/Dockerfile
+++ b/keycloak/docker/Dockerfile
@@ -14,14 +14,19 @@
 RUN /opt/keycloak/bin/kc.sh build
 
 
+FROM registry.access.redhat.com/ubi9 AS ubi-micro-build
+RUN dnf install --releasever 9 --setopt install_weak_deps=false --nodocs -y util-linux
+
+
 FROM quay.io/keycloak/keycloak:${KC_TAG}
 
 COPY --from=builder /opt/keycloak/ /opt/keycloak/
+COPY --from=ubi-micro-build /usr/lib64/libcap-ng.so.0* /usr/lib64/
+COPY --from=ubi-micro-build /usr/bin/setpriv /usr/bin
 
 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
index 772add0..5f3454d 100644
--- a/keycloak/docker/entrypoint
+++ b/keycloak/docker/entrypoint
@@ -2,20 +2,11 @@
 
 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})
+secret() {
+    seed=$(cat /run/secrets/seed)
+    printf "%s:%40s" "${seed}" "$*" | sha256sum | sed 's/[[:space:]].*//'
 }
 
-exec /opt/keycloak/bin/kc.sh "$@"
+export KC_DB_PASSWORD=$(secret db:keycloak)
+
+exec setpriv --reuid=keycloak --regid=root --init-groups --inh-caps=-all /opt/keycloak/bin/kc.sh "$@"
diff --git a/postgres/docker/entrypoint b/postgres/docker/entrypoint
index 1782d31..be591bc 100644
--- a/postgres/docker/entrypoint
+++ b/postgres/docker/entrypoint
@@ -2,16 +2,7 @@
 
 set -e
 
+# This master password won't be known to anyone
 export POSTGRES_PASSWORD=$(mktemp -u XXXXXXXXXXXXXXXX)
 
-kc_secret=/tmp/passwd/keycloak/secret
-{
-    if [ ! -f ${kc_secret} ]; then
-        mkdir -p $(dirname ${kc_secret})
-        echo $(mktemp -u XXXXXXXXXXXXXXXX) >${kc_secret}
-    fi
-    chown root:postgres ${kc_secret}
-    chmod 444 ${kc_secret}
-}
-
 exec docker-entrypoint.sh "$@"
diff --git a/postgres/init.sh b/postgres/init.sh
index 6ef8e46..a39f33d 100755
--- a/postgres/init.sh
+++ b/postgres/init.sh
@@ -2,12 +2,17 @@
 
 set -e
 
-{
-    kc_secret=/tmp/passwd/keycloak/secret
-    kc_password=$(cat ${kc_secret})
+secret() {
+    seed=$(cat /run/secrets/seed)
+    printf "%s:%40s" "${seed}" "$*" | sha256sum | sed 's/[[:space:]].*//'
+}
 
+add_user_db() {
+    user="$1"
     psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL
-	CREATE USER keycloak WITH ENCRYPTED PASSWORD '${kc_password}';
-	CREATE DATABASE keycloak WITH ENCODING='UTF8' OWNER keycloak;
+	CREATE USER ${user} WITH ENCRYPTED PASSWORD '$(secret db:${user})';
+	CREATE DATABASE ${user} WITH ENCODING='UTF8' OWNER ${user};
 EOSQL
 }
+
+add_user_db keycloak