wmantly a0964ce350 feat(multi-site): route replication traffic over the mesh when available
Cross-component routing TODO item: a spoke's resync push now prefers
its WG mesh IP (reported via the noInbound/meshIp fields added for the
relay automation) over the public endpoint, falling back to the public
endpoint if the mesh attempt fails for any reason (tunnel not actually
up between these two particular gateways yet, transient failure,
etc.) -- a mesh-routing preference must never turn into "spoke stops
getting updates."

Plain HTTP over the mesh IP, not HTTPS: the WG tunnel is already
encrypted, same reasoning already applied to the no-inbound relay
terminating at the master.

A spoke with no meshIp on file behaves exactly as before (public
endpoint only) -- this is additive, not a behavior change for spokes
that haven't opted into mesh registration.
2026-08-10 20:39:27 -04:00

Theta Directory

A production-grade, self-hosted OpenID Connect provider, Resource Directory & IAM Engine, and bundled OpenLDAP directory with a modern web console — designed for home-labs and enterprise infrastructure that demand total sovereignty over their identity, secrets, and resource catalog.

It provides a single source of truth for identity (OIDC + LDAP), host/service directory inventory, access control groups, and secrets management running entirely on your own hardware without third-party cloud lock-in.

Theta Directory is deployed as part of Theta Suite, alongside Theta Proxy and Theta Gateway — it isn't installed or run on its own. ./setup.sh wires the whole stack together automatically.

Documentation: https://theta42.github.io/theta-suite/sso/

Screenshots

Dashboard Users
Dashboard User list
Groups OAuth Apps
Groups OAuth clients
Sites & Replication
Sites
Agent Capabilities & Metrics Agent Install (Join Key)
Agent capabilities & metrics Agent install with join key

Features

  • OpenID Connect / OAuth 2.0 provider — issue your own access, refresh, and ID tokens; protect your apps with standard OIDC login. Discovery document at /.well-known/openid-configuration.
  • Bundled OpenLDAP directory — users, groups, POSIX accounts (posixAccount/inetOrgPerson), SSH public keys, and sudo roles, with memberOf + referential-integrity overlays. This is your single source of truth for identity, not a sidecar.
  • Web management UI — manage users, groups, and OAuth clients from a browser; invite and password-reset flows over email; user self-service for profile and API tokens.
  • Direct LDAP binds — Linux hosts (PAM/SSSD login, LDAP-backed sudo rules, SSH public keys via openssh-lpk) and LDAP-native apps (Gitea, Emby, and anything else that speaks LDAP) use LDAPS (636) or StartTLS against the same directory, so you don't maintain a second user database for them.
  • Personal access tokens — any user can mint a long-lived bearer token to drive the management API from scripts or CI, scoped to their own permissions.
  • Directory & Inventory Graph — full host/service/site graph with resource metadata, automatic LDAP group provisioning (_access / _admin), and Access Request workflows.
  • Subtype Management & Metrics Drivers Engine — 4-tier resolution engine binding subType metadata (systemd, docker, proxmox, wireguard, postgresql, redis, k8s) to operational telemetry, log streaming, and remote lifecycle control.
  • Explicit Secret Inheritance Mode — OpenBao KV-v2 integration with strict upward ancestor lineage (Resource -> Host -> Cluster -> Site), preserving precise secret scoping across services and containers.
  • Multi-Site Support (Geo-Location Scaling) — built-in support for N-Way Multi-Master OpenLDAP replication across physical sites for HA and low latency.

Secrets

Secrets are loaded from OpenBao at boot via @simpleworkjs/bao-conf, which deep-merges secret/sso-manager/conf over the file-loaded config (fail-soft: if OpenBao is unreachable, boot continues from CONF_SECRETS). The SSO authenticates to OpenBao with the scoped VAULT_TOKEN (env, policy sso-broker) — never the root token.

The SSO also acts as the vault broker for the whole stack: it mints per-user (user-<uid>) and per-admin (sso-admin) tokens through the sso-broker token role and exposes the personal-secrets UI at Vault → My Secrets (secret/users/<uid>/*, server-side token injection + path-scope guard) and an admin Apps tab to mint scoped tokens for external apps (secret/apps/<name>/*). The old utils/conf_manager.js was replaced by @simpleworkjs/bao-conf; the admin Configuration UI (/api/conf) now writes secret/sso-manager/conf through bao-conf.set.

The config/*-secrets.js files are operator-edit seed artifacts (gitignored), not the authoritative store. For the full architecture, policies, token model, and rotation procedure, see theta-suite's Secrets docs.

Architecture

┌─────────────┐
│  Browser /  │
│  OIDC apps  │
└──────┬──────┘
       │ HTTP/HTTPS
       ▼
┌────────────────────────┐      ┌─────────────┐
│  Theta Directory       │◄────►│   Redis     │
│  - OIDC provider       │      │ - sessions  │
│  - web UI (:3001)      │      │ - models    │
│  - management API      │      └─────────────┘
└────────┬───────────────┘
         │ ldapi/ldap (localhost)
         ▼
┌────────────────────────┐
│  OpenLDAP (slapd)      │
│  - users / groups      │
│  - LDAPS :636          │─── Linux hosts + LDAP apps bind directly
│  - StartTLS :389       │
└────────────────────────┘

Documentation

The nitty LDAP details (overlay setup, the custom theta42Person schema, the required groups, LDAPS/TLS, direct-bind service accounts) live in:

  • DEPLOYMENT.md — Docker + bare metal, the config layers, the app_* env reference, LDAPS/TLS, backups, troubleshooting.
  • API.md — the management API.
  • docs/ — the same content broken into OAuth/OIDC and LDAP, also published at the unified theta-suite docs site.
  • CHANGELOG.md — what changed in each release.
  • All of the above is also readable from the running app itself at /docs — no internet access required.

License

MIT — see LICENSE.

S
Description
LDAP GUI and API manager for use with SSO.
Readme MIT 58 MiB
Languages
JavaScript 63.6%
EJS 31%
Shell 5.2%
CSS 0.2%