Extend voice-limit-guard to enforce a per-room publish-source policy
(io.lotus.room_quality allow_screenshare/allow_camera) for ALL Matrix clients,
alongside the existing participant limit.
- At token issue, re-sign the LiveKit JWT's canPublishSources to drop forbidden
sources (microphone always kept). Verifies our own secret signed the token
first and fails open on mismatch, so a secret drift can never mint a token the
SFU rejects. Limit check and source policy are independent (one's outage can't
skip the other).
- Live (mid-call) enforcement: a background reconcile loop calls LiveKit
UpdateParticipant to revoke a forbidden source from participants who joined
before the policy changed -- which unpublishes their in-progress
screenshare/camera server-side within ~3s and blocks re-publish. Only removes
sources (never grants), preserves other permission flags, fails open, and runs
as a daemon thread that cannot crash or block token issuance.
- Endpoint-specific room-id extraction (/get_token->room_id, /sfu/get->room) so
a client sending both keys can't get a different room's policy applied.
- Auto-deploy the guard on LXC 151 (py_compile-gated, backup + rollback).
- Unit tests: JWT re-sign/verify + tamper, secret-mismatch, source narrowing,
reconcile (never-grant / preserve-flags / disable-on-empty), fail-open.
Numeric bitrate/fps caps are NOT server-enforceable on an SFU (LiveKit forwards,
never transcodes) and remain a Lotus-client-cooperative setting; the
screenshare/camera permission is the hard cross-client lever.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The cinny/lotus-deploy.sh (hyphen) force-deploy variant was an untracked,
redundant duplicate of the CI-gated cinny/lotus_deploy.sh (underscore) added in
c13549f. It's been removed, so its install block here referenced a file that no
longer exists. The CI-gated lotus_deploy.sh is the single source of truth for
the webhook web deploy.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The live /usr/local/bin/lotus_deploy.sh (the `lotus-deploy` webhook target) was
never under version control and had rotted into two deploy-killing bugs that
froze chat.lotusguild.org on an old build:
1. CI gate: it waited on the WHOLE workflow run with a 15-min cap. Web CI shares
the single act_runner with the slow Tauri desktop builds, so a web run could
sit queued >15 min -> "result: timeout" -> deploy aborted. Now it gates only
on the "Build & Quality Checks" commit-status context (build + unit tests),
decoupled from "Trigger Desktop Build", and waits up to 45 min.
2. Dead element-call copy: `cp node_modules/@element-hq/element-call-embedded/...`
under `set -e` aborted every deploy after the widget was forked to
@lotusguild/element-call-embedded. The build already emits dist/public/
element-call; replaced the copy with a presence check.
Also: rsync now excludes config.json so the app deploy stops clobbering the
production runtime config (homeserver list / allowCustomHomeservers) that the
matrix repo owns. lxc106-cinny.sh now installs this script (syntax-checked).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The chat.lotusguild.org nginx config (LXC 106) was edited directly on the box
and never tracked — which is how its CSP drifted (kept a dead Sentry URL and
blocked matrix.org logins). Snapshot it as cinny/nginx.conf (verbatim from prod,
incl. the corrected connect-src that now allows matrix.org/*.matrix.org) and
deploy it via lxc106-cinny.sh: back up the live file, swap, `nginx -t`, and
reload only on success (auto-restore the backup if validation fails, so a bad
config can't take the site down). TLS terminates at the NPM proxy, so this is a
plain HTTP server block with no secrets.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Removed standalone matrixbot/deploy.sh — deploy is handled by the existing
webhook system. Added matrixbot/ block to deploy/lxc151-hookshot.sh: on push,
if any matrixbot/ file changed, source files are synced to /opt/matrixbot and
matrixbot.service is restarted automatically.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Per-LXC deploy scripts (lxc151-hookshot, lxc106-cinny, lxc139-landing, lxc110-draupnir)
- Per-LXC webhook hook configs with unique HMAC-SHA256 secrets
- Livekit graceful restart script + systemd timer (waits for zero active calls)
- Fix hookshot/deploy.sh capitalization bug (Uptime-Kuma, Tinker-Tickets, etc.)
Each LXC independently clones repo and runs its own deploy.sh via adnanh/webhook on port 9000.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>