Skip to content

Releases: theta42/theta-suite

v1.34.5

Choose a tag to compare

@wmantly wmantly released this 03 Aug 00:04
1d14fce

Automatically build and install theta-agent on the host system as a systemd service during setup.sh. Added CFG_CREATE_ALL_HTTP option to setup.env.

v1.34.4

Choose a tag to compare

@wmantly wmantly released this 02 Aug 23:48
30609de

Updated sso-manager-node submodule to v1.19.6 to pull in a fix for the Vault API 403 error on the Secrets List.

v1.34.3

Choose a tag to compare

@wmantly wmantly released this 02 Aug 23:09
925ac02

Update submodules to latest versions and fix setup script issues

v1.34.2

Choose a tag to compare

@wmantly wmantly released this 02 Aug 18:12
2785b86

What's Changed

  • chore: update submodules to v1.19.4 and v1.14.2 by @wmantly in #136

Full Changelog: v1.34.1...v1.34.2

v1.34.1

Choose a tag to compare

@wmantly wmantly released this 02 Aug 17:25
9c3cbb0

What's Changed

Full Changelog: v1.34.0...v1.34.1

v1.33.0

Choose a tag to compare

@wmantly wmantly released this 02 Aug 04:39

chore: bump submodules for OpenBao secret integration

v1.31.1: sso v1.17.2 + /vault policy fix (setup.sh)

Choose a tag to compare

@wmantly wmantly released this 02 Aug 02:56
6de31aa

[v1.31.1] - 2026-08-01

Pairs the sso v1.17.2 post-deploy fixes with the theta-suite half of the
/vault secrets-list 403 fix (the sso-admin OpenBao policy grant that lives
in setup.sh), and rolls the sso-manager-node submodule gitlink to v1.17.2.
proxy (v1.13.1), jump-host (v1.14.1), and ldap-client (v1.23.0) are
unchanged.

