docs: fix quickstart drift, add LICENSE, document admin bypass and LDAPS cert mount for public release (#17)

Cleanup pass ahead of the public release announcement:

- docs/index.md: fix the Quick Start block, which described a stale
  "edit config then re-run setup.sh a second time" flow. setup.sh now
  requires setup.env (with CFG_BASE_DN) before it will do anything, and
  builds + bootstraps + starts in a single run. Updated to match
  README.md's correct 4-line sequence.
- Add a standard MIT LICENSE at the repo root (theta42, 2026) so
  docs/index.md's "MIT License — see the repository for details" claim
  is actually true.
- docs/standalone.md: document the hardcoded auth.adminUsers:
  ['proxyadmin2'] local anti-lockout admin bypass written into every
  generated proxy-secrets.js — what it's for, that it requires a
  matching SSO user to actually use, and how to rename/extend/disable
  it.
- README.md + docker-compose.yml: fix the LDAPS strict-trust security
  note, which implied mounting the SSO's cert into the proxy was a
  config-only change. It also requires a docker-compose.yml edit
  (ldap-certs isn't mounted into the proxy service); added commented-out
  boilerplate for that mount and clarified the doc text.
- Also includes the pre-existing "Why use this instead of running the
  two separately?" README paragraph that was already staged as
  in-progress work.
- Verified: no Vagrant references, no emoji, and no hardcoded
  custom-domain URLs anywhere in this repo outside the proxy/ and
  sso-manager-node/ submodules; no docs/CNAME (github.io URL scheme
  confirmed).
- Added --- section dividers to docs/*.md to match README.md's
  formatting convention.

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-13 23:10:55 -04:00
committed by GitHub
parent 20a586de4f
commit b43c3d0d1d
7 changed files with 119 additions and 4 deletions
+10
View File
@@ -11,6 +11,8 @@ theta-env is a **composition** repo: it builds the two existing projects from
their git submodules and adds the glue that wires them together. It does not
fork or patch them — both projects work unchanged on their own.
---
## The three repos
| Repo | Role |
@@ -22,6 +24,8 @@ fork or patch them — both projects work unchanged on their own.
The two projects are pinned as **git submodules**. `git clone --recursive`
fetches all three in one step; `git submodule update --remote` bumps them.
---
## The two containers
```
@@ -68,6 +72,8 @@ redis instances is the no-source-patch path and is fine at this scale.
| `3001` (sso) | localhost only | SSO web UI (first-run convenience; fronted by the proxy normally) |
| `389` (sso) | **no** | plain LDAP — internal only (app↔slapd over localhost) |
---
## The first-run bootstrap
`./setup.sh` orchestrates first-run wiring; `bootstrap/bootstrap.js` does the
@@ -127,6 +133,8 @@ admin creds from `./config/sso-secrets.js` sidesteps that entirely, and going
through the HTTP API for the OAuth client validates the whole admin login path
end-to-end.
---
## Idempotency
Re-running `./setup.sh` converges to `./config/`:
@@ -139,6 +147,8 @@ Re-running `./setup.sh` converges to `./config/`:
So `setup.sh` is safe to re-run after editing `./config/`, after a `docker
compose down`, or after restoring from backup.
---
## Backups and restore
`./setup.sh` auto-snapshots `./config/` + LDAP + both Redis to
+16 -2
View File
@@ -14,13 +14,15 @@ It exists for people whose needs are met by these two projects and who want to
run them "very simply." Each project still works **standalone**; this repo just
wires them together and automates the first-run glue.
---
## Quick start
```bash
git clone --recursive https://github.com/theta42/theta-env.git
cd theta-env
./setup.sh # generates ./config/ the first time — edit it, then re-run
./setup.sh # builds + bootstraps + starts the stack
cp setup.env.example setup.env # then edit setup.env: set CFG_BASE_DN to your domain
./setup.sh # first run: generates ./config/ from setup.env, builds + bootstraps + starts
```
You need **Docker** + **Docker Compose**. `./setup.sh` is idempotent — re-run any
@@ -30,6 +32,8 @@ See the [Quickstart Guide](quickstart.html) for a walkthrough of `./config/` and
what `setup.sh` does, [Architecture](architecture.html) for how the pieces fit
together, and [Standalone](standalone.html) for running each project on its own.
---
## What you get
- **SSO Manager** at `https://<SSO_HOST>` — log in as your first admin to manage
@@ -44,6 +48,8 @@ together, and [Standalone](standalone.html) for running each project on its own.
creator (carrying their permissions); mint/rotate/revoke under **API Tokens**
in each UI. See each submodule's DEPLOYMENT for the details.
---
## The `./config/` values you must set
All config and secrets live in `./config/sso-secrets.js` +
@@ -62,6 +68,8 @@ There is **no `.env`**. Set at least these in `./config/sso-secrets.js`:
See `config.example/` for the full annotated shape (SMTP, LDAP cert CN, proxy
OIDC/LDAP/auth, …).
---
## Architecture
```
@@ -88,6 +96,8 @@ The proxy is **both** an OIDC client of the SSO (for login) **and** a direct LDA
client (for user lookups). See [Architecture](architecture.html) for the full
diagram + the first-run bootstrap flow.
---
## Documentation
- [Quickstart Guide](quickstart.html) — full walkthrough of `./config/` + `setup.sh`.
@@ -95,11 +105,15 @@ diagram + the first-run bootstrap flow.
design, and how the bootstrap wires the proxy into a fresh SSO.
- [Standalone](standalone.html) — running SSO Manager or the proxy on its own.
---
## Community
- [GitHub Repository](https://github.com/theta42/theta-env)
- [Issue Tracker](https://github.com/theta42/theta-env/issues)
---
## License
MIT License — see the repository for details.
+20
View File
@@ -7,6 +7,8 @@ title: Quickstart
[← Back to Home](index.html)
---
## Prerequisites
- A Linux host with **Docker** + **Docker Compose** (the v2 plugin `docker
@@ -18,6 +20,8 @@ title: Quickstart
certs; otherwise the proxy serves a self-signed fallback (browsers warn —
expected for LAN use).
---
## 1. Clone
```bash
@@ -32,6 +36,8 @@ step. If you forgot it:
git submodule update --init --recursive
```
---
## 2. Configure `setup.env` (enter your domain once)
```bash
@@ -63,6 +69,8 @@ file shape.
> exist, `./setup.sh` migrates them into `./config/` preserving your existing
> secrets — no need to write a `setup.env`.
---
## 3. Run
```bash
@@ -86,6 +94,8 @@ What happens:
The first run builds two Docker images (a few minutes). Subsequent runs are
fast.
---
## 4. Point DNS at the host
`stack.ssoHost` and `stack.proxyHost` (from `./config/sso-secrets.js`) must
@@ -98,6 +108,8 @@ echo "127.0.0.1 sso.lab.local proxy.lab.local" | sudo tee -a /etc/hosts
(The proxy needs port 80 reachable for Let's Encrypt; on a LAN without that it
serves a self-signed cert — browsers will warn, which is fine for home-lab use.)
---
## 5. Log in
Open `https://<SSO_HOST>` and log in as your bootstrap admin
@@ -110,6 +122,8 @@ it). Add the Host records you want to protect with OIDC.
First-run fallbacks (if DNS/TLS isn't ready yet): SSO UI at
`http://127.0.0.1:3001`, proxy UI at `http://127.0.0.1:3000`.
---
## Re-running
`./setup.sh` is **idempotent** — safe to re-run after editing `./config/`, after
@@ -118,6 +132,8 @@ then converges the stack to your `./config/` values (LDAP service account + admi
passwords are reset to the config; the OAuth client is kept if `proxy-secrets.js`
already holds its creds).
---
## Direct LDAP for legacy apps
Legacy apps bind LDAP directly over LDAPS:
@@ -131,6 +147,8 @@ ldapsearch -x -H ldaps://<host>:636 \
Use the `cn=ldapclient` service account (read-only, the bootstrap created it)
or the admin DN. Use LDAPS (636), not plain LDAP.
---
## Backups and restore
`./setup.sh` auto-snapshots `./config/` + LDAP + both Redis to `./backups/<ts>/`
@@ -145,6 +163,8 @@ docker compose exec sso-manager slapcat -f /etc/openldap/slapd.conf \
-b "<base>" > backup-$(date +%F).ldif
```
---
## Next steps
- Add users / groups in the SSO UI.
+33
View File
@@ -11,6 +11,8 @@ theta-env composes the two projects but doesn't fork them — both work on their
own. The submodules in this repo are normal clones; you can also clone them
directly from GitHub.
---
## SSO Manager alone
The all-in-one image (`Dockerfile.openldap`) bundles the app + OpenLDAP + Redis:
@@ -46,6 +48,8 @@ sudo systemctl enable --now sso-manager
Idempotent — re-run to update. See the SSO Manager
[deployment guide](https://theta42.github.io/sso-manager-node/deployment.html).
---
## Proxy alone
The all-in-one image (`Dockerfile`) bundles OpenResty + the Node app + Redis:
@@ -70,6 +74,33 @@ so `app_*` would silently override your file.
Requires `@simpleworkjs/conf` >= 1.1.0. Full reference:
[proxy deployment docs](https://theta42.github.io/proxy/docker.html).
### The `auth.adminUsers` anti-lockout account
Both `setup.sh` and `config.example/proxy-secrets.js.example` write
`auth.adminUsers: ['proxyadmin2']` into `proxy-secrets.js`. This is a
**local, config-driven admin bypass** — the proxy grants full admin rights to
any logged-in OIDC user whose username (the `preferred_username` claim from
the SSO) matches an entry in `auth.adminUsers`, regardless of their LDAP group
membership (see `proxy/nodejs/utils/roles.js`, `resolveEffective()`). It exists
so an operator can't lock themselves out of the proxy mgmt UI if the SSO's
`app_sso_admin` group is ever misconfigured, deleted, or otherwise broken.
It is **not** derived from any `setup.env` value, and it does **not** create a
user by itself — the name is only a username match. To actually use the
bypass, create a user with uid `proxyadmin2` in the SSO (it does not need to
be in `app_sso_admin` or any other group) and log in through the proxy as that
user.
To change or disable it, edit `auth.adminUsers` directly in
`./config/proxy-secrets.js` after the first `./setup.sh` run (re-running
`setup.sh` will not overwrite an existing `proxy-secrets.js`):
- **Rename** it to a less guessable username: `adminUsers: ['your-break-glass-uid']`.
- **Add more** anti-lockout accounts: `adminUsers: ['proxyadmin2', 'another-admin']`.
- **Disable** it entirely: `adminUsers: []` (global admin then comes only from
`auth.adminGroups` membership — make sure at least one real admin group is
reachable before doing this).
### Bare metal
```bash
@@ -80,6 +111,8 @@ See the proxy
[Docker guide](https://theta42.github.io/proxy/docker.html) /
[installation guide](https://theta42.github.io/proxy/installation.html).
---
## Mixing and matching
theta-env isn't required to use the two together — the four wiring steps are