From 7284bcec7b37c7490913e54ae517c5859a4c5ef3 Mon Sep 17 00:00:00 2001 From: William Mantly Date: Tue, 4 Aug 2026 19:32:35 -0400 Subject: [PATCH] fix: setup.sh ldap.vars re-run abort + drop app_super_admin; roll up sso v1.26.1 (v1.36.1) - setup.sh: ldap.vars generation read CFG_* first-run vars (unset on re-run); now reads real values from sso-secrets.js, so LDAP enrollment works on re-runs - generated ldap_access_groups now references god_admin (app_super_admin gone) - gitlink: sso-manager-node 8db00f0 (v1.26.1) --- CHANGELOG.md | 6 ++++++ bootstrap/bootstrap.js | 7 ++++--- setup.sh | 39 ++++++++++++++++++++++++++++++++------- sso-manager-node | 2 +- 4 files changed, 43 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 309856b..9796480 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,12 @@ orchestration code; see each submodule's own `CHANGELOG.md` [sso-manager-node](https://github.com/theta42/sso-manager-node/blob/master/CHANGELOG.md)) for what changed inside the apps it composes. +## [v1.36.1] - 2026-08-04 + +### Fixed +- **`setup.sh` no longer aborts with `CFG_BASE_DN: unbound variable`** — the ldap-client `ldap.vars` generation read the CFG_* first-run vars, which `ensure_config` only derives once (it returns early on a re-run once `sso-secrets.js` exists). It now reads the real values from the operator-owned `./config/sso-secrets.js` when the CFG_* vars are unset, so LDAP enrollment works on re-runs too. The generated `ldap_access_groups` now references `god_admin` (the legacy `app_super_admin` is gone). +- **Roll up sso v1.26.1** — drops the legacy `app_super_admin`: `SUPER_ADMIN_GROUP` is now `god_admin` (nested into every resource's `_admin` group), and `docker-entrypoint.sh` no longer seeds/nests `app_super_admin`. See the [sso changelog](https://github.com/theta42/sso-manager-node/blob/master/CHANGELOG.md). + ## [v1.36.0] - 2026-08-04 ### Added diff --git a/bootstrap/bootstrap.js b/bootstrap/bootstrap.js index 688b992..75d2465 100644 --- a/bootstrap/bootstrap.js +++ b/bootstrap/bootstrap.js @@ -90,10 +90,11 @@ const CLIENT_NAME = 'theta-proxy'; const ADMIN_DN = `cn=${ADMIN_UID},ou=people,${BASE_DN}`; const SVC_DN = `cn=ldapclient,ou=people,${BASE_DN}`; // god_admin is the global super group (docs/GROUPS.md §2); the bootstrapped -// admin is its first member. app_sso_admin / app_sso_oauth_admin are the legacy +// admin is its first member. app_sso_admin / app_sso_oauth_admin are the // per-console admin groups still used by the SSO UI. god_admin is nested into -// app_super_admin by docker-entrypoint.sh, so LDAP-level consumers (SSSD, sudo) -// resolve it transitively. +// the app_sso_* groups (and every resource's _admin group) by +// docker-entrypoint.sh + api_directory_admin, so LDAP-level consumers (SSSD, +// sudo) resolve it transitively. const ADMIN_GROUPS = ['god_admin', 'app_sso_admin', 'app_sso_oauth_admin']; const log = (...a) => process.stderr.write('[bootstrap] ' + a.join(' ') + '\n'); diff --git a/setup.sh b/setup.sh index f9a28bf..1e508e0 100755 --- a/setup.sh +++ b/setup.sh @@ -292,6 +292,21 @@ dn_from_domain() { echo "dc=$1" | sed 's/\./,dc=/g' } +# Read a value from the (operator-owned) ./config/sso-secrets.js -- the source of +# truth on re-runs, where the CFG_* first-run shell vars are not (re)derived +# (ensure_config returns early once sso-secrets.js exists). Reads `stack.`. +# Prints empty on any failure. Usage: sso_secrets_get ldapBaseDn +sso_secrets_get() { + node -e 'const c=require(process.argv[1]);const k=process.argv[2];console.log(c&&c.stack&&c.stack[k]!=null?c.stack[k]:"")' \ + "$PWD/$CONFIG_DIR/sso-secrets.js" "$1" 2>/dev/null || true +} + +# Read a top-level (non-stack) secret from sso-secrets.js, e.g. serviceAccountPass. +sso_secrets_get_top() { + node -e 'const c=require(process.argv[1]);const k=process.argv[2];console.log(c&&c[k]!=null?c[k]:"")' \ + "$PWD/$CONFIG_DIR/sso-secrets.js" "$1" 2>/dev/null || true +} + # Write ./config/sso-secrets.js from the CFG_* shell vars. write_sso_secrets() { local dn="$CFG_BASE_DN" domain="$CFG_DOMAIN" @@ -1265,15 +1280,25 @@ if [[ "$CFG_THETA_AGENT_ENABLE" == "1" ]] && [[ -x /usr/local/bin/theta-agent ]] # ldap.vars (cp ldap.vars.template ldap.vars + edit) is always kept. if [[ ! -f ldap-client/ldap.vars ]]; then info " Generating ldap-client/ldap.vars from the stack config..." + # CFG_* first-run vars may be unset on a re-run (ensure_config returns + # early once sso-secrets.js exists), so fall back to reading the real + # values from the operator-owned sso-secrets.js. All `:-` guarded so a + # missing value degrades to an empty ldap.vars field, not a set -u abort. + ldap_base_dn="${CFG_BASE_DN:-$(sso_secrets_get ldapBaseDn)}" + ldap_site="${CFG_SITE_NAME:-$(sso_secrets_get siteName)}" + ldap_bind_pass="${CFG_SVC_PASS:-$(sso_secrets_get_top serviceAccountPass)}" + sso_host="${CFG_SSO_HOST:-$(sso_secrets_get ssoHost)}" + ldaps_host="${CFG_LDAPS_HOST:-}" + [[ -n "$ldaps_host" ]] || ldaps_host="${sso_host:-}" cat > ldap-client/ldap.vars <