Mosaic ships an optional HTTPS server that serves the same SolidJS SPA as the desktop shell. When enabled, you can reach Mosaic from any browser on the configured bind address — useful for headless seedboxes, LAN-attached HTPCs, or just a second device on your network.

The remote interface is off by default. When you turn it on for the first time, the binding stays on 127.0.0.1 (loopback) until you explicitly opt in to LAN exposure.

Enabling

In the desktop UI, open Settings → Web Interface:

Field Default Notes
Enabled false Master toggle — the server only binds when this is on
Port 8080 TCP port the listener binds
Bind to all false When off, listens on 127.0.0.1 over HTTP. When on, listens on 0.0.0.0 over HTTPS.
Username admin Login username; case-sensitive constant-time compared
Password (unset) Argon2id-hashed; logging in requires this to be set
API key (rotatable) Random 32-byte token (base64.RawURLEncoding). Use as Authorization: Bearer <key>.

Transport depends on the bind mode. When Bind to all is off (loopback default), the server speaks plain HTTP — no cert is generated or used, and the session cookie’s Secure flag is off. When Bind to all is on, the server speaks HTTPS, and a self-signed certificate (cert.pem + key.pem, ECDSA P-256, 10-year validity) is generated at <DataDir>/web-tls/ the first time the bind flips on. The cert covers localhost, 127.0.0.1, and ::1 only. Adding LAN hostnames or external IPs to the cert SAN list is a known TODO (H2) — see the Security page. If you need to import the cert into your system trust store, the source files live at <DataDir>/web-tls/cert.pem (paths per platform are listed in Installation).

Setting the password

The first time you enable the web interface, you must set a password before you can log in. From the desktop UI, click Set password under Settings → Web Interface; over the API, PUT /api/settings/web/password with {"password": "..."} (this requires you to already be authenticated, so the canonical first-time path is via the desktop shell).

Password storage is Argon2id with the lib’s recommended parameters — see backend/remote/cred/. Setting a new password invalidates every active session.

API key (bearer token)

Every web-interface install has a single rotatable API key. Use it as a bearer token to authenticate machine-to-machine requests without going through the login flow:

Authorization: Bearer <key>

For browser WebSocket upgrades that can’t set custom headers, pass it as a query param: wss://host:port/api/ws?key=<key>.

To rotate the key:

POST /api/settings/web/api_key/rotate

The response body is {"api_key": "<new-key>"}. The previous key is immediately invalid.

Reaching the server

In loopback-only mode (the default), browse to http://127.0.0.1:<port>/ — plain HTTP. With Bind to all on, browse to https://<host>:<port>/; your browser will show a self-signed cert warning the first time — accept it and bookmark the cert exception per browser, or import <DataDir>/web-tls/cert.pem into your system trust store.

The login form posts to /api/login; on success the response sets a mosaic_session cookie (HttpOnly, SameSite=Strict, Path=/). The cookie’s Secure flag is set only when the server is bound for HTTPS (i.e. Bind to all is on); on loopback HTTP the cookie still works because Secure only matters cross-origin.

Bearer-keyed scripts

Scripts and external clients should authenticate with the API key instead of going through /api/login. Bearer-keyed requests skip the Origin/Referer CSRF guard since they’re not subject to browser auto-attached credentials. See the Authentication page for the full model.

Recommendations

  • Loopback-only by default. Treat “Bind to all” as opt-in. Even on a LAN, exposing Mosaic outside your trust boundary is a footgun.
  • Tunnel for external access. If you need Mosaic from outside the LAN, put it behind a reverse proxy with a real cert, or reach it through SSH/Tailscale/WireGuard. Don’t port-forward 8080 to the public internet.
  • Rotate the API key if a script or device that previously held it is decommissioned.
  • Watch the audit list. v0.1.22 hardened the server substantially but two follow-ups remain (cert SANs, signed manifest); see Security.