Files
theta-suite/docs/standalone.md
T
wmantly b43c3d0d1d 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>
2026-07-13 23:10:55 -04:00

5.0 KiB

layout, title
layout title
default Standalone

Running each project standalone

← Back to Home

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:

git clone https://github.com/theta42/sso-manager-node.git
cd sso-manager-node
mkdir -p config && cp secrets.js.example config/sso-secrets.js   # edit it
docker compose up -d --build

The entrypoint symlinks config/sso-secrets.js to nodejs/conf/secrets.js so @simpleworkjs/conf reads it. Set ldap.bindPassword, oauth.jwtSecret, and 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 your file.

  • Web UI: http://localhost:3001
  • Health: http://localhost:3001/health
  • OIDC discovery: http://localhost:3001/.well-known/openid-configuration
  • LDAPS: ldaps://<host>:636

Requires @simpleworkjs/conf >= 1.1.0. Full reference: SSO Manager deployment docs.

Bare metal

sudo ./install.sh -p 'your-ldap-password' -b 'dc=yourdomain,dc=com' -n 'Your Org' -o 3001
sudo systemctl enable --now sso-manager

Idempotent — re-run to update. See the SSO Manager deployment guide.


Proxy alone

The all-in-one image (Dockerfile) bundles OpenResty + the Node app + Redis:

git clone https://github.com/theta42/proxy.git
cd proxy
mkdir -p config && cp secrets.js.example config/proxy-secrets.js   # edit it
docker compose up -d --build

The entrypoint symlinks config/proxy-secrets.js to nodejs/conf/secrets.js so @simpleworkjs/conf reads it. Fill in oidc (your SSO's endpoints + clientId/clientSecret/redirectUri), ldap (bind creds + search base), and auth (admin groups/users). Pass no app_* env — env beats secrets.js, so app_* would silently override your file.

  • Proxy (public, auto-SSL): https://<host>/
  • Mgmt UI / API: http://127.0.0.1:3000/
  • Health: http://127.0.0.1:3000/health

Requires @simpleworkjs/conf >= 1.1.0. Full reference: proxy deployment docs.

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

wget -O - https://raw.githubusercontent.com/theta42/proxy/master/ops/install.sh | sudo bash

See the proxy Docker guide / installation guide.


Mixing and matching

theta-env isn't required to use the two together — the four wiring steps are documented in both projects' deployment guides:

  1. One Docker network (or reachable hostnames) so the proxy can reach the SSO internally for token/userinfo + LDAPS.
  2. Set the SSO's oauth.issuer (in its secrets.js) to the browser-facing HTTPS URL the proxy serves the SSO at.
  3. Register the proxy as an OIDC client in the SSO, with redirectUri matching the proxy's callback; put the resulting clientId/clientSecret in the proxy's secrets.js.
  4. Point the proxy's ldap.url at the SSO's LDAPS + create a dedicated cn=ldapclient service account; set the same password as bindPassword.

theta-env just automates those four steps with ./setup.sh. If you prefer to do them by hand (or want the two on separate hosts), follow the standalone guides above.

← Back to Home