···11+# Matrix Synapse + Element Web + ATLogin
22+33+A NixOS infrastructure for Matrix with Bluesky/ATProto authentication via ATLogin.
44+55+> **Warning**: The VM uses hardcoded dummy secrets for local testing only. Do not use these values in production.
66+77+## VM Test Environment
88+99+### Quick Start
1010+1111+**Without tunnel** (localhost only - won't work with external PDS):
1212+```bash
1313+nix run .#vm
1414+```
1515+1616+**With Tailscale** (recommended - works with Element X on phone):
1717+1818+```bash
1919+TAILSCALE_HOSTNAME=matrix-test.tail1234.ts.net \
2020+TAILSCALE_AUTHKEY=tskey-auth-xxx \
2121+nix run --impure .#vm
2222+```
2323+2424+Then:
2525+- From your computer: open http://localhost:8080 or https://matrix-test.tail1234.ts.net
2626+- From your phone: use `https://matrix-test.tail1234.ts.net` as homeserver
2727+2828+**With ngrok** (alternative):
2929+3030+```bash
3131+# Terminal 1: Start ngrok
3232+ngrok http 9411
3333+3434+# Terminal 2: Start the VM with the ngrok URL
3535+ATLOGIN_URL=https://abc123.ngrok-free.app nix run --impure .#vm
3636+```
3737+3838+Then open http://localhost:8080 in your browser.
3939+4040+### Services
4141+4242+| Service | URL | Description |
4343+|-------------|--------------------------|--------------------------------|
4444+| Element Web | http://localhost:8080 | Matrix web client |
4545+| Synapse API | http://localhost:8008 | Matrix homeserver |
4646+| ATLogin | http://localhost:9411 | ATProto OIDC provider |
4747+4848+### Why is a tunnel needed?
4949+5050+ATProto OAuth uses Pushed Authorization Requests (PAR). When you authenticate:
5151+5252+1. You click "Sign in with Bluesky" in Element
5353+2. ATLogin starts an OAuth flow with your PDS (e.g., bsky.social)
5454+3. **Your PDS needs to fetch ATLogin's client-metadata.json to validate the client**
5555+4. If ATLogin is on localhost, the PDS can't reach it
5656+5757+Tailscale (with HTTPS enabled) or ngrok provides a URL that the PDS can reach.
5858+5959+### Tailscale (Recommended)
6060+6161+Tailscale Funnel exposes the VM publicly with HTTPS. Benefits over ngrok:
6262+- Stable URL (doesn't change on restart)
6363+- HTTPS with auto-generated certificates
6464+- Access from any device
6565+6666+#### 1. Enable HTTPS in Tailscale Admin
6767+6868+1. Go to [Tailscale Admin Console](https://login.tailscale.com/admin/settings/features)
6969+2. Enable "HTTPS Certificates" for your tailnet
7070+7171+#### 2. Get an Auth Key
7272+7373+1. Go to [Tailscale Keys](https://login.tailscale.com/admin/settings/keys)
7474+2. Generate a new auth key (reusable + ephemeral recommended for test VMs)
7575+3. Copy the key (starts with `tskey-auth-`)
7676+7777+#### 3. Find Your Hostname
7878+7979+Your hostname will be: `<machine-name>.<tailnet-name>.ts.net`
8080+8181+For example: `matrix-test.tail1234.ts.net`
8282+8383+#### 4. Start the VM
8484+8585+```bash
8686+TAILSCALE_HOSTNAME=matrix-test.tail1234.ts.net \
8787+TAILSCALE_AUTHKEY=tskey-auth-xxx \
8888+nix run --impure .#vm
8989+```
9090+9191+The VM will:
9292+- Auto-join your tailnet on boot
9393+- Generate HTTPS certificate via `tailscale cert`
9494+- Set all URLs to use your Tailscale hostname
9595+9696+#### 5. Test with Element X
9797+9898+On your phone:
9999+1. Install Element X
100100+2. Enter homeserver: `https://matrix-test.tail1234.ts.net`
101101+3. Sign in with Bluesky
102102+103103+### Step-by-Step with ngrok
104104+105105+#### 1. Install ngrok
106106+107107+```bash
108108+# macOS
109109+brew install ngrok
110110+111111+# Or download from https://ngrok.com/download
112112+```
113113+114114+#### 2. Start ngrok
115115+116116+```bash
117117+ngrok http 9411
118118+```
119119+120120+You'll see output like:
121121+```
122122+Forwarding https://abc123.ngrok-free.app -> http://localhost:9411
123123+```
124124+125125+Copy that `https://...ngrok-free.app` URL.
126126+127127+#### 3. Start the VM
128128+129129+```bash
130130+ATLOGIN_URL=https://abc123.ngrok-free.app nix run .#vm
131131+```
132132+133133+The VM will automatically configure ATLogin and Synapse to use this public URL.
134134+135135+#### 4. Test
136136+137137+1. Open http://localhost:8080
138138+2. Click "Sign in with Bluesky"
139139+3. Enter your Bluesky handle (e.g., `alice.bsky.social`)
140140+4. Authenticate with your Bluesky account
141141+5. You're logged into Matrix!
142142+143143+### VM Controls
144144+145145+- **Quit VM**: Press `Ctrl+A X`
146146+- **Console**: Auto-logs in as root
147147+- **Logs**: `journalctl -u atlogin -f` or `journalctl -u matrix-synapse -f`
148148+149149+### Ports
150150+151151+The VM forwards these ports to your host:
152152+153153+- `8080` → `80` (nginx/Element Web)
154154+- `8008` → `8008` (Synapse)
155155+- `9411` → `9411` (ATLogin)