STATUS/plan: phases 5-7 and 11 live and verified; refreshed unfinished list
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
@@ -180,7 +180,7 @@ Checklist:
|
|||||||
- [ ] Medal local filename pattern → add to `ItemTimestamp` (need a sample filename)
|
- [ ] Medal local filename pattern → add to `ItemTimestamp` (need a sample filename)
|
||||||
- [ ] later: serve `dist/` at `/plugins/` via Caddy as a plugin repo; theme CSS
|
- [ ] later: serve `dist/` at `/plugins/` via Caddy as a plugin repo; theme CSS
|
||||||
|
|
||||||
### Phase 5 — copyparty behind Authentik (built; apply pending)
|
### Phase 5 — copyparty behind Authentik ✅ live
|
||||||
- [ ] Authentik → Providers → Proxy provider, *forward auth (single application)*, external host
|
- [ ] Authentik → Providers → Proxy provider, *forward auth (single application)*, external host
|
||||||
`https://ovh1.HOST`; Application bound to it; add to the embedded outpost
|
`https://ovh1.HOST`; Application bound to it; add to the embedded outpost
|
||||||
- [ ] Caddy: `forward_auth 127.0.0.1:9000 { uri /outpost.goauthentik.io/auth/caddy; copy_headers X-Authentik-Username X-Authentik-Groups … }`
|
- [ ] Caddy: `forward_auth 127.0.0.1:9000 { uri /outpost.goauthentik.io/auth/caddy; copy_headers X-Authentik-Username X-Authentik-Groups … }`
|
||||||
@@ -194,13 +194,13 @@ Checklist:
|
|||||||
- [x] decided: no WebDAV (Discord login only); browser downloads
|
- [x] decided: no WebDAV (Discord login only); browser downloads
|
||||||
- [ ] policy on the Application: only `editors` + `admins` + `streamers` may pass
|
- [ ] policy on the Application: only `editors` + `admins` + `streamers` may pass
|
||||||
|
|
||||||
### Phase 6 — Syncthing UI + dump behind Authentik (built together with phase 5; apply pending)
|
### Phase 6 — Syncthing UI + dump behind Authentik ✅ live
|
||||||
- [ ] `/sync/`: forward-auth, policy `admins` only; Syncthing GUI auth can stay as a second layer
|
- [ ] `/sync/`: forward-auth, policy `admins` only; Syncthing GUI auth can stay as a second layer
|
||||||
- [ ] `dumpd.py`: read `X-Authentik-Username` / `X-Authentik-Groups` from Caddy instead of basic auth;
|
- [ ] `dumpd.py`: read `X-Authentik-Username` / `X-Authentik-Groups` from Caddy instead of basic auth;
|
||||||
admin = member of `admins`; drop `dump-users.txt`
|
admin = member of `admins`; drop `dump-users.txt`
|
||||||
- [ ] dock: `Dump tonight` sends no credentials; session cookie carries identity
|
- [ ] dock: `Dump tonight` sends no credentials; session cookie carries identity
|
||||||
|
|
||||||
### Phase 7 — dock polish + cleanup (built with phase 11; apply pending)
|
### Phase 7 — dock polish + cleanup ✅ live (dock mints tokens; no stored credentials)
|
||||||
- [ ] `dumpd.py` gains `GET /me` → `{user, groups, stream_key}` for the logged-in streamer;
|
- [ ] `dumpd.py` gains `GET /me` → `{user, groups, stream_key}` for the logged-in streamer;
|
||||||
dock fills OBS settings from it — nobody types a stream password again
|
dock fills OBS settings from it — nobody types a stream password again
|
||||||
- [ ] `configure.py` shrinks: hostnames + streamers only (editors and admin live in Authentik)
|
- [ ] `configure.py` shrinks: hostnames + streamers only (editors and admin live in Authentik)
|
||||||
@@ -263,7 +263,7 @@ Same pattern as Jellyfin: Authentik is the identity, Gitea trusts it.
|
|||||||
- [ ] policy on the Authentik application: who may reach Gitea at all (e.g. `admins` + a `devs` group)
|
- [ ] policy on the Authentik application: who may reach Gitea at all (e.g. `admins` + a `devs` group)
|
||||||
- [ ] test with a non-admin Discord user; confirm admin mapping via `admins` group
|
- [ ] test with a non-admin Discord user; confirm admin mapping via `admins` group
|
||||||
|
|
||||||
### Phase 11 — MediaMTX auth through Authentik (no stream keys anywhere) (built; apply pending)
|
### Phase 11 — MediaMTX auth through Authentik (no stream keys anywhere) ✅ live
|
||||||
Implemented variant: **short-lived HMAC tokens minted by dumpd** for Discord-authenticated members of
|
Implemented variant: **short-lived HMAC tokens minted by dumpd** for Discord-authenticated members of
|
||||||
`streamers` (no Authentik app passwords — "Discord only" decision). Dock and portal mint a token per Go Live;
|
`streamers` (no Authentik app passwords — "Discord only" decision). Dock and portal mint a token per Go Live;
|
||||||
manual setups get it from the dock's accordion. MediaMTX `authMethod: http` → dumpd `/mtx-auth` on 8081
|
manual setups get it from the dock's accordion. MediaMTX `authMethod: http` → dumpd `/mtx-auth` on 8081
|
||||||
|
|||||||
42
STATUS.md
42
STATUS.md
@@ -1,6 +1,6 @@
|
|||||||
# Vanguard stack — what runs, what people do, what's unfinished
|
# Vanguard stack — what runs, what people do, what's unfinished
|
||||||
|
|
||||||
Living document. Updated whenever something is deployed or changes behaviour. Last update: 2026-10-31.
|
Living document. Updated whenever something is deployed or changes behaviour. Last update: 2026-10-31 (evening).
|
||||||
Host: `ovh1.dumpstervigilantes.rip` (OVH SYS-1, Debian 13). Bundle: `~/vanguard-stream` on the box.
|
Host: `ovh1.dumpstervigilantes.rip` (OVH SYS-1, Debian 13). Bundle: `~/vanguard-stream` on the box.
|
||||||
Source of truth: this repo, `techy/Media-Server-Setup` on the stack's own Gitea (`ssh://git@git.dumpstervigilantes.rip:2222/techy/Media-Server-Setup.git`).
|
Source of truth: this repo, `techy/Media-Server-Setup` on the stack's own Gitea (`ssh://git@git.dumpstervigilantes.rip:2222/techy/Media-Server-Setup.git`).
|
||||||
|
|
||||||
@@ -25,11 +25,11 @@ Source of truth: this repo, `techy/Media-Server-Setup` on the stack's own Gitea
|
|||||||
|
|
||||||
| Who | Activity | Where | Login |
|
| Who | Activity | Where | Login |
|
||||||
|---|---|---|---|
|
|---|---|---|---|
|
||||||
| Streamer | Type a title (live preview + naming rules), Go Live, Stop. "Dump tonight" if it was junk (3-day undo). Manual-setup accordion with endpoints and a hidden token | OBS browser dock `https://ovh1…/dock/` | Discord login in the dock (once); dock mints a 12 h token per Go Live — **no passwords** (pending apply) |
|
| Streamer | Type a title (live preview + naming rules), Go Live, Stop. "Dump tonight" if it was junk (3-day undo). Manual-setup accordion with endpoints and a hidden token | OBS browser dock `https://ovh1…/dock/` | Discord login in the dock; dock mints a 12 h token per Go Live — **no passwords, verified live** |
|
||||||
| Gamer | Nothing; clips save where they always did | their clipper + Syncthing, paired once | — |
|
| Gamer | Nothing; clips save where they always did | their clipper + Syncthing, paired once | — |
|
||||||
| Editor | Browse by streamer/title, scrub in browser, download originals, upload finals | copyparty `https://ovh1…/` | Discord (Authentik); rights by group `editors` / `media-admins` — **pending apply** |
|
| Editor | Browse by streamer/title, scrub in browser, download originals (zip/tar for folders), upload finals | copyparty `https://ovh1…/` | Discord (Authentik); rights by group `editors` / `media-admins` |
|
||||||
| Anyone in the Discord server | Watch recordings and clips by streamer and season | Jellyfin `https://watch.…/` | Discord (Authentik) |
|
| Anyone in the Discord server | Watch recordings and clips by streamer and season | Jellyfin `https://watch.…/` | Discord (Authentik) |
|
||||||
| Anyone in the Discord server | Watch live: all active streams in dockable windows, audio follows focus, per-window mute/volume | Live portal `https://live.…/` | Discord (Authentik, domain-level) — live; viewer side not yet exercised during a stream |
|
| Anyone in the Discord server | Watch live: all active streams in dockable windows, audio follows focus, per-window mute/volume | Live portal `https://live.…/` | Discord (Authentik, domain-level) — **live, shows a real stream** |
|
||||||
| Streamer (Windows) | **Go Live** from the browser: pick the WarDogs window (+audio on Windows Chrome 141+; Linux/Mac video only), streams as `<user>/HelmetCam-<date>`; no OBS needed | Live portal → Go Live | Discord; key fetched for the logged-in user — **verified end to end** (publish → `.live` → sweep → title folder) |
|
| Streamer (Windows) | **Go Live** from the browser: pick the WarDogs window (+audio on Windows Chrome 141+; Linux/Mac video only), streams as `<user>/HelmetCam-<date>`; no OBS needed | Live portal → Go Live | Discord; key fetched for the logged-in user — **verified end to end** (publish → `.live` → sweep → title folder) |
|
||||||
| Devs | Host code, review, CI | Gitea `https://git.…/`, ssh 2222 | **local account** (Discord later) |
|
| Devs | Host code, review, CI | Gitea `https://git.…/`, ssh 2222 | **local account** (Discord later) |
|
||||||
| Bot dev | Push code, restart container, read logs; web UI at `https://bot.…/` | Gitea + compose; `bot/AGENT.md` | web UI behind Discord (Authentik), once its provider exists |
|
| Bot dev | Push code, restart container, read logs; web UI at `https://bot.…/` | Gitea + compose; `bot/AGENT.md` | web UI behind Discord (Authentik), once its provider exists |
|
||||||
@@ -43,10 +43,10 @@ Source of truth: this repo, `techy/Media-Server-Setup` on the stack's own Gitea
|
|||||||
|
|
||||||
| Service | Role | State |
|
| Service | Role | State |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| MediaMTX | RTMP/SRT ingest, records fMP4; publish auth delegated to dumpd (tokens) | live; auth switch **pending apply** (hot-reload, no restart) |
|
| MediaMTX | RTMP/SRT ingest, records fMP4; publish auth delegated to dumpd (tokens via `/mtx-auth`) | live, token auth verified |
|
||||||
| copyparty | browse/scrub/download/WebDAV/finals upload | behind Authentik, group permissions — **built, pending apply** (currently local accounts) |
|
| copyparty | browse/scrub/download/finals upload | behind Authentik, group permissions (`editors`, `media-admins`), Discord-only, no WebDAV | live |
|
||||||
| dumpd + dock | dump-tonight endpoint, OBS dock page | identity from Authentik headers — **built, pending apply** |
|
| dumpd + dock | dump, stream tokens, MediaMTX auth hook; OBS dock | identity from Authentik headers | live |
|
||||||
| Syncthing | clip intake, UI at `/sync/` | UI behind Authentik + `media-admins` — **built, pending apply** |
|
| Syncthing | clip intake, UI at `/sync/` | UI behind Authentik + `media-admins` | live |
|
||||||
| normalize sweep | editing standard, one copy per clip | live |
|
| normalize sweep | editing standard, one copy per clip | live |
|
||||||
| nftables | host firewall (22, 80/443, 1935, 2222, 3306, 8890/udp, 22000) | live |
|
| nftables | host firewall (22, 80/443, 1935, 2222, 3306, 8890/udp, 22000) | live |
|
||||||
| Caddy | TLS + routing for all hostnames | live |
|
| Caddy | TLS + routing for all hostnames | live |
|
||||||
@@ -62,21 +62,17 @@ Source of truth: this repo, `techy/Media-Server-Setup` on the stack's own Gitea
|
|||||||
|
|
||||||
## Unfinished, in rough priority
|
## Unfinished, in rough priority
|
||||||
|
|
||||||
1. **MediaMTX container recreate** for `TZ=America/New_York` (filenames were UTC-stamped) and `moq: no` — `docker compose up -d --force-recreate mediamtx` after the compose upload.
|
1. Authentik: `discord-roles-to-groups` policy so `streamers`/`editors`/`media-admins`/`bot-users` follow Discord roles (`bot-users` group needed for the bot host). Set the provider's Invalidation flow to `default-provider-invalidation-flow` so every logout forces a full re-login.
|
||||||
1b. Authentik `discord-roles-to-groups` policy + `bot-users` group (`bot` CNAME now correct).
|
2. Confirm plugin 0.1.3 under Jellyfin → Plugins and the Gitea runner registered.
|
||||||
1c. Confirm plugin 0.1.2 installed and runner registered.
|
3. Portal viewer during a real stream: corner chip `webrtc`; Windows Go Live with WarDogs audio (first Windows streamer).
|
||||||
1d. Watch a real stream from a second browser: corner chip should say `webrtc`; confirm WarDogs audio came through.
|
4. Gitea login via Authentik (plan phase 10).
|
||||||
2. **Register the runner** (`./registerGiteaRunner.sh`).
|
5. Housekeeping: pin `AUTHENTIK_TAG`, rotate the Discord client secret seen in a screenshot, nightly Postgres dump, Caddyfile formatting warning.
|
||||||
3. **`bot` CNAME + Authentik proxy provider** — first use of forward-auth; proves the pattern for copyparty.
|
6. Medal filename pattern in the plugin (need a sample filename).
|
||||||
4. **Apply phase 5+6** (copyparty, dock, dump, /sync behind Authentik; group permissions). Authentik side: group `media-admins` with techy in it. Decision: Discord login only → no WebDAV; browser downloads (zip/tar) instead.
|
7. Home archive puller on the home box.
|
||||||
5. **Apply phase 7+11** (token publish auth): `configure.py` apply (MediaMTX hot-reloads; no stream interruption), new dumpd + unit, firewall rule for 8081 from Docker, dock upload, portal deploy. Then every streamer must be in the Authentik `streamers` group.
|
8. Plugin repository served by Caddy so Jellyfin updates from its catalog.
|
||||||
6. **Gitea login via Authentik** (OIDC source, auto-register, `admins` → Gitea admin).
|
9. Clip submissions (belongs to the bot). Bot code from the other dev.
|
||||||
7. **Housekeeping**: pin `AUTHENTIK_TAG` in `.env`, rotate the Discord client secret that was in a screenshot, nightly Postgres dump, Jellyfin login branding (Discord button first), check a non-admin Discord user's Jellyfin view.
|
10. Authentik blueprint from `.env` (Discord source, groups, policies, provider) for reproducible installs.
|
||||||
8. **Medal filename pattern** in the plugin's timestamp parser — need one sample filename.
|
11. SYS-3 when transcoding or sweep speed hurts.
|
||||||
9. **Home archive puller** on the home box.
|
|
||||||
10. **Plugin repository** served by Caddy so Jellyfin updates the plugin from its catalog.
|
|
||||||
11. **Clip submissions** (Medal/Twitch/YouTube links, Discord uploads) — belongs to the bot.
|
|
||||||
13. **SYS-3** when transcoding or sweep speed hurts: Quick Sync, flip the plugin's policy toggle off.
|
|
||||||
|
|
||||||
## Verified behaviours worth remembering
|
## Verified behaviours worth remembering
|
||||||
- **Never scp generated configs** (`mediamtx.yml`, `copyparty.conf`, `Caddyfile`, `dump-users.txt`, `.env`): a template copy wiped all streamers once. They are gitignored now; `*.example.*` are reference only.
|
- **Never scp generated configs** (`mediamtx.yml`, `copyparty.conf`, `Caddyfile`, `dump-users.txt`, `.env`): a template copy wiped all streamers once. They are gitignored now; `*.example.*` are reference only.
|
||||||
|
|||||||
Reference in New Issue
Block a user