From 59305ca27ce37ea9b327d409cf4d83dd82692167 Mon Sep 17 00:00:00 2001 From: Brad Stein Date: Thu, 8 Jan 2026 11:56:35 -0300 Subject: [PATCH] comms: mint guest tokens via MAS login --- services/comms/NOTES.md | 2 +- services/comms/guest-register-configmap.yaml | 44 ++++++++++++------- services/comms/guest-register-deployment.yaml | 2 - 3 files changed, 28 insertions(+), 20 deletions(-) diff --git a/services/comms/NOTES.md b/services/comms/NOTES.md index f3ba78f..39898da 100644 --- a/services/comms/NOTES.md +++ b/services/comms/NOTES.md @@ -7,7 +7,7 @@ Core flow - Synapse is the homeserver; MAS fronts login, Synapse serves client/server APIs. - Element Web provides the main UI; Element Call embeds LiveKit for group video. - LiveKit handles SFU media; Coturn provides TURN for NAT traversal. -- matrix-guest-register provides guest accounts + guest sessions (no Keycloak). +- matrix-guest-register provisions MAS guest accounts and performs MAS password login to mint device-bound guest tokens (no Keycloak). Operational jobs - mas-db-ensure-job: ensures MAS database role/database + secret in comms. diff --git a/services/comms/guest-register-configmap.yaml b/services/comms/guest-register-configmap.yaml index b5bc803..a40d52c 100644 --- a/services/comms/guest-register-configmap.yaml +++ b/services/comms/guest-register-configmap.yaml @@ -21,8 +21,6 @@ data: MAS_ADMIN_CLIENT_ID = os.environ["MAS_ADMIN_CLIENT_ID"] MAS_ADMIN_CLIENT_SECRET_FILE = os.environ.get("MAS_ADMIN_CLIENT_SECRET_FILE", "/etc/mas/admin-client/client_secret") MAS_ADMIN_SCOPE = os.environ.get("MAS_ADMIN_SCOPE", "urn:mas:admin") - SESSION_TTL_SEC = int(os.environ.get("SESSION_TTL_SEC", "43200")) - RATE_WINDOW_SEC = int(os.environ.get("RATE_WINDOW_SEC", "60")) RATE_MAX = int(os.environ.get("RATE_MAX", "30")) _rate = {} # ip -> [window_start, count] @@ -126,21 +124,30 @@ data: user = payload.get("data") or {} return status, user.get("id") - def _create_session(admin_token, user_id, scope): - status, payload = _admin_api( + def _set_password(admin_token, user_id, password): + status, _payload = _admin_api( admin_token, "POST", - "/personal-sessions", - { - "actor_user_id": user_id, - "human_name": "guest session", - "scope": scope, - "expires_in": SESSION_TTL_SEC, - }, + f"/users/{parse.quote(user_id)}/set-password", + {"password": password}, ) - if status != 201: - return None - return (payload.get("data", {}).get("attributes", {}) or {}).get("access_token") + return status in (200, 204) + + def _login_password(username, password): + payload = { + "type": "m.login.password", + "identifier": {"type": "m.id.user", "user": f"@{username}:{SERVER_NAME}"}, + "password": password, + } + status, data = _json( + "POST", + f"{MAS_BASE}/_matrix/client/v3/login", + body=payload, + timeout=20, + ) + if status != 200: + return None, None + return data.get("access_token"), data.get("device_id") def _set_display_name(access_token, user_id, displayname): _json( @@ -235,9 +242,12 @@ data: if not mas_user_id or not localpart: raise RuntimeError("add_user_failed") - access_token = _create_session(admin_token, mas_user_id, "urn:matrix:client:api:*") + password = secrets.token_urlsafe(18) + if not _set_password(admin_token, mas_user_id, password): + raise RuntimeError("set_password_failed") + access_token, device_id = _login_password(localpart, password) if not access_token: - raise RuntimeError("session_failed") + raise RuntimeError("login_failed") try: _set_display_name(access_token, f"@{localpart}:{SERVER_NAME}", displayname) except Exception: @@ -248,7 +258,7 @@ data: resp = { "user_id": f"@{localpart}:{SERVER_NAME}", "access_token": access_token, - "device_id": "guest_device", + "device_id": device_id or "guest_device", "home_server": SERVER_NAME, } return self._send_json(200, resp) diff --git a/services/comms/guest-register-deployment.yaml b/services/comms/guest-register-deployment.yaml index a9dd675..284cc42 100644 --- a/services/comms/guest-register-deployment.yaml +++ b/services/comms/guest-register-deployment.yaml @@ -47,8 +47,6 @@ spec: value: http://matrix-authentication-service:8081/api/admin/v1 - name: SYNAPSE_BASE value: http://othrys-synapse-matrix-synapse:8008 - - name: SESSION_TTL_SEC - value: "43200" - name: MATRIX_SERVER_NAME value: live.bstein.dev - name: RATE_WINDOW_SEC