Changed (theta-suite)

  • setup.shsso-admin policy: added a list grant on the bare KV mount
    root secret/metadata so an admin can list the top-level dirs in the /vault
    UI. secret/metadata/* already covered nested paths, but not the mount root
    itself — so the secrets list 403'd. (The matching per-user/per-app directory
    grants ship in sso v1.17.2's vault_broker.js.)
  • setup.shensure_policy: now always (re)writes the policy instead of
    skipping when it exists. bao policy write is an idempotent overwrite, so a
    re-run applies policy edits (like the new grant above) instead of stranding
    the old HCL with "already exists — keeping."

Changed (submodule gitlinks)

  • sso-manager-node: v1.17.1v1.17.2 — the post-deploy fixes (auto-slug
    plugins, schedule dropdown, /profile rendering, plugin-edit persistence,
    nmap in the image, the sso-side /vault policy grants) plus the SMS (VoIP.ms)
    and Terms-of-Service configuration on /conf. Full changelog below.

Deploy

Operators upgrading from v1.31.0:

  1. git pull and git submodule update --init --recursive.
  2. Re-run ./setup.shrequired: applies the new sso-admin
    secret/metadata list grant and the ensure_policy always-write refresh
    (idempotent). Per-user vault policies self-heal on the next /vault visit
    (sso v1.17.2 re-writes them).
  3. docker compose build && docker compose up -d — the rebuild installs nmap
    in the sso image (fixes the nmap plugin "not found" error).

Bundled submodule release notes

sso-manager-node v1.17.2 — post-deploy fixes + SMS/TOS on /conf

Post-deploy fixes from testing the v1.31.0 stack, plus the SMS (VoIP.ms) and
Terms-of-Service configuration the /conf page was missing.

Fixed
  • Plugin slug is now auto-generated from the instance name — the New Plugin
    modal no longer asks for a Slug (it derives a stable, unique handle from the
    name, appending -2, -3, … on collision). The generated slug still shows in
    the table and the Edit (read-only) modal. POST /api/plugins slug is now
    optional; an explicit slug is still accepted and validated.
  • Plugin schedule is a dropdown, not a raw cron box: Hourly / Daily /
    Weekly, plus Custom which reveals the raw 5-field cron input. Stored value
    is still a cron string, so the server is unchanged.
  • /vault secrets list no longer 403s. The per-user, per-app, and admin
    OpenBao policies granted list only on secret/metadata/.../* (nested
    paths), never on the directory path itself — so listing a directory's
    contents (which checks list on the directory, e.g.
    secret/metadata/users/<uid> or the mount root secret/metadata) was denied.
    vault_broker.js's userPolicyHcl/appPolicyHcl now also grant list on the
    bare directory path, and ensurePolicy now always re-writes the policy
    (idempotent) so already-created user-<uid> policies pick up the new grant on
    the next vault-page visit. The matching sso-admin mount-root grant ships in
    theta-suite v1.31.1 (setup.sh), where ensure_policy is likewise made
    always-write so re-running ./setup.sh applies policy edits.
  • /profile no longer shows literal {{…}} tags. Three template fragments
    sat outside the jq-repeat="user" scope, so they rendered raw: the card
    header Profile: {{user.uid}}, the Members of {{user.uid}}'s Group tab
    label, and the Admin Actions block's {{#isActive}}/{{#isInactive}}
    buttons. The header/label are now populated by JS (the Members label
    already had a setter pointing at a missing id); the Admin Actions block is
    moved inside the scope so {{uid}}/{{#isActive}}/{{#isInactive}} render
    and the correct Activate/Deactivate button shows.
  • Editing a plugin now persists. The Edit modal had been prefilled with the
    masked secret values and rendered them as fields, but PUT /:id only saves
    non-secret config — so an edited secret was silently dropped. The Edit modal
    now shows non-secret fields only (secrets have their own Edit-Secrets
    modal), removing the confusion.
  • nmap plugin: "NMAP not found at command location: nmap" — the nmap
    binary was not installed in the app image. Dockerfile.openldap now apk adds nmap in the runtime stage, and plugins/discovery/nmap.js translates
    the opaque node-nmap spawn-missing error into an actionable lastError.
Added
  • SMS (VoIP.ms) configuration on /conf. The existing VoIP.ms SMS sender
    (models/sms.js, used for 2FA OTP delivery) was configurable only via env /
    config files. It now has an SMS card on /conf (API username, DID, API
    password), saved to OpenBao at secret/sso-manager/conf under voipms, with
    the API password masked (********) and leave-blank-to-keep — mirroring the
    SMTP card exactly. models/sms.js reads conf.voipms.* at call time, so a
    saved change takes effect live without a restart.
  • Terms of Service editor moved to /conf from the admin Overview
    dashboard, where it never belonged. The same app.tos.get/update flow,
    the "require all users to re-accept" checkbox, and the app_sso_admin gate
    (matching routes/tos.js's PUT gate) are preserved. The Overview page keeps
    stats, notifications, and metrics.

[v1.31.0] - 2026-08-01

v1.31.0 — roll up submodules (sso v1.17.1 + ldap-client v1.23.0)

Choose a tag to compare

@wmantly wmantly released this 02 Aug 01:27
e2e8143

[v1.31.0] - 2026-08-01

Roll-up release: bumps the composed submodules to their latest tags so a fresh
git clone + ./setup.sh deploys the SSO Manager plugin system, the /conf
SMTP/OAuth secret masking, and the ldap-client changelog. proxy (v1.13.1) and
jump-host (v1.14.1) were already at latest and are unchanged.

Changed (submodule gitlinks)

  • sso-manager-node: v1.16.1v1.17.1 (the plugin system shipped in
    v1.17.0, plus the v1.17.1 /conf secret-masking hardening).
  • ldap-client: v1.1.1v1.23.0 — a CHANGELOG-only release (the new
    CHANGELOG.md documenting v1.1.0/v1.0.0; no code change — the "UI polish"
    tag message is misleading, the v1.1.1…v1.23.0 diff is CHANGELOG.md only).

Deploy

Operators upgrading from a prior release:

  1. git pull and git submodule update --init --recursive (or a fresh clone).
  2. Re-run ./setup.sh — this is required if you haven't yet applied the
    v1.30.1 sso-broker OpenBao policy grant for secret/plugins/* (idempotent;
    it grants the existing SSO_VAULT_TOKEN access live, so plugin-secrets
    storage works).
  3. docker compose build && docker compose up -d. Existing
    conf.discovery.plugins setups auto-migrate into PluginInstance rows +
    OpenBao secrets on first boot of sso v1.17.x.

Bundled submodule release notes

sso-manager-node v1.17.0 — real plugin system (loadable instances + OpenBao secrets)

[1.17.0] - 2026-08-01

A real plugin system: the half-built discovery plugins (statically
configured in sso-secrets.js, only toggleable for cron/enabled) become
configurable, loadable/unloadable plugin instances you manage from a
dedicated Plugins page and the /api/plugins API, with multiple runtime
copies of each type and per-instance secrets stored in OpenBao.

Added

  • Plugin instances — a new PluginInstance ORM model
    (nodejs/models/plugin_instance.js, Sequelize) is the registry of
    configured, scheduled plugin copies. Each has a pluginType, a unique
    slug (the discovery source name), a cron schedule, an enabled flag
    (load/unload), non-secret config (JSON), and last-run bookkeeping. Multiple
    instances of the same type are supported.
  • Plugin registry (nodejs/services/plugin_registry.js) — generalizes the
    one-shot discovery-plugin scan in scheduler.js. Plugin types are modules
    under nodejs/plugins/<category>/<type>.js exporting a manifest
    (type, category, name, description, configSchema, validate,
    run/discover). Exposes getTypes, getModule, splitConfig (secret vs
    non-secret), mask, and required-field helpers for the UI/API.
  • Per-instance secrets in OpenBao (nodejs/utils/plugin_secrets.js) —
    configSchema fields flagged secret:true (e.g. a Proxmox tokenSecret,
    UniFi password) are stored at secret/plugins/<instance-id>/conf, never in
    the DB. The UI only ever sees masked (********) values. Plugins run
    in-process (BullMQ workers), so they need no OpenBao token of their own — the
    SSO reads/writes via the sso-broker token. Requires theta-suite ≥ v1.30.1
    for the sso-broker policy grant on secret/plugins/*; the API fails-soft
    with a clear error if absent.
  • /api/plugins API (nodejs/routes/api_plugins.js, replaces the old
    routes/plugins.js) — GET /types, list/get/create/update/update-secrets/
    test/load/unload/run/delete/runs. Admin-only
    (app_sso_admin / app_sso_directory_admin / app_super_admin).
  • Plugins page (/plugins, views/plugins.ejs) + nav entry — instance
    table with New/Edit/Edit-Secrets/Test/Run-now/Load/Unload/Delete, config forms
    rendered from each type's configSchema.
  • validate ("Test" button) on the built-in Proxmox/UniFi/Nmap plugins.

Changed

  • services/scheduler.js now schedules from the PluginInstance table instead
    of static conf.discovery.plugins + a Redis override hash. Each instance owns
    a stable BullMQ JobScheduler id (plugin:<instanceId>) so load/unload
    upsert/remove one schedule without disturbing the rest. Discovery plugins
    reconcile results under the instance's slug.
  • The three discovery plugins (plugins/discovery/{proxmox,unifi,nmap}.js)
    gained manifests (configSchema, validate, run alias). nmap's
    targetRange is non-secret; Proxmox tokenSecret and UniFi password are
    secret.
  • The /plugins page route renders the page instead of redirecting to
    /directory; the Agents & Scheduler tab was removed from /directory
    (plugins are now managed on the Plugins page). The /docs/agents link is
    aliased to /docs/plugins.
  • docs/plugins.md, docs/vault.md, docs/_config.yml (nav), and API.md
    (Plugin Endpoints section) document the new system.

Legacy migration

On first boot of v1.17.0, if the PluginInstance table is empty and
conf.discovery.plugins has entries, one instance per configured type is seeded
automatically (secret fields copied into OpenBao). After that the static
config is ignored — manage plugins from the UI/API. Idempotent (guarded by the
empty-table check).

Prerequisite

theta-suite ≥ v1.30.1 — re-run ./setup.sh after upgrading so the
sso-broker OpenBao policy is granted secret/plugins/*. Without it, storing
plugin secrets fails with a clear error.

sso-manager-node v1.17.1 — mask SMTP/OAuth secrets + leave-blank-to-keep on /conf

[1.17.1] - 2026-08-01

Hardens the runtime SMTP/OAuth secret handling on the /conf admin page to
match the plugin-secrets discipline: the SMTP password and OAuth JWT secret are
no longer returned in cleartext by GET /api/conf or round-tripped through the
form. They remain saved in OpenBao at secret/sso-manager/conf at runtime
(unchanged) — only how they're surfaced to the admin changes.

Changed

  • GET /api/conf now masks smtp.pass and oauth.jwtSecret to ********
    (was: returned in cleartext). Non-secret fields (host, port, user, from,
    secure, issuer, token lifetimes) are returned as before.
  • POST /api/conf now treats a blank or ******** secret-field submission
    as "keep the current stored value" — so an admin editing the From address or
    token lifetimes no longer has to re-enter (or leak) the SMTP password / JWT
    secret. Only a genuinely new, non-blank value overwrites. The preserved values
    are re-applied to live conf immediately, as before.
  • /conf page (views/conf.ejs): the Password and JWT Secret fields carry
    a "leave unchanged to keep the current value stored in OpenBao" hint; the page
    copy notes secret fields are masked. No JSON-textarea editing is involved —
    SMTP is and remains configured through structured form fields.

Notes

  • SMTP (and OAuth) config was already saved to OpenBao at runtime before
    this release (via POST /api/confbaoConf.set('sso-manager/conf'), and
    overlaid back at boot by bao-conf.init). This release closes the
    cleartext-exposure gap; it does not move the storage path.
  • No theta-suite policy change required — secret/sso-manager/conf was already
    granted to the sso-broker policy.

ldap-client v1.23.0 — CHANGELOG-only (no code change)

Adds a CHANGELOG.md documenting v1.1.0 (app_super_admin / app_jump_admin
group support in SSSD access filters; the sso/jump-host TLS-validation
divergence) and v1.0.0 (initial SSSD LDAP auth release). No source changes vs
v1.1.1; the v1.23.0 tag commit only adds this file.

v1.30.1 — sso-broker OpenBao access to secret/plugins/*

Choose a tag to compare

@wmantly wmantly released this 02 Aug 00:50
1185bb9

[v1.30.1] - 2026-08-01

Prerequisite release for the SSO Manager plugin system (shipped in
sso-manager-node v1.17.0). Grants the sso-broker OpenBao policy access to the
new per-instance plugin secrets namespace so the SSO can store plugin secrets in
OpenBao instead of sso-secrets.js.

Changed (theta-suite orchestration)

  • setup.sh: added secret/data/plugins/* (CRUD+list) and
    secret/metadata/plugins/* (list/read/delete) to the sso-broker policy
    HCL. ensure_policy sso-broker is idempotent, so re-running ./setup.sh
    immediately grants the existing SSO_VAULT_TOKEN access to secret/plugins/*
    (policies are evaluated live; the token keeps its id). The SSO side fails-soft
    with a clear error if this grant is absent.
  • Docs: docs/secrets.md (new "Plugin secrets" section + sso-broker
    policy row) and docs/architecture.md (sso-manager access row) now list
    secret/plugins/*.

The plugin system itself (configurable plugin instances, load/unload, UI/API,
multi-copy, secrets in OpenBao) is in sso-manager-node v1.17.0; theta-suite
will bump its submodule gitlink to that release next.

v1.30.0 — renamed to theta-suite

Choose a tag to compare

@wmantly wmantly released this 01 Aug 22:47
3287777

[v1.30.0] - 2026-08-01

The project is renamed theta-env → theta-suite — it has grown from a
docker-compose wiring two projects into an integrated suite of four
applications around a shared OpenBao secrets store, and the name should reflect
that. The GitHub repository is renamed theta42/theta-env
theta42/theta-suite (old URLs redirect), and the docs site moves to
https://theta42.github.io/theta-suite/.

Changed (theta-suite orchestration)

  • Renamed theta-env → theta-suite across the superproject: docs/_config.yml
    (title + baseurl: /theta-suite + repo URLs), README.md, setup.sh
    (incl. the THETA_SUITE_REEXECED self-update sentinel), docker-compose.yml,
    bootstrap/bootstrap.js, .github/workflows/lint.yml, config.example/*,
    docs/robots.txt, all docs pages, and this changelog.
  • Compose project name note: docker compose derives the project name from
    the clone directory, so named volumes follow it (<project>_openbao-data).
    A fresh git clone of theta-suite uses the theta-suite project name; an
    existing deployment that keeps its theta-env directory keeps its
    theta-env_* volumes — no data migration is required, just don't mix the two.
  • Docs site baseurl is now /theta-suite, matching the renamed repo's
    GitHub Pages URL.

Docs

  • architecture.md rewritten. Replaced the outdated "The two containers"
    / "The three repos" framing with the actual topology — four always-on
    services (openbao, sso-manager, proxy, jump-host) plus the
    ldap-client host-enrollment tool — a real diagram, a full Secrets
    (OpenBao)
    section (central store, scoped per-app policies/tokens, the
    @simpleworkjs/bao-conf boot overlay, per-user KV, external-app minting),
    and an OpenBao-aware "how config reaches the apps". Removed the
    LDAP-"legacy apps" wording (direct LDAP binds are first-class: Linux hosts
    PAM/SSSD, sudo, SSH keys).
  • index.md — integrated-suite framing; added Central secrets (OpenBao)
    and ldap-client to "What you get" and "Related projects".
  • standalone.md + README.md — standalone is now framed as an advanced
    opt-in; the integrated ./setup.sh stack is the supported path.

Submodule bump

  • sso-manager-node → v1.16.1 — fixes the 401 on /conf and /vault for
    a logged-in admin. Both view routes 401'd because this app's auth-token is a
    header set by client JS (localStorage), not a cookie, so req.user is
    undefined on a browser navigation; the routes now render the shell and gate
    client-side (app.auth.forceLogin), with /api/conf + /api/vault still
    enforcing auth + OpenBao scope server-side. See the
    sso v1.16.1 release.