Sign-in by customer: realm petrolyst, row rules, guest role (PD-21)
Keycloak import for realm petrolyst: two clients, petrolyst with MFA for Superset and Traefik, petrolyst-app password only. It lists only app.petrolyst.com and traefik.petrolyst.com, and no customer names, as this repository is public. public.v_operator shows each customer's group. Dashboards overview and site, role Petrolyst Guest, filtered by row. Superset refuses a user with no mapped role. The realm travels with the release: each release's compose files name their realm and secret file, and a rollback needs only its target's secret. Not deployed. Checks earlier on this content: tests/run.sh 109 of 109 and read-only, dashboards import twice, column drift 0, compose config on old and new trees, the secret check on a scratch folder, a rehearsal on a throwaway Keycloak 26.4. Never a real deploy or rollback; shellcheck not installed today, clean when last run. Codex inspected once; its fixes are not re-inspected, on the owner's word. Bands: persistence, Superset. Rules: 1, 2, 3, 6, 14. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
ab553526f6
commit
78a498f1ce
20 files changed
+279
-78
No files matched your search
+28
-10
@@ -17,9 +17,11 @@ ROLLBACK_MARK=$STATE/rollback-in-progress
|
||||
|
||||
ATOMA_HOST=${ATOMA_HOST:-atoma.petrolyst.com}
|
||||
TRAEFIK_HOST=${TRAEFIK_HOST:-traefik.petrolyst.com}
|
||||
KEYCLOAK_REALM_URL=${KEYCLOAK_REALM_URL:-https://iam.thedigitalbridge.io/realms/thedigitalbridge}
|
||||
PETROLYST_ROOT=$ROOT
|
||||
export ATOMA_HOST TRAEFIK_HOST KEYCLOAK_REALM_URL PETROLYST_ROOT
|
||||
# The Keycloak realm is not set here: each release's compose files name their own, with the secret
|
||||
# file that belongs to it. A rollback, which runs this file from the release it leaves, therefore
|
||||
# returns to the old release's realm and secret. Exporting a value here would override them.
|
||||
export ATOMA_HOST TRAEFIK_HOST PETROLYST_ROOT
|
||||
|
||||
# --host pins the daemon, as in petrolyst-web/deploy/deploy.sh: a stale
|
||||
# `docker context use` must not send this deploy to another daemon.
|
||||
@@ -39,8 +41,8 @@ SUPERSET_INPUTS=(
|
||||
)
|
||||
|
||||
# Every file the stacks need from /opt/petrolyst (host/secrets-init.sh).
|
||||
# The Keycloak client secret is not listed: it depends on the release (check_keycloak_secrets).
|
||||
REQUIRED_FILES=(
|
||||
secrets/shared/keycloak_petrolyst_client_secret
|
||||
secrets/traefik/oauth2_proxy_cookie_secret
|
||||
secrets/fuel-monitoring/superset_secret_key
|
||||
secrets/fuel-monitoring/superset_db_password
|
||||
@@ -126,10 +128,7 @@ preflight() {
|
||||
for f in "${REQUIRED_FILES[@]}"; do
|
||||
[ -s "$ROOT/$f" ] || die "missing or empty: $ROOT/$f (run host/secrets-init.sh as root)"
|
||||
done
|
||||
# oauth2-proxy uses the client secret file byte for byte.
|
||||
f=$ROOT/secrets/shared/keycloak_petrolyst_client_secret
|
||||
[ "$(tail -c1 "$f" | wc -l)" -eq 0 ] ||
|
||||
die "$f ends with a newline; store it again with: host/secrets-init.sh keycloak-secret"
|
||||
check_keycloak_secrets "$release"
|
||||
bad=$(find "$release/petrolyst-insights" \( -name 'Dockerfile*' -o -name '*compose*.y*ml' \
|
||||
-o -name '*.env' -o -name '.env' -o -path '*/.gitea/*' -o -path '*/.github/*' \) -print)
|
||||
[ -z "$bad" ] || die "petrolyst-insights/ holds customization only; found: $bad"
|
||||
@@ -141,6 +140,21 @@ preflight() {
|
||||
die "containers of the old project fuel-monitoring exist; remove them first (README \"Removing the old project\")"
|
||||
}
|
||||
|
||||
# check_keycloak_secrets <release>: the client secret that release's compose files name, which
|
||||
# differs per realm. So a rollback needs only its target's secret, not the one of the release it leaves.
|
||||
check_keycloak_secrets() {
|
||||
local release=$1 names name f
|
||||
names=$(cat "$release/stacks/fuel-monitoring/compose.yaml" "$release/traefik/compose.yaml" |
|
||||
grep -oE 'secrets/shared/keycloak_[a-z_]+' | sort -u) || die "$release names no Keycloak client secret"
|
||||
for name in $names; do
|
||||
f=$ROOT/$name
|
||||
[ -s "$f" ] || die "missing or empty: $f (run host/secrets-init.sh as root)"
|
||||
# oauth2-proxy uses the client secret file byte for byte.
|
||||
[ "$(tail -c1 "$f" | wc -l)" -eq 0 ] ||
|
||||
die "$f ends with a newline; store it again"
|
||||
done
|
||||
}
|
||||
|
||||
# promote <release> <sha>: make the release the live tree. --chmod applies to
|
||||
# the destination only: the live tree stays writable, the release read-only.
|
||||
promote() {
|
||||
@@ -234,7 +248,7 @@ probe() {
|
||||
}
|
||||
|
||||
smoke_tests() {
|
||||
local i body code location
|
||||
local i body code location realm
|
||||
log "smoke tests"
|
||||
# First deploy: Let's Encrypt may need a minute to issue the certificate.
|
||||
for i in $(seq 1 24); do
|
||||
@@ -244,17 +258,21 @@ smoke_tests() {
|
||||
sleep 5
|
||||
done
|
||||
|
||||
# The realm this release runs on. These tests check redirects only, not a real sign-in: they
|
||||
# pass with a wrong client secret, so a person signs in after a change of realm or secret.
|
||||
realm=$(fm exec -T superset printenv KEYCLOAK_REALM_URL) || die "Superset has no KEYCLOAK_REALM_URL"
|
||||
|
||||
read -r code location < <(probe "$ATOMA_HOST" /login/)
|
||||
[ "$code" = 302 ] && [[ $location == "https://$ATOMA_HOST/login/keycloak"* ]] ||
|
||||
die "/login/ should redirect to /login/keycloak, got $code $location"
|
||||
|
||||
read -r code location < <(probe "$ATOMA_HOST" /login/keycloak)
|
||||
[ "$code" = 302 ] && [[ $location == "$KEYCLOAK_REALM_URL/protocol/openid-connect/auth?"* ]] &&
|
||||
[ "$code" = 302 ] && [[ $location == "$realm/protocol/openid-connect/auth?"* ]] &&
|
||||
[[ $location == *client_id=petrolyst* && $location == *code_challenge_method=S256* ]] ||
|
||||
die "/login/keycloak should redirect to Keycloak with client_id=petrolyst and PKCE S256, got $code $location"
|
||||
|
||||
read -r code location < <(probe "$TRAEFIK_HOST" /)
|
||||
[ "$code" = 302 ] && [[ $location == "$KEYCLOAK_REALM_URL/"* || $location == *"/oauth2/start"* ]] ||
|
||||
[ "$code" = 302 ] && [[ $location == "$realm/"* || $location == *"/oauth2/start"* ]] ||
|
||||
die "https://$TRAEFIK_HOST/ should redirect to Keycloak, got $code $location"
|
||||
|
||||
# Superset's own connection "Fuel" (fuel_ro, password from /run/secrets) reads fuel-db and
|
||||
|
||||
Reference in new issue
Block a user