Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 30146e9588 | |||
| 481602ae60 |
+13
-1
@@ -10,6 +10,17 @@ for what changed inside the apps it composes.
|
|||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
## [1.1.16] - 2026-07-18
|
||||||
|
|
||||||
|
### Bumped
|
||||||
|
- proxy -> [v1.1.14](https://github.com/theta42/proxy/releases/tag/v1.1.14)
|
||||||
|
- sso-manager-node -> [v1.1.14](https://github.com/theta42/sso-manager-node/releases/tag/v1.1.14)
|
||||||
|
|
||||||
|
Both: bumped `@simpleworkjs/conf` to 1.2.0 and `jq-repeat` to 2.2.0.
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- `./config/sso-secrets.js` and `./config/proxy-secrets.js` are now loaded via each app's `CONF_SECRETS` env var (set by the entrypoint) instead of being symlinked into `/app/conf/secrets.js` — neither container needs write access to its own `conf/` directory anymore. No change to the config file format or bind mounts; existing `./config/` directories keep working as-is.
|
||||||
|
|
||||||
## [1.1.15] - 2026-07-17
|
## [1.1.15] - 2026-07-17
|
||||||
|
|
||||||
### Bumped
|
### Bumped
|
||||||
@@ -195,7 +206,8 @@ First tagged release. Establishes the `vX.Y.Z` tag convention going forward.
|
|||||||
- proxy -> [v1.1.0](https://github.com/theta42/proxy/releases/tag/v1.1.0)
|
- proxy -> [v1.1.0](https://github.com/theta42/proxy/releases/tag/v1.1.0)
|
||||||
- sso-manager-node -> [v1.1.0](https://github.com/theta42/sso-manager-node/releases/tag/v1.1.0)
|
- sso-manager-node -> [v1.1.0](https://github.com/theta42/sso-manager-node/releases/tag/v1.1.0)
|
||||||
|
|
||||||
[Unreleased]: https://github.com/theta42/theta-env/compare/v1.1.15...HEAD
|
[Unreleased]: https://github.com/theta42/theta-env/compare/v1.1.16...HEAD
|
||||||
|
[1.1.16]: https://github.com/theta42/theta-env/compare/v1.1.15...v1.1.16
|
||||||
[1.1.15]: https://github.com/theta42/theta-env/compare/v1.1.14...v1.1.15
|
[1.1.15]: https://github.com/theta42/theta-env/compare/v1.1.14...v1.1.15
|
||||||
[1.1.14]: https://github.com/theta42/theta-env/compare/v1.1.13...v1.1.14
|
[1.1.14]: https://github.com/theta42/theta-env/compare/v1.1.13...v1.1.14
|
||||||
[1.1.13]: https://github.com/theta42/theta-env/compare/v1.1.12...v1.1.13
|
[1.1.13]: https://github.com/theta42/theta-env/compare/v1.1.12...v1.1.13
|
||||||
|
|||||||
@@ -172,7 +172,8 @@ operator-owned and `setup.env` is ignored.
|
|||||||
### Configuration — `./config/` (no `.env` files)
|
### Configuration — `./config/` (no `.env` files)
|
||||||
|
|
||||||
All config and secrets live in a bind-mounted `./config/` directory (gitignored),
|
All config and secrets live in a bind-mounted `./config/` directory (gitignored),
|
||||||
read by each app's `@simpleworkjs/conf` from a symlinked `secrets.js`:
|
read by each app's `@simpleworkjs/conf` via the `CONF_SECRETS` env var, which
|
||||||
|
the entrypoint points at the mounted file:
|
||||||
|
|
||||||
- **`./config/sso-secrets.js`** — SSO config: `ldap` (base, admin password,
|
- **`./config/sso-secrets.js`** — SSO config: `ldap` (base, admin password,
|
||||||
user/group bases), `oauth` (issuer, `jwtSecret`), `smtp`, `name`, plus
|
user/group bases), `oauth` (issuer, `jwtSecret`), `smtp`, `name`, plus
|
||||||
|
|||||||
+8
-7
@@ -13,11 +13,12 @@
|
|||||||
# Config + secrets live in bind-mounted ./config/ (gitignored):
|
# Config + secrets live in bind-mounted ./config/ (gitignored):
|
||||||
# ./config/sso-secrets.js — SSO app + orchestrator config
|
# ./config/sso-secrets.js — SSO app + orchestrator config
|
||||||
# ./config/proxy-secrets.js — proxy OIDC/LDAP/auth config
|
# ./config/proxy-secrets.js — proxy OIDC/LDAP/auth config
|
||||||
# Each app's entrypoint symlinks its file into /app/conf/secrets.js so
|
# Each app's entrypoint points CONF_SECRETS at its file so @simpleworkjs/conf
|
||||||
# @simpleworkjs/conf reads it. No app_* env is passed (app_* env would override
|
# (>= 1.2.0) reads it directly -- no app_* env is passed (app_* env would
|
||||||
# secrets.js). The sso-manager mounts ./config read-write so the bootstrap can
|
# override secrets.js), and no write access to /app/conf is needed. The
|
||||||
# write the generated OAuth client creds back into proxy-secrets.js; the proxy
|
# sso-manager mounts ./config read-write so the bootstrap can write the
|
||||||
# mounts it read-only.
|
# generated OAuth client creds back into proxy-secrets.js; the proxy mounts
|
||||||
|
# it read-only.
|
||||||
#
|
#
|
||||||
# Compose only interpolates the port defaults below — there is no .env file.
|
# Compose only interpolates the port defaults below — there is no .env file.
|
||||||
# First-run wiring (LDAP service account, first admin, OAuth client) is
|
# First-run wiring (LDAP service account, first admin, OAuth client) is
|
||||||
@@ -56,7 +57,7 @@ services:
|
|||||||
volumes:
|
volumes:
|
||||||
# Operator-edited SSO secrets (sso-secrets.js). Read-WRITE so the bootstrap
|
# Operator-edited SSO secrets (sso-secrets.js). Read-WRITE so the bootstrap
|
||||||
# can write the generated OAuth client creds into proxy-secrets.js. The
|
# can write the generated OAuth client creds into proxy-secrets.js. The
|
||||||
# entrypoint symlinks /config/sso-secrets.js -> /app/conf/secrets.js.
|
# entrypoint points CONF_SECRETS at /config/sso-secrets.js.
|
||||||
- ./config:/config
|
- ./config:/config
|
||||||
# Persist the LDAP database across container recreation.
|
# Persist the LDAP database across container recreation.
|
||||||
- ldap-data:/var/lib/ldap
|
- ldap-data:/var/lib/ldap
|
||||||
@@ -108,7 +109,7 @@ services:
|
|||||||
volumes:
|
volumes:
|
||||||
# Operator-edited proxy secrets (proxy-secrets.js). READ-ONLY — the proxy
|
# Operator-edited proxy secrets (proxy-secrets.js). READ-ONLY — the proxy
|
||||||
# only reads it; the sso-manager bootstrap writes the OAuth creds. The
|
# only reads it; the sso-manager bootstrap writes the OAuth creds. The
|
||||||
# entrypoint symlinks /config/proxy-secrets.js -> /app/conf/secrets.js.
|
# entrypoint points CONF_SECRETS at /config/proxy-secrets.js.
|
||||||
- ./config:/config:ro
|
- ./config:/config:ro
|
||||||
# Persist Redis (AOF + RDB) so Host records, permissions, DNS creds, local
|
# Persist Redis (AOF + RDB) so Host records, permissions, DNS creds, local
|
||||||
# users, AND the auto-ssl Let's Encrypt certs survive container recreation.
|
# users, AND the auto-ssl Let's Encrypt certs survive container recreation.
|
||||||
|
|||||||
+13
-12
@@ -102,9 +102,9 @@ inputs from the bind-mounted `./config/sso-secrets.js` + `./config/proxy-secrets
|
|||||||
read-only). If `proxy-secrets.js` already holds a `clientId`+`clientSecret`
|
read-only). If `proxy-secrets.js` already holds a `clientId`+`clientSecret`
|
||||||
matching an existing client, they are kept; if the client exists but the file
|
matching an existing client, they are kept; if the client exists but the file
|
||||||
has no usable secret, the secret is rotated and written back.
|
has no usable secret, the secret is rotated and written back.
|
||||||
6. **Build + start the proxy**, wait for `/health`. The proxy entrypoint symlinks
|
6. **Build + start the proxy**, wait for `/health`. The proxy entrypoint points
|
||||||
`./config/proxy-secrets.js` to `/app/conf/secrets.js`, so `@simpleworkjs/conf`
|
`CONF_SECRETS` at `./config/proxy-secrets.js`, so `@simpleworkjs/conf`
|
||||||
(≥1.1.0) reads the OAuth creds + LDAP bind creds from the file.
|
(≥1.2.0) reads the OAuth creds + LDAP bind creds from the file.
|
||||||
7. **Register `<SSO_HOST>` and `<PROXY_HOST>` as Host records in the proxy** —
|
7. **Register `<SSO_HOST>` and `<PROXY_HOST>` as Host records in the proxy** —
|
||||||
`setup.sh` runs a short script inside the proxy container that calls its
|
`setup.sh` runs a short script inside the proxy container that calls its
|
||||||
Host model directly (`Host.create({host, ip, targetPort, ...})`), rather
|
Host model directly (`Host.create({host, ip, targetPort, ...})`), rather
|
||||||
@@ -123,19 +123,20 @@ inputs from the bind-mounted `./config/sso-secrets.js` + `./config/proxy-secrets
|
|||||||
### How config reaches the apps (no `.env`)
|
### How config reaches the apps (no `.env`)
|
||||||
|
|
||||||
All config and secrets live in `./config/` (gitignored, bind-mounted). Each
|
All config and secrets live in `./config/` (gitignored, bind-mounted). Each
|
||||||
entrypoint symlinks its file to `/app/conf/secrets.js` early, before the app
|
entrypoint points the `CONF_SECRETS` env var (`@simpleworkjs/conf` >= 1.2.0)
|
||||||
starts:
|
at its file early, before the app starts:
|
||||||
|
|
||||||
```
|
```
|
||||||
./config/sso-secrets.js -> sso-manager:/app/conf/secrets.js (./config RW)
|
CONF_SECRETS=/config/sso-secrets.js (sso-manager, ./config RW)
|
||||||
./config/proxy-secrets.js -> proxy:/app/conf/secrets.js (./config RO)
|
CONF_SECRETS=/config/proxy-secrets.js (proxy, ./config RO)
|
||||||
```
|
```
|
||||||
|
|
||||||
`@simpleworkjs/conf` loads `conf/base.js → <env>.js → conf/secrets.js → app_*
|
`@simpleworkjs/conf` loads `conf/base.js → <env>.js → secrets file → app_*
|
||||||
env`, where **env beats `secrets.js`**. So compose passes **no `app_*` env vars**
|
env`, where **env beats the secrets file**. So compose passes **no `app_*` env
|
||||||
(only `NODE_ENV`, `NODE_PORT`) — that makes `secrets.js` authoritative. The SSO
|
vars** (only `NODE_ENV`, `NODE_PORT`) — that makes the secrets file
|
||||||
entrypoint reads the few values it needs at startup (LDAP base DN, admin
|
authoritative. The SSO entrypoint reads the few values it needs at startup
|
||||||
password, JWT secret, cert CN) from `secrets.js` via an in-container `node` call.
|
(LDAP base DN, admin password, JWT secret, cert CN) from `sso-secrets.js` via
|
||||||
|
an in-container `node` call.
|
||||||
|
|
||||||
### Why not `require` the SSO's internal models?
|
### Why not `require` the SSO's internal models?
|
||||||
|
|
||||||
|
|||||||
+8
-8
@@ -25,18 +25,18 @@ mkdir -p config && cp secrets.js.example config/sso-secrets.js # edit it
|
|||||||
docker compose up -d --build
|
docker compose up -d --build
|
||||||
```
|
```
|
||||||
|
|
||||||
The entrypoint symlinks `config/sso-secrets.js` to `nodejs/conf/secrets.js` so
|
The entrypoint points the `CONF_SECRETS` env var at `config/sso-secrets.js` so
|
||||||
`@simpleworkjs/conf` reads it. Set `ldap.bindPassword`, `oauth.jwtSecret`, and
|
`@simpleworkjs/conf` reads it. Set `ldap.bindPassword`, `oauth.jwtSecret`, and
|
||||||
the `stack`/`bootstrap` keys (the app ignores the ones it doesn't use). Pass
|
the `stack`/`bootstrap` keys (the app ignores the ones it doesn't use). Pass
|
||||||
**no `app_*` env** — env beats `secrets.js`, so `app_*` would silently override
|
**no `app_*` env** — env beats the secrets file, so `app_*` would silently
|
||||||
your file.
|
override your file.
|
||||||
|
|
||||||
- Web UI: `http://localhost:3001`
|
- Web UI: `http://localhost:3001`
|
||||||
- Health: `http://localhost:3001/health`
|
- Health: `http://localhost:3001/health`
|
||||||
- OIDC discovery: `http://localhost:3001/.well-known/openid-configuration`
|
- OIDC discovery: `http://localhost:3001/.well-known/openid-configuration`
|
||||||
- LDAPS: `ldaps://<host>:636`
|
- LDAPS: `ldaps://<host>:636`
|
||||||
|
|
||||||
Requires `@simpleworkjs/conf` >= 1.1.0. Full reference:
|
Requires `@simpleworkjs/conf` >= 1.2.0. Full reference:
|
||||||
[SSO Manager deployment docs](https://theta42.github.io/sso-manager-node/deployment.html).
|
[SSO Manager deployment docs](https://theta42.github.io/sso-manager-node/deployment.html).
|
||||||
|
|
||||||
### Bare metal
|
### Bare metal
|
||||||
@@ -62,11 +62,11 @@ mkdir -p config && cp secrets.js.example config/proxy-secrets.js # edit it
|
|||||||
docker compose up -d --build
|
docker compose up -d --build
|
||||||
```
|
```
|
||||||
|
|
||||||
The entrypoint symlinks `config/proxy-secrets.js` to `nodejs/conf/secrets.js` so
|
The entrypoint points the `CONF_SECRETS` env var at `config/proxy-secrets.js`
|
||||||
`@simpleworkjs/conf` reads it. Fill in `oidc` (your SSO's endpoints +
|
so `@simpleworkjs/conf` reads it. Fill in `oidc` (your SSO's endpoints +
|
||||||
`clientId`/`clientSecret`/`redirectUri`), `ldap` (bind creds + search base), and
|
`clientId`/`clientSecret`/`redirectUri`), `ldap` (bind creds + search base), and
|
||||||
`auth` (admin groups/users). Pass **no `app_*` env** — env beats `secrets.js`,
|
`auth` (admin groups/users). Pass **no `app_*` env** — env beats the secrets
|
||||||
so `app_*` would silently override your file.
|
file, so `app_*` would silently override your file.
|
||||||
|
|
||||||
- Proxy (public, auto-SSL): `https://<host>/`
|
- Proxy (public, auto-SSL): `https://<host>/`
|
||||||
- Mgmt UI / API: `http://127.0.0.1:3000/`
|
- Mgmt UI / API: `http://127.0.0.1:3000/`
|
||||||
|
|||||||
+1
-1
Submodule proxy updated: b9bdf36638...f0eadbc2d7
@@ -220,7 +220,7 @@ write_sso_secrets() {
|
|||||||
cat > "$CONFIG_DIR/sso-secrets.js" <<SSOEOF
|
cat > "$CONFIG_DIR/sso-secrets.js" <<SSOEOF
|
||||||
'use strict';
|
'use strict';
|
||||||
// Generated by setup.sh. Edit freely; re-run ./setup.sh to apply.
|
// Generated by setup.sh. Edit freely; re-run ./setup.sh to apply.
|
||||||
// The SSO app reads this via @simpleworkjs/conf (symlinked to conf/secrets.js).
|
// The SSO app reads this via @simpleworkjs/conf (CONF_SECRETS env var).
|
||||||
// The app ignores the extra stack/bootstrap/serviceAccountPass keys (read by
|
// The app ignores the extra stack/bootstrap/serviceAccountPass keys (read by
|
||||||
// the orchestrator). Back this file up off-host — it holds all SSO secrets.
|
// the orchestrator). Back this file up off-host — it holds all SSO secrets.
|
||||||
|
|
||||||
@@ -271,8 +271,8 @@ write_proxy_secrets() {
|
|||||||
local dn="$CFG_BASE_DN"
|
local dn="$CFG_BASE_DN"
|
||||||
cat > "$CONFIG_DIR/proxy-secrets.js" <<PROXYEOF
|
cat > "$CONFIG_DIR/proxy-secrets.js" <<PROXYEOF
|
||||||
'use strict';
|
'use strict';
|
||||||
// Generated by setup.sh. The proxy reads this via @simpleworkjs/conf (symlinked
|
// Generated by setup.sh. The proxy reads this via @simpleworkjs/conf (CONF_SECRETS
|
||||||
// to conf/secrets.js). clientId/clientSecret are filled in by the bootstrap
|
// env var). clientId/clientSecret are filled in by the bootstrap
|
||||||
// (run by ./setup.sh) — leave them as-is. ldap.bindPassword MUST equal
|
// (run by ./setup.sh) — leave them as-is. ldap.bindPassword MUST equal
|
||||||
// serviceAccountPass in sso-secrets.js (the proxy binds as that account).
|
// serviceAccountPass in sso-secrets.js (the proxy binds as that account).
|
||||||
|
|
||||||
|
|||||||
+1
-1
Submodule sso-manager-node updated: 47a9f6c3ec...c5a2c0a71d
Reference in New Issue
Block a user