#!/usr/bin/env bash # Server secrets, run as root after bootstrap.sh. # secrets-init.sh generate every missing secret; never overwrites one # secrets-init.sh keycloak-secret store the client secret of Keycloak client # "petrolyst" (Clients > petrolyst > Credentials), # read from the terminal or stdin # # Layout: /opt/petrolyst/secrets/{shared,traefik,fuel-monitoring}/ are root:deploy # 0750, so only root and the deploy user can reach them; the files are 0444 # because each container reads them under its own uid. set -euo pipefail die() { echo "ERROR: $*" >&2; exit 1; } [ "$(id -u)" = 0 ] || die "run as root" getent group deploy >/dev/null || die "group deploy is missing: run host/bootstrap.sh first" ROOT=/opt/petrolyst SECRETS=$ROOT/secrets umask 077 install -d -o root -g deploy -m 0750 "$SECRETS" "$SECRETS/shared" "$SECRETS/traefik" "$SECRETS/fuel-monitoring" # write_secret : no trailing newline (oauth2-proxy reads the file # byte for byte), replaced atomically. write_secret() { printf '%s' "$2" >"$1.tmp" chown root:deploy "$1.tmp" chmod 0444 "$1.tmp" mv "$1.tmp" "$1" } generate() { if [ -s "$1" ]; then echo "kept $1" else write_secret "$1" "$(openssl rand -hex "$2")" echo "generated $1" fi } case ${1:-all} in keycloak-secret) if [ -t 0 ]; then printf 'Client secret of Keycloak client "petrolyst": ' >&2 IFS= read -rs value echo >&2 else # `pbpaste | ...` sends no final newline: read then still sets value but # fails, which set -e would turn into a silent exit. IFS= read -r value || true fi value=$(printf '%s' "$value" | tr -d '[:space:]') [ -n "$value" ] || die "empty secret" write_secret "$SECRETS/shared/keycloak_petrolyst_client_secret" "$value" echo "stored $SECRETS/shared/keycloak_petrolyst_client_secret" exit 0 ;; all) ;; *) die "usage: secrets-init.sh [keycloak-secret]" ;; esac # Hex only, so no value ever needs quoting in a URL or a properties file. generate "$SECRETS/fuel-monitoring/superset_secret_key" 32 generate "$SECRETS/fuel-monitoring/superset_db_password" 32 generate "$SECRETS/fuel-monitoring/fuel_db_password" 32 generate "$SECRETS/fuel-monitoring/fuel_db_ro_password" 32 # 32 hex characters = a 32-byte cookie key, as oauth2-proxy requires. generate "$SECRETS/traefik/oauth2_proxy_cookie_secret" 16 if [ ! -s "$SECRETS/shared/keycloak_petrolyst_client_secret" ]; then echo echo "Still missing: the Keycloak client secret. Copy it from Keycloak" echo "(realm thedigitalbridge > Clients > petrolyst > Credentials), then run:" echo " $0 keycloak-secret" exit 1 fi echo "All secrets present."