The base DN (stack.ldapBaseDn) is the single place the domain is set; the
LDAP DNs (bindDN/userBase/groupBase) and oauth.issuer all derive from it and
must stay consistent. Drifting them apart (leaving bindDN at dc=example,dc=com
while ldapBaseDn is the real domain) makes the SSO bind against a non-existent
root DN and every login fails with Invalid Credentials.
- secrets.js.example: clarifying comment at ldapBaseDn
- DEPLOYMENT.md: "domain entered once as the base DN" note + theta-env
setup.env cross-link (merged the two duplicate theta-env blockquotes)
- README.md: cross-link to DEPLOYMENT.md from "Server set up"
Docs only; no app/secrets-structure change.
Co-authored-by: Claude <noreply@anthropic.com>
Lossless upgrades + config story for the all-in-one image.
Redis persistence (Part A):
- Replace in-memory `--save "" --appendonly no` with AOF + RDB persisted to /data
(--appendonly yes, periodic saves, --dbfilename dump.rdb). OAuth clients,
tokens, and other model-redis state now survive container recreation.
- Add the `sso-data` named volume -> /data in docker-compose.yml.
Config from ./config/sso-secrets.js (Part B):
- docker-entrypoint.sh: when /config/sso-secrets.js is mounted, symlink it to
/app/conf/secrets.js and read the server-side LDAP vars (base DN, admin pass,
org, domain, cert CN, JWT) from the file via one `node` call (base64-decoded,
no eval/quoting hazards). No app_* env is exported in this mode, so the file
is authoritative (@simpleworkjs/conf precedence: base < env < secrets.js <
app_* env). Falls back to the existing LDAP_* env-var mode when the file is
absent (standalone/bare-metal still works).
- docker-compose.yml: trim `environment:` to NODE_ENV/NODE_PORT only and add
`./config:/config:ro`. Removing the app_* env is required — any leftover
app_* would silently override secrets.js.
- secrets.js.example: add orchestrator-only `stack`, `bootstrap`, and
`serviceAccountPass` keys (ignored by the app; read by the entrypoint, the
theta-env bootstrap, and setup.sh).
Backup/restore docs:
- Full "Backups and restore" runbook in DEPLOYMENT.md (what lives where,
manual backup, full / Redis-only / LDAP-only restore, AOF-vs-RDB note,
upgrades). Restore uses slapadd -f (static slapd.conf), and RDB restore
requires deleting the AOF first (AOF wins on startup).
- Pointers in docs/deployment.md and docs/ldap.md; update the Docker Setup
section for the new ./config/ approach (env vars now advanced/optional).
Co-authored-by: Claude <noreply@anthropic.com>