a78db906e8
Mail sending fell back to a hardcoded noreply@theta42.com From address when smtp.from wasn't set, which authenticated relays reject with "Sender is not same as SMTP authenticate username" since no relay authorized this account to send as that address. Falls back to smtp.user first now. Also: catalog card titles now read name-then-icon instead of icon-then-name, and a handful of docs corrections found in an accuracy pass (configuration.md missing the OpenBao/live-config layer, plugins.md undercounting plugin types, vault.md describing OpenBao dev-mode/root-token access that doesn't reflect the real production setup, orphaned discovery.md/vault.md pages linked in, README's required-groups list missing app_sso_directory_admin). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0113gCdnfSCuZr6xvPDxTo3D
118 lines
4.9 KiB
Markdown
118 lines
4.9 KiB
Markdown
---
|
|
layout: default
|
|
title: Configuration
|
|
description: SSO Manager's config layers — conf/base.js defaults, secrets.js overrides, and app_* environment variables.
|
|
---
|
|
|
|
# Configuration
|
|
|
|
[← Back to Home](index.html)
|
|
|
|
The app loads configuration via
|
|
[`@simpleworkjs/conf`](https://www.npmjs.com/package/@simpleworkjs/conf), which
|
|
deep-merges, in order (later wins):
|
|
|
|
1. `conf/base.js` — committed, generic defaults (`dc=example,dc=com`,
|
|
`localhost`, `SSO Manager`).
|
|
2. `conf/<NODE_ENV>.js` — optional, environment-specific.
|
|
3. `conf/secrets.js` — gitignored; secrets + per-deployment values.
|
|
4. **`app_*` environment variables** — the highest-precedence layer among these
|
|
four.
|
|
|
|
Any env var whose name starts with `app_` overrides the merged config. The rest
|
|
of the name splits on **double-underscore** (`__`) into a nested path. Values are
|
|
`JSON.parse`-coerced when possible (numbers, booleans, null, JSON) and kept as
|
|
raw strings otherwise.
|
|
|
|
### A fifth, higher-precedence layer: OpenBao + the Configuration UI
|
|
|
|
In a theta-suite deployment, `@simpleworkjs/bao-conf`'s `init()` deep-merges
|
|
`secret/sso-manager/conf` (from OpenBao) over the four layers above at boot —
|
|
this is the layer `setup.sh`/theta-suite actually manages, and it wins over
|
|
everything else here. On top of that, the admin **Configuration** page in the
|
|
UI writes straight to `secret/sso-manager/conf` (via `routes/api_conf.js`)
|
|
and applies the change to the live `conf` object immediately
|
|
(`applyToLiveConf`) — no restart, and it bypasses `conf/secrets.js` entirely.
|
|
If a value isn't behaving the way `conf/secrets.js` says it should, check the
|
|
Configuration UI / OpenBao before assuming a file edit didn't take — it's
|
|
almost certainly OpenBao (or a live UI edit) winning the merge.
|
|
|
|
## Examples
|
|
|
|
| Env var | Sets | Type |
|
|
|---------|------|------|
|
|
| `app_ldap__url=ldap://host:389` | `conf.ldap.url` | string |
|
|
| `app_ldap__bindPassword=secret` | `conf.ldap.bindPassword` | string |
|
|
| `app_ldap__userBase=ou=people,dc=…` | `conf.ldap.userBase` | string |
|
|
| `app_ldap__uidGidMin=1500` | `conf.ldap.uidGidMin` | number (new-user id floor) |
|
|
| `app_ldap__uidGidReservedFloor=9000` | `conf.ldap.uidGidReservedFloor` | number (ids at/above this are ignored when allocating) |
|
|
| `app_ldap__ldapsHost=ldap.internal.example.com` | `conf.ldap.ldapsHost` | string (hostname shown on `/integrations` for LDAPS binds; empty = derive from `oauth.issuer`) |
|
|
| `app_ldap__ldapsPort=636` | `conf.ldap.ldapsPort` | number (port shown on `/integrations`) |
|
|
| `app_oauth__jwtSecret=...` | `conf.oauth.jwtSecret` | string |
|
|
| `app_oauth__issuer=https://sso.example.com` | `conf.oauth.issuer` | string |
|
|
| `app_oauth__token_lifetime__access_token=3600` | `conf.oauth.token_lifetime.access_token` | number |
|
|
| `app_smtp__secure=false` | `conf.smtp.secure` | boolean |
|
|
| `app_smtp__host=smtp.example.com` | `conf.smtp.host` | string |
|
|
| `app_name=My SSO` | `conf.name` | string |
|
|
| `app_redis__host=redis.local` | `conf.redis.host` | string (external Redis) |
|
|
|
|
## The `app_*` env layer requires conf >= 1.1.0
|
|
|
|
The `app_*` environment-variable override layer was added in
|
|
`@simpleworkjs/conf` **1.1.0**. On 1.0.0 the app ignores all `app_*` vars and only
|
|
reads `base.js` / `<NODE_ENV>.js` / `secrets.js`. The Docker image will not honor
|
|
`app_*` env on 1.0.0. Refresh the lock from the `nodejs/` directory:
|
|
|
|
```bash
|
|
cd nodejs && npm install @simpleworkjs/conf@^1.1.0
|
|
```
|
|
|
|
## Inspecting the merged config
|
|
|
|
From the `nodejs/` directory:
|
|
|
|
```bash
|
|
node -e "console.log(require('@simpleworkjs/conf').ldap)"
|
|
node -e "console.log(require('@simpleworkjs/conf').oauth)"
|
|
node -e "console.log(require('@simpleworkjs/conf'))" # everything
|
|
```
|
|
|
|
Or, inside the running container:
|
|
|
|
```bash
|
|
docker compose exec sso-manager node -e "console.log(require('@simpleworkjs/conf').ldap)"
|
|
```
|
|
|
|
`app_*` env vars override `secrets.js`, which overrides `base.js` — if a value
|
|
isn't what you expect, check those layers in that order.
|
|
|
|
## Migrating an existing instance to the generic defaults
|
|
|
|
The committed `nodejs/conf/base.js` ships **generic** defaults
|
|
(`dc=example,dc=com`, `localhost`, `SSO Manager`). Previously it carried
|
|
Theta42-specific values (LDAP bind DN/bases, SMTP host/user/sender, OAuth
|
|
issuer). If you run an existing instance off this repo:
|
|
|
|
- Move per-deployment, non-secret values (bind DN, user/group bases, SMTP
|
|
host/user/sender, OAuth issuer, org name) from `base.js` into your gitignored
|
|
`conf/secrets.js`, **or** set them as `app_*` env vars.
|
|
- Secret values (LDAP bind password, SMTP password, JWT secret) already belong
|
|
in `secrets.js`.
|
|
|
|
## Troubleshooting `app_*` env vars
|
|
|
|
### `app_*` vars seem to do nothing
|
|
|
|
You're on `@simpleworkjs/conf` 1.0.0. Bump to 1.1.0+ (above).
|
|
|
|
### LDAP operations 401 / "Invalid Credentials"
|
|
|
|
Check the merged LDAP config the app actually sees:
|
|
|
|
```bash
|
|
cd nodejs && node -e "console.log(require('@simpleworkjs/conf').ldap)"
|
|
```
|
|
|
|
Confirm `url` / `bindDN` / `bindPassword` / `userBase` match your directory.
|
|
|
|
[← Back to Home](index.html) |