97 lines
5 KiB
Markdown
97 lines
5 KiB
Markdown
# MatrixRTC standalone publication policy (iscg policy1)
|
|
|
|
## Policy and boundary
|
|
|
|
This is a narrow fork of Element's lk-jwt-service v0.9.0, upstream commit
|
|
`0e176b1eca44e67b11484d0bdf56999807bf2b8e` (AGPL-3.0-only). It fixes both
|
|
standalone endpoints, `/sfu/get` and `/get_token`:
|
|
|
|
- Matrix OpenID verification still runs, including the subject's server name
|
|
and the claimed user ID where the protocol supplies one.
|
|
- Every successfully authenticated participant may publish audio/video in the
|
|
requested, room-scoped session, regardless of their homeserver.
|
|
- `LIVEKIT_FULL_ACCESS_HOMESERVERS=iscg.dev` still gates the server-side
|
|
`CreateRoom` call and delayed-leave delegation. It is NOT widened to `astr.to`
|
|
or `*`. No user's JWT gains room creation, list, recording or admin privileges.
|
|
- Existing application-service membership checks, when configured, are unchanged.
|
|
- The SFU MUST retain `room.auto_create: false`. Otherwise remote users can
|
|
create arbitrary SFU rooms by joining, regardless of JWT-service policy.
|
|
- A remote user may obtain a scoped token before a local user creates the room;
|
|
the SFU rejects joining a missing room. This is intentional upstream behaviour.
|
|
- Existing one-hour token TTL, SFU participant limits and container hardening
|
|
are preserved. No new appservice/admin credential is introduced.
|
|
|
|
**This is not Matrix room-membership authorization.** On Heather, Tuwunel
|
|
1.9.4 has no MSC4502/MSC4512 integration, and lk-jwt-service is standalone.
|
|
Someone with valid Matrix OpenID and knowledge of a room ID can request an SFU
|
|
token even if not a Matrix member, including for an unencrypted call. This
|
|
limitation existed for subscribing before the patch and now includes publishing.
|
|
Room IDs are not authorization secrets; E2EE, when enabled by clients, protects
|
|
media confidentiality, not resource abuse or forged room participation. Do not
|
|
advertise this deployment as membership-checked or suitable for anonymous guests.
|
|
|
|
The fuller migration is homeserver-backed MSC4195/MSC4502/MSC4512 integration
|
|
with scoped application-service membership checks. It requires a homeserver
|
|
that supports those APIs (or a separately reviewed Tuwunel implementation),
|
|
client compatibility checks and a backed-up migration. Adding `astr.to` or `*`
|
|
to the full-access list does not solve membership authorization. The newer
|
|
upstream `LIVEKIT_REMOTE_CAN_PUBLISH_HOMESERVERS` option applies to federated
|
|
application-service requests, not to these standalone endpoints.
|
|
|
|
## Source and tests
|
|
|
|
`standalone-publication.patch` changes two authorization arguments, adds a
|
|
startup policy banner, regression tests and updates the two HTTP integration
|
|
suites' remote publication expectations. Creation, delegation, OpenID and
|
|
membership-check implementations are not replaced.
|
|
|
|
The image build fails unless all root-library unit tests and both HTTP/OpenID
|
|
integration suites (`get_token`, `sfu_get`) pass. Regressions cover local users,
|
|
`astr.to`, an unrelated server, rejected OpenID, foreign/forged subject,
|
|
room-scoped JWTs and lack of creation/admin permissions. Existing membership
|
|
and delayed-event denial tests remain part of the unit suite.
|
|
|
|
The upstream archive, patch and Rust builder image are SHA256-pinned, and Cargo
|
|
uses `--locked`. Alpine build-tool packages are fetched from its package
|
|
repository, so this is a pinned-source build recipe, NOT a claim of bit-for-bit
|
|
reproducible output. Preserve the exported release image and its checksum too.
|
|
|
|
## Build (Linux amd64 / Docker)
|
|
|
|
From this directory:
|
|
|
|
```sh
|
|
# Run long work in tmux. No production secrets are needed by the build.
|
|
sudo bash build.sh
|
|
```
|
|
|
|
The resulting image is
|
|
`iscg/lk-jwt-service:0.9.0-policy1-6e21c58c02d6`.
|
|
The image is local-only and Compose uses `pull_policy: never`. On a replacement
|
|
host, rebuild it or load the preserved Docker image archive BEFORE starting
|
|
Arion. Do not replace it with an unreviewed latest tag. Tests and compiler run
|
|
in build containers; no Rust toolchain is installed on the NixOS host.
|
|
|
|
## Deployment and rollback
|
|
|
|
Deploy only `matrix-rtc-jwt` with the evaluated Arion composition, after staging
|
|
and health/token/media checks. No homeserver, SFU, Coturn or unrelated service
|
|
restart is required. Compare the Nix source baseline to `/run/current-system`
|
|
and inspect dry activation before switching so unrelated edits are not applied.
|
|
|
|
The deployment receipt records the exact image ID and new Nix generation.
|
|
Before deployment preserve the old generation, old composition, old image,
|
|
container start-time baseline and config source. Keep release archives outside
|
|
cache on Heather and Poppy.
|
|
|
|
For an emergency rollback, use the saved pre-policy Arion composition:
|
|
|
|
```sh
|
|
sudo arion --prebuilt-file /path/from/receipt/old-compose.yaml \
|
|
up -d --no-deps --pull never matrix-rtc-jwt
|
|
```
|
|
|
|
Then restore the pre-policy Nix generation/source selectively, retaining any
|
|
subsequent unrelated edits. Do not restart the whole `heather.service`, wipe
|
|
volumes, revert the homeserver database or disable TLS verification. Rejoin the
|
|
call to obtain a fresh JWT; previously issued tokens do not change retroactively.
|