Files
wmantly 5925940936 Fix Directory topology: containers aren't hosts; bump submodules; docs
bootstrap.js no longer creates host_theta-proxy / host_theta-jump as
synthetic kind:'host' resources. Proxy and jump-host are containers running
on the one real stack host, not machines of their own -- and jump-host
resolves its SSH-reachable-hosts list from exactly kind:'host', so the
mistake wasn't just conceptual, it could offer unreachable SSH targets.
Their services now parent directly onto the stack host, like every other
component. Installs seeded between 2026-08-05 and this release self-heal on
the next ./setup.sh run: existing children are re-parented off the
synthetic hosts and the now-empty synthetic hosts are removed. Validated
live against a running instance carrying the exact bad state.

Bumps submodules to sso-manager-node v1.30.2, proxy v1.35.1,
jump-host v1.19.1.

Also: README's architecture diagram + repo layout were stale (2-service
view predating jump-host/OpenBao, 2 of 5 submodules listed); new
docs/fixtures.md + docs/screenshots.md + bootstrap/seed-demo-users.sh for
consistent, repeatable demo data and screenshot passes.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0113gCdnfSCuZr6xvPDxTo3D
2026-08-06 21:38:48 -04:00

176 lines
8.2 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
title: Canonical demo fixtures
---
# Canonical demo fixtures
The exact users, groups, and hosts that should exist on a stack used for
screenshots or demos, so every future pass seeds the *same* data and a
screenshot diff only shows what actually changed in the UI — not incidental
differences in who/what happened to exist that day.
Persona: a single admin/power-user running theta42 across a **big homelab and
a small business** — mix of self-hosted infra (Proxmox, Pi-hole, Plex) and
office-y apps (invoicing, helpdesk, wiki) with real department structure.
Domain: `laptop-dev.vm42.us` (real public DNS pointing at this machine — see
"Domain" below). Update this doc if the domain ever changes again.
## Users
| uid | Name | Department | Password | Notes |
|---|---|---|---|---|
| `schen` | Sarah Chen | Engineering | `DemoPass123!` | DevOps lead |
| `dkim` | David Kim | Engineering | `DemoPass123!` | Backend developer |
| `ppatel` | Priya Patel | Engineering | `DemoPass123!` | Frontend developer |
| `mjohnson` | Marcus Johnson | Finance | `DemoPass123!` | Finance manager |
| `lnguyen` | Linda Nguyen | Finance | `DemoPass123!` | Bookkeeper |
| `erodriguez` | Emily Rodriguez | Support | `DemoPass123!` | Support lead |
| `tbaker` | Tom Baker | Support | `DemoPass123!` | Support tech |
| `jwilson` | James Wilson | Management | `DemoPass123!` | Owner |
| `svc-monitoring` | — | service account | `ServiceAcct!2024` | Grafana/Prometheus scraping |
| `svc-backup` | — | service account | `ServiceAcct!2024` | Backup automation |
uidNumbers 50005009 in that order. Mail is `<first>.<last>@laptop-dev.vm42.us`
(service accounts use their uid, e.g. `monitoring@laptop-dev.vm42.us`).
## Groups
`groupOfNames`, owned by `cn=admin,...`, member of the department's users:
- `engineering` — schen, dkim, ppatel
- `finance` — mjohnson, lnguyen
- `support` — erodriguez, tbaker
- `management` — jwilson
- `app_sso_service_account` (built-in) — svc-monitoring, svc-backup
## Seeding users + groups
```sh
cd theta-env
docker cp bootstrap/seed-demo-users.sh sso-manager:/tmp/seed-demo-users.sh
docker compose exec -T sso-manager bash /tmp/seed-demo-users.sh
```
Idempotent — re-running skips anything that already exists. If you add a
fixture below, add it to `bootstrap/seed-demo-users.sh` too and keep the two
in sync.
## Proxy hosts
All under `*.laptop-dev.vm42.us`. `setup.sh` itself creates the first two
(sso, proxy) — everything else below is added by hand through Hosts → Add
host (Proxy UI, currently no seed script — see note at the bottom).
| Host | Target | Auth | Notes |
|---|---|---|---|
| `sso` | `sso-manager:3001` | — | created by `setup.sh` |
| `proxy` | `127.0.0.1:3000` | — | created by `setup.sh` |
| `jump` | `jump-host:3002` | — | created by `setup.sh` |
| `proxmox` | `10.0.10.5:8006` (HTTPS) | Basic — realm "Proxmox VE", users `dkim`, `schen` | |
| `pbs` | `10.0.10.6:8007` (HTTPS) | Basic — realm "Proxmox Backup Server", user `dkim` | |
| `grafana` | `10.0.10.12:3000` + LB target `10.0.10.13:3000` | SSO — group `engineering` | load-balancing example |
| `nextcloud` | `10.0.10.20:80` | SSO — any authenticated user | empty allow-lists |
| `ha` | `10.0.10.30:8123` | Basic — realm "Home Assistant", user `jwilson` | |
| `jenkins` | `10.0.10.40:8080` | SSO — group `engineering` | |
| `gitea` | `10.0.10.41:3000` | Off (public) | has its own login |
| `plex` | `10.0.10.50:32400` | Off (public) | has its own login |
| `nas` | `10.0.10.60:5001` (HTTPS) | Basic — realm "Synology NAS", user `jwilson` | |
| `pihole` | `10.0.10.61:80` | Basic — realm "Pi-hole Admin", user `dkim` | |
| `wiki` | `10.0.10.70:3000` | SSO — any authenticated user | |
| `invoices` | `10.0.10.80:8000` | SSO — group `finance` | small-business flavor |
| `helpdesk` | `10.0.10.81:3000` | SSO — group `support` | small-business flavor |
Basic-auth passwords used: `dkim:HomeLab!2024`, `schen:Engineering!24`,
`jwilson:HomeOwner!24`.
## Domain
`CFG_DOMAIN=laptop-dev.vm42.us` in `setup.env`, real public DNS (CNAME
through `718it.biz`) that resolves back to this machine. `CFG_LDAPS_HOST`
is pinned to the LAN IP of the interface holding the default route
(`ip route get 1.1.1.1`), not just any active interface — this machine had
two (wifi + USB ethernet) and only one was actually externally reachable
through the existing port-forward/prod-proxy setup.
A production reverse proxy in front of this host handles TLS/ACME for
`*.718it.biz`-family domains (to avoid hitting Let's Encrypt's rate limits
re-provisioning a cert every time this dev stack rebuilds) — if a fresh
rebuild's Host records don't resolve correctly from the public domain right
after `setup.sh`, that's the layer to check, not this stack's own nginx/lua
routing. `curl -sk -D - https://sso.laptop-dev.vm42.us/` from the host
machine is the fastest way to confirm whether the issue is server-side.
## Known-good login shortcuts
Skip SSO's self-signed-cert dance entirely for admin/screenshot work — every
app ships a local anti-lockout admin account for exactly this:
```sh
# SSO Manager admin (bootstrap account, uid "admin")
node -e "console.log(require('./config/sso-secrets.js').bootstrap.adminPass)"
# Proxy — username proxyadmin2
node -e "console.log(require('./config/proxy-secrets.js').auth.localAdminPass)"
# Jump-host — username jumpadmin
node -e "console.log(require('./config/jump-secrets.js').auth.localAdminPass)"
```
Ports (from `setup.env` — check it, these are operator-configurable):
SSO `3001`, Proxy management UI `3010` (`MGMT_PORT`), Jump-host `3002`.
A freshly-bootstrapped `admin` account hits the onboarding flow (accept ToS,
enter a DOB) before the rest of the UI is usable — expect that on a stack
that was just rebuilt from scratch.
## Jump-host access (SSO Directory resource)
Jump-host's dashboard ("Hosts you can reach") is **not** driven by Proxy's
Host records — it resolves access via the SSO Manager's own Directory
(`kind: host` resources), filtered by the logged-in user's LDAP group
membership. This is a completely separate system from Proxy's HTTP-routing
hosts above; a Proxy host existing does not make it SSH-reachable through
jump-host.
For a `dkim`-can-reach-something screenshot, one Directory host resource was
added:
- **Directory → Add Resource**: name `proxmox-node`, kind `Host`, IP
`10.0.10.5`, parent resource `local (site_local)`.
- **Associated LDAP Groups → `site_local_host_proxmox-node_access`
Members → Add member → `dkim`** (added the individual user directly, not
the `engineering` group — the resource's own auto-generated `_access`
group's member picker only offers individual users).
To reproduce: repeat those two steps for `proxmox-node` if it's missing, or
add more Directory host resources the same way for a richer "Hosts you can
reach" list.
**To screenshot as a real fixture user** (not the `jumpadmin` local
anti-lockout admin, whose "My hosts" list is always non-empty by virtue of
infra ownership, not a real access grant): log out, click "Log in with
Jump" on the login page, and sign in as `dkim` / `DemoPass123!` through the
real SSO flow. This exercises the actual OIDC redirect through
`sso.laptop-dev.vm42.us` — by this point in the session it worked cleanly in
the browser; if it doesn't (stale cookies/redirect loop from an earlier bad
state), see `docs/screenshots.md` §2 for the fallback.
## What's not yet automated
Proxy hosts are still added by hand (no `seed-demo-hosts.sh` equivalent) —
the Proxy UI has no simple LDIF-style bulk-import path the way LDAP does, and
scripting it means either driving the browser or reverse-engineering the
session-cookie login flow for curl. If this list changes often enough to be
annoying, that's the next thing worth building — a small node script run via
`docker compose exec proxy node ...` calling the `Host` model directly,
mirroring how `setup.sh`'s own step 7 registers the sso/proxy hosts.
## Screenshot workflow
See `docs/screenshots.md` for the full screenshot-capture workflow
(save-to-disk, where each doc image lives, the app.modal.js browser-cache
gotcha). Once fixtures match this doc, only re-screenshot pages whose UI
actually changed since the last pass — the data itself shouldn't be the
reason a screenshot looks different.