Matrix Synapse + Element Web + ATLogin#
A NixOS infrastructure for Matrix with Bluesky/ATProto authentication via ATLogin.
Warning: The VM uses hardcoded dummy secrets for local testing only. Do not use these values in production.
VM Test Environment#
Quick Start#
Without tunnel (localhost only - won't work with external PDS):
nix run .#vm
With Tailscale (recommended - works with Element X on phone):
TAILSCALE_HOSTNAME=matrix-test.tail1234.ts.net \
TAILSCALE_AUTHKEY=tskey-auth-xxx \
nix run --impure .#vm
Then:
- From your computer: open http://localhost:8080 or https://matrix-test.tail1234.ts.net
- From your phone: use
https://matrix-test.tail1234.ts.netas homeserver
With ngrok (alternative):
# Terminal 1: Start ngrok
ngrok http 9411
# Terminal 2: Start the VM with the ngrok URL
ATLOGIN_URL=https://abc123.ngrok-free.app nix run --impure .#vm
Then open http://localhost:8080 in your browser.
Services#
| Service | URL | Description |
|---|---|---|
| Element Web | http://localhost:8080 | Matrix web client |
| Synapse API | http://localhost:8008 | Matrix homeserver |
| ATLogin | http://localhost:9411 | ATProto OIDC provider |
Why is a tunnel needed?#
ATProto OAuth uses Pushed Authorization Requests (PAR). When you authenticate:
- You click "Sign in with Bluesky" in Element
- ATLogin starts an OAuth flow with your PDS (e.g., bsky.social)
- Your PDS needs to fetch ATLogin's client-metadata.json to validate the client
- If ATLogin is on localhost, the PDS can't reach it
Tailscale (with HTTPS enabled) or ngrok provides a URL that the PDS can reach.
Tailscale (Recommended)#
Tailscale Funnel exposes the VM publicly with HTTPS. Benefits over ngrok:
- Stable URL (doesn't change on restart)
- HTTPS with auto-generated certificates
- Access from any device
1. Enable HTTPS in Tailscale Admin#
- Go to Tailscale Admin Console
- Enable "HTTPS Certificates" for your tailnet
2. Get an Auth Key#
- Go to Tailscale Keys
- Generate a new auth key (reusable + ephemeral recommended for test VMs)
- Copy the key (starts with
tskey-auth-)
3. Find Your Hostname#
Your hostname will be: <machine-name>.<tailnet-name>.ts.net
For example: matrix-test.tail1234.ts.net
4. Start the VM#
TAILSCALE_HOSTNAME=matrix-test.tail1234.ts.net \
TAILSCALE_AUTHKEY=tskey-auth-xxx \
nix run --impure .#vm
The VM will:
- Auto-join your tailnet on boot
- Generate HTTPS certificate via
tailscale cert - Set all URLs to use your Tailscale hostname
5. Test with Element X#
On your phone:
- Install Element X
- Enter homeserver:
https://matrix-test.tail1234.ts.net - Sign in with Bluesky
Step-by-Step with ngrok#
1. Install ngrok#
# macOS
brew install ngrok
# Or download from https://ngrok.com/download
2. Start ngrok#
ngrok http 9411
You'll see output like:
Forwarding https://abc123.ngrok-free.app -> http://localhost:9411
Copy that https://...ngrok-free.app URL.
3. Start the VM#
ATLOGIN_URL=https://abc123.ngrok-free.app nix run .#vm
The VM will automatically configure ATLogin and Synapse to use this public URL.
4. Test#
- Open http://localhost:8080
- Click "Sign in with Bluesky"
- Enter your Bluesky handle (e.g.,
alice.bsky.social) - Authenticate with your Bluesky account
- You're logged into Matrix!
VM Controls#
- Quit VM: Press
Ctrl+A X - Console: Auto-logs in as root
- Logs:
journalctl -u atlogin -forjournalctl -u matrix-synapse -f
Ports#
The VM forwards these ports to your host:
8080→80(nginx/Element Web)8008→8008(Synapse)9411→9411(ATLogin)