# Local OIDC / next-gen-auth (MSC3861) test loop The Lotus client gained MSC3861/MSC2965 OIDC login (P4-6). lotusguild's own homeserver is **not** MSC3861, so to exercise the flow without a mozilla.org tester you need a local homeserver that delegates auth to a **Matrix Authentication Service (MAS)**. This is the dev loop. > Status: the Lotus-client side is unit-tested + gate-green; this server loop is > the manual end-to-end check. It hasn't been run in CI (no container runtime > there), so treat version pins as a starting point and bump as needed. ## 1. Stand up MAS + Synapse The simplest path is the **upstream MAS docker-compose quickstart** — it's maintained and handles key generation + the database: (`docker compose` section). Use it to get MAS + Synapse + Postgres running, then apply the two Lotus-specific deltas below. A minimal `compose.yaml` skeleton (generate MAS keys first — do **not** hand-write them): ```yaml services: postgres: image: postgres:16 environment: { POSTGRES_USER: synapse, POSTGRES_PASSWORD: pw, POSTGRES_DB: synapse } mas: image: ghcr.io/element-hq/matrix-authentication-service:latest command: server ports: ['8090:8080'] # MAS issuer on http://localhost:8090 volumes: ['./mas:/data'] # First run once: `docker compose run --rm mas config generate -o /data/config.yaml` # then edit /data/mas/config.yaml (see §1a) before `up`. synapse: image: ghcr.io/element-hq/synapse:latest ports: ['8008:8008'] # client/federation API volumes: ['./synapse:/data'] depends_on: [postgres, mas] ``` ### 1a. MAS `config.yaml` — the parts that matter After `config generate` (which fills in `secrets.keys` + `encryption`), set: ```yaml http: public_base: http://localhost:8090/ issuer: http://localhost:8090/ database: uri: postgresql://synapse:pw@postgres/synapse matrix: homeserver: localhost # the server_name endpoint: http://synapse:8008/ secret: "REPLACE_WITH_A_LONG_SHARED_ADMIN_TOKEN" clients: - client_id: "0000000000000000000SYNAPSE" client_auth_method: client_secret_basic client_secret: "REPLACE_WITH_A_SHARED_CLIENT_SECRET" passwords: # so you can create a local test account in the MAS UI enabled: true ``` ### 1b. Synapse `homeserver.yaml` — delegate auth to MAS See `synapse-msc3861.yaml` in this folder; the key block is: ```yaml experimental_features: msc3861: enabled: true issuer: http://localhost:8090/ client_id: "0000000000000000000SYNAPSE" client_auth_method: client_secret_basic client_secret: "REPLACE_WITH_A_SHARED_CLIENT_SECRET" # == MAS clients[].client_secret admin_token: "REPLACE_WITH_A_LONG_SHARED_ADMIN_TOKEN" # == MAS matrix.secret account_management_url: "http://localhost:8090/account" ``` Create a test user via the MAS UI (`http://localhost:8090/`) or `docker compose exec mas mas-cli manage register-user`. Sanity check discovery (the client relies on this): ```bash curl -s http://localhost:8008/.well-known/matrix/client | jq '."m.authentication"' # -> { "issuer": "http://localhost:8090/", "account": "http://localhost:8090/account" } ``` ## 2. Point the Lotus dev client at it Run the client: `npm start` (vite dev). Override `public/config.json` so the local server is selectable and custom servers are allowed: ```json { "defaultHomeserver": 0, "homeserverList": ["localhost:8008"], "allowCustomHomeservers": true, "hashRouter": { "enabled": false, "basename": "/" } } ``` Dynamic client registration handles the redirect URI automatically — it's `/auth/oidc/callback` (e.g. `http://localhost:5173/auth/oidc/callback`), and MAS allows `http://localhost` redirects in dev. ## 3. Run the checklist See **section N** of `../../LOTUS_TESTING.md` for the actual pass/fail steps (login redirect, callback, session-persist-on-reload, token refresh, logout revocation, account-management link, and the non-OIDC-regression check). ## Files here - `synapse-msc3861.yaml` — the Synapse experimental-features delta. - `config.local.json` — the Lotus `public/config.json` override.