Merge pull request #175 from theta42/release/v1.46.0
chore: release v1.46.0
This commit is contained in:
@@ -8,6 +8,17 @@ orchestration code; see each submodule's own `CHANGELOG.md`
|
||||
[sso-manager-node](https://github.com/theta42/sso-manager-node/blob/master/CHANGELOG.md))
|
||||
for what changed inside the apps it composes.
|
||||
|
||||
## [v1.46.0] - 2026-08-07
|
||||
|
||||
Rolls up **theta-agent v1.6.0**, **sso-manager-node v1.31.0**, **jump-host v1.19.1**.
|
||||
|
||||
### Added
|
||||
- **On-demand CLI Secret Fetching.** `theta-agent get-secret <key>` and `theta-agent get-secrets [--env|--json]` for dynamic secret resolution without plaintext files on disk.
|
||||
- **Resource Secrets Engine & Zero-View Security.** OpenBao KV-v2 encrypted secrets for directory resources with strict regex validation (`^[A-Za-z0-9_]+$`), password generator, and multi-level hierarchy secret inheritance.
|
||||
- **OpenBao `sso-broker` Policy.** Granted `secret/data/resources/*` and `secret/metadata/resources/*` permissions to `sso-broker`.
|
||||
- **Zero-Trust LDAP WebSocket Tunnel.** Auto-starts local `/run/theta/ldap.sock` and `127.0.0.1:3890` loopback listeners on managed nodes.
|
||||
- **Agent Self-Update & Service Control.** Added `theta-agent update` and `theta-agent reinitialize` CLI commands with automated service restarts (`sssd`, `sshd`).
|
||||
|
||||
## [v1.45.0] - 2026-08-06
|
||||
|
||||
Rolls up **sso-manager-node v1.30.2**, **proxy v1.35.1**, **jump-host v1.19.1**.
|
||||
|
||||
Vendored
+6
-18
@@ -642,24 +642,12 @@ async function seedDirectory(token, clientId, jumpClientId) {
|
||||
requestable: false,
|
||||
});
|
||||
|
||||
// OpenBao and its renewer sidecar are part of what the stack deploys, so
|
||||
// they belong in the directory like every other component. Without entries
|
||||
// their containers had nowhere to attach and showed up as parentless
|
||||
// discoveries on a fresh install.
|
||||
await ensure('service', 'OpenBao', 'openbao', host.id, {
|
||||
address: 'http://openbao:8200',
|
||||
port: 8200,
|
||||
subType: 'vault',
|
||||
icon: 'mdi:safe',
|
||||
tagline: 'Secrets store for the stack.',
|
||||
requestable: false,
|
||||
});
|
||||
await ensure('service', 'Bao Renewer', 'bao-renewer', host.id, {
|
||||
subType: 'sidecar',
|
||||
icon: 'mdi:autorenew',
|
||||
tagline: 'Renews the stack service tokens against OpenBao.',
|
||||
requestable: false,
|
||||
});
|
||||
// Remove legacy OpenBao/bao-renewer seed resources if present — OpenBao is an
|
||||
// internal stack service, not a user-facing published directory service.
|
||||
const openbaoRes = resources.find((r) => r.slug === 'openbao');
|
||||
const renewerRes = resources.find((r) => r.slug === 'bao-renewer');
|
||||
if (openbaoRes) await dirDelete(token, `resources/${openbaoRes.id}`);
|
||||
if (renewerRes) await dirDelete(token, `resources/${renewerRes.id}`);
|
||||
|
||||
// SSH jump host service (core component — always registered).
|
||||
let jumpSvc = null;
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
title: theta-suite
|
||||
title: Theta Suite
|
||||
description: A unified, one-command SSO Manager + OIDC proxy stack for home labs and small businesses.
|
||||
url: "https://theta42.github.io"
|
||||
baseurl: "/theta-suite"
|
||||
|
||||
@@ -78,10 +78,13 @@ die() { error "$*"; exit 1; }
|
||||
# (stale policies/tokens causing vault 403s). The Redis vault-token cache is
|
||||
# flushed once sso-manager is back up (see the OpenBao bootstrap section).
|
||||
RESET_OPENBAO=0
|
||||
SEED_NODE_SECRET=0
|
||||
SEED_NODE_ARGS=()
|
||||
for arg in "$@"; do
|
||||
case "$arg" in
|
||||
--reset-openbao) RESET_OPENBAO=1 ;;
|
||||
*) warn "unknown argument: $arg (ignored)" ;;
|
||||
--seed-node-secret) SEED_NODE_SECRET=1 ;;
|
||||
*) if [[ "$SEED_NODE_SECRET" == 1 ]]; then SEED_NODE_ARGS+=("$arg"); else warn "unknown argument: $arg (ignored)"; fi ;;
|
||||
esac
|
||||
done
|
||||
|
||||
@@ -878,6 +881,29 @@ seed_app_conf() {
|
||||
|| warn " could not seed secret/${vault_path} (continuing — app will use its file fallback)"
|
||||
}
|
||||
|
||||
# Seed a node-scoped secret for a theta-agent (DESIGN.md §5). Node secrets live
|
||||
# at secret/data/nodes/<agent-id>/* and are read by the agent (via the SSO's
|
||||
# /api/v1/agent/secrets) on behalf of 3rd-party apps on the host. Agent ids are
|
||||
# minted at enrollment, so this is a helper the operator calls per node, not a
|
||||
# boot-time seed:
|
||||
# ./setup.sh --seed-node-secret <agent-id> <name> <key>=<value> [<key>=<value>...]
|
||||
seed_node_conf() {
|
||||
local agent_id="$1" name="$2"; shift 2
|
||||
[[ -n "$agent_id" && -n "$name" ]] || die "seed_node_conf: need <agent-id> <name>"
|
||||
# CLI paths are mount-relative (no "data/" segment -- the CLI inserts that
|
||||
# itself for KV v2, same as seed_app_conf's "secret/${vault_path}" above).
|
||||
# The HTTP API path api_agent_ops.js checks against (secret/data/nodes/...)
|
||||
# is what this resolves to underneath.
|
||||
local path="secret/nodes/${agent_id}/${name}"
|
||||
if bao_run kv get "$path" >/dev/null 2>&1; then
|
||||
info " ${path} already seeded — keeping."
|
||||
return 0
|
||||
fi
|
||||
info "Seeding ${path}..."
|
||||
docker exec -e BAO_TOKEN="$VAULT_TOKEN" openbao bao kv put "$path" "$@" >/dev/null \
|
||||
|| die "failed to seed ${path}"
|
||||
}
|
||||
|
||||
info "Configuring OpenBao policies..."
|
||||
# sso-broker — sso's authority to read/write its own conf, mint per-user and
|
||||
# per-app tokens (auth/token/create/sso-broker), and create the matching
|
||||
@@ -900,6 +926,13 @@ path "secret/metadata/plugins/*" { capabilities = ["list", "read", "delete"] }
|
||||
# a key that changes on every boot makes signature verification meaningless.
|
||||
path "secret/data/agent/*" { capabilities = ["create", "read", "update", "delete", "list"] }
|
||||
path "secret/metadata/agent/*" { capabilities = ["list", "read", "delete"] }
|
||||
# Node-scoped secrets for theta-agent (DESIGN.md §5): each node reads only its
|
||||
# own secret/data/nodes/<agent-id>/* subtree via the SSO's /api/v1/agent/secrets
|
||||
# endpoint. The SSO (sso-broker) must be able to read them on the agent's behalf.
|
||||
path "secret/data/resources/*" { capabilities = ["create", "read", "update", "delete", "list"] }
|
||||
path "secret/metadata/resources/*" { capabilities = ["list", "read", "delete"] }
|
||||
path "secret/data/nodes/*" { capabilities = ["create", "read", "update", "delete", "list"] }
|
||||
path "secret/metadata/nodes/*" { capabilities = ["list", "read", "delete"] }
|
||||
path "auth/token/create/sso-broker" { capabilities = ["update"] }
|
||||
path "auth/token/create/sso-app" { capabilities = ["update"] }
|
||||
path "auth/token/renew-accessor" { capabilities = ["update"] }
|
||||
@@ -980,6 +1013,13 @@ info " policies: sso-broker, sso-admin, proxy, jump-host (+ per-user/app cre
|
||||
info " token roles: sso-broker (user-*/app-*/sso-admin, 24h period), sso-app (app-*, 768h period), theta-svc (service tokens, 768h period)"
|
||||
info " app tokens: SSO_VAULT_TOKEN, PROXY_VAULT_TOKEN, JUMP_VAULT_TOKEN in .env (periodic; renewed by bao-renewer)"
|
||||
|
||||
# --seed-node-secret <agent-id> <name> <key>=<value>... : seed a node-scoped
|
||||
# secret for a theta-agent (DESIGN.md §5). Runs after OpenBao is configured so
|
||||
# the sso-broker policy (which grants secret/data/nodes/*) is in place.
|
||||
if [[ "$SEED_NODE_SECRET" == 1 ]]; then
|
||||
seed_node_conf "${SEED_NODE_ARGS[@]}"
|
||||
fi
|
||||
|
||||
# bao-renewer: renews the three periodic service tokens every 12h so they never
|
||||
# hit their period boundary while the stack is running. Recreated (not just
|
||||
# started) so it always picks up freshly re-minted tokens from .env.
|
||||
|
||||
Reference in New Issue
Block a user