Skip to Content
DocsCloud OSMobile Pairing

Mobile Pairing

Pair a phone to your Quazzar OS instance with a single QR scan. The pairing tunnel works even when your server is on a private/grey IP — no port forwarding, no UPnP, no STUN/TURN. Bytes route through Quazzar Cloud sealed end-to-end with X25519 + XChaCha20-Poly1305; the relay never sees plaintext.

Available on every plan. Shipping in 0.7.1 as the foundation for the upcoming Quazzar mobile app — the app itself arrives in the next release.

How it works (briefly)

[phone] [Quazzar Cloud] [your server] | | | | 1. POST /pair (QR token) | | |--------------------------------| | | | 2. push pair-cmd via SSE | | |------------------------------->| | | | | 3. WS /pair/relay/<sid> | | |--------------------------------|<-- 4. server dials in (mTLS) --| | | | | 5. X25519 KEX, then E2E encrypted bytes flow ↔ |
  • The server reaches the relay using its existing outbound mTLS connection. No inbound port to forward.
  • The relay is a byte-shovel; it bridges raw frames between the two ends and never decrypts.
  • After successful pairing, the phone holds a long-term key + a server-issued bearer token. Subsequent reconnects don’t need a new QR.

Pair a phone

  1. On the OS, open Settings → Control Center → Mobile pairing.
  2. Click Show pairing QR. The QR encodes a quazzar-pair://... URL with a session-bound secret that expires in 5 minutes.
  3. Scan the QR with the Quazzar mobile app (or visit the URL on the phone — useful for testing). The phone runs the X25519 key exchange with your server and is paired.
  4. The new device appears in the Paired devices list. The QR closes automatically.

Revoke a phone

Find the device in Paired devices and click Revoke. The phone’s bearer token is invalidated immediately, and any active session is closed. To reconnect, the phone scans a fresh QR.

What the phone can do

Once paired, the phone speaks the same HTTP API as the desktop web client through the encrypted tunnel. The mobile app uses this to render Dashboard / Monitor / Apps / Molly chat / notifications without a separate mobile backend.

The tunnel terminates on your server; from your apps’ point of view, it’s an authenticated HTTP request like any other.

Security

  • End-to-end encryption — frames sealed with XChaCha20-Poly1305 under a key derived from a double X25519 (ephemeral × ephemeral || long × long). Forward secrecy plus mutual long-term authentication.
  • TOFU pinning on the phone — the phone remembers your server’s long-term public key on first pair. A subsequent KEX with a different key is rejected automatically.
  • Relay can’t read traffic — the relay sees only AEAD ciphertext. We’ve documented this in our threat model and the on-server crypto code is open source so anyone can audit.
  • QR tokens are single-use — 5-minute expiry, consumed on first successful pair. A leaked QR photo is useless after either condition.

Performance

  • Idle (no active phone): zero long-lived sockets. Server only opens the relay connection when CC notifies it that a phone is connecting.
  • Per active session: ~200 KB resident on the server, 1 goroutine. Capped at 4 concurrent sessions per node.
  • AEAD seal/open of a 4 KB frame takes ~5 µs — typical mobile interactions are well under 0.01% of one CPU.

What’s not yet there

  • Push notifications — phone-app v1 only works while it’s foregrounded. Push-wake via APNs/FCM is a follow-up.
  • Direct phone↔server peer-to-peer — when our native mesh VPN ships in the Networking phase, phones and servers will be able to talk directly without the relay for in-network use cases. Until then, all traffic transits Quazzar Cloud.
  • Multiple servers per phone — one phone, one paired server in v1. Multi-server profiles arrive with the mobile app’s account-switcher.