Skip to content

HTTPS and certificates

HTTPS is not optional here. Gamepads, Keyboard Lock and microphone capture all need a secure context, so an HTTP-only deployment quietly loses three features.

You do not have to obtain a certificate. Quasar generates one on first boot and keeps it.

On first boot the control plane writes a self-signed certificate into its state directory and reuses it from then on. Nothing to configure, and no re-prompting after a restart.

The one thing you must get right is which names it claims. Set them before you start the stack:

Terminal window
QUASAR_TLS_HOSTS=192.168.1.50,quasar.lan

List every address anyone will type into a browser. LAN IP, hostname, VPN address, all of them.

Accepting the browser warning works, but you redo it per browser and per device, and it leaves the padlock struck through. Installing the certificate in your operating system’s trust store fixes it once per machine.

Download it straight from the server:

Terminal window
curl -k https://<host-ip>:8443/v1/tls/certificate.pem -o quasar.pem

That endpoint needs no login, which is deliberate and safe. A server certificate is public by definition: every TLS handshake hands the same bytes to every client that connects, before any authentication happens. Anyone who can reach port 8443 can already read it with openssl s_client. The route serves the leaf only, re-encoded from the parsed certificate rather than read off disk, so there is no file path that could point at a key. The private key is never returned by any route.

Add quasar.pem to your platform’s trust store. On macOS that is Keychain Access, set to Always Trust. On Windows it is the Trusted Root Certification Authorities store. On Linux it varies by distribution, usually /usr/local/share/ca-certificates followed by update-ca-certificates.

Trusting it only helps if it names the address you actually use, so fix QUASAR_TLS_HOSTS first.

On a LAN you control, clicking through is reasonable. On a network you do not control it is not, and first contact is exactly when it matters, because that is when the founding admin account gets claimed.

The control plane logs the fingerprint at startup. Compare it against what your browser shows:

Terminal window
docker compose -f deploy/docker-compose.yml logs quasar-control-plane | grep fingerprint

The certificate is generated once and kept for ten years, so adding a name to QUASAR_TLS_HOSTS afterwards does nothing by itself. Delete the certificate and let it regenerate.

  1. Add the name to QUASAR_TLS_HOSTS in deploy/.env.

  2. Delete the existing pair.

    Terminal window
    docker compose -f deploy/docker-compose.yml exec quasar-control-plane \
    rm -f /var/lib/quasar-control/tls/cert.pem /var/lib/quasar-control/tls/key.pem
  3. Recreate the container.

    Terminal window
    docker compose -f deploy/docker-compose.yml up -d --force-recreate quasar-control-plane

The new certificate has a new fingerprint, so every browser that accepted the old one warns again, and every machine you added it to needs the new one.

If you have a certificate already, from an internal certificate authority or a public one for a name you own, Quasar will serve it instead. Mount both PEM files into the container and point at them:

Terminal window
QUASAR_TLS_CERT=/etc/quasar/tls/cert.pem
QUASAR_TLS_KEY=/etc/quasar/tls/key.pem

Set both or neither. One alone is a configuration error and the control plane refuses to start.

What the certificate needs:

  • Every browser-facing name as a subject alternative name. LAN IP, hostname, VPN address, public name if you have one. Modern browsers ignore the common name entirely and read only the SAN list. IP addresses go in as IP SANs, not DNS SANs.
  • The full chain in the certificate file, leaf first, then intermediates. A leaf on its own validates in curl on your machine and fails in a browser somewhere else.
  • An unencrypted private key. There is nowhere to type a passphrase at boot.
  • Extended key usage including server authentication, which is the default for anything issued as a server certificate.

The node agent and /health talk to the control plane over plain HTTP on 8080 and are exempt from the HTTPS redirect, so your certificate only ever has to satisfy browsers.

If your own proxy terminates TLS and forwards to Quasar, its certificate is the one browsers see and Quasar’s own is irrelevant. Check the allowed origins under Admin, Settings: a proxy that preserves the public host may work with the same-origin default, while a host-rewriting proxy or several public names needs an explicit list. See Behind a reverse proxy.

Terminal window
QUASAR_TLS=off

HTTP only, and you lose gamepads, Escape capture and microphone with it. Only do this when something in front of Quasar is providing HTTPS.

Setting Default Purpose
QUASAR_TLS auto auto generates and keeps a self-signed pair. off disables the listener.
QUASAR_TLS_HOSTS unset Names and IPs the generated certificate claims.
QUASAR_TLS_CERT / QUASAR_TLS_KEY unset Your own PEM files. Set both.
QUASAR_TLS_ADDR :8443 The HTTPS listener.
LISTEN_ADDR :8080 The HTTP listener.
QUASAR_HTTP_REDIRECT auto Redirects browser routes from HTTP to HTTPS.
QUASAR_TLS_REDIRECT_PORT the TLS port The external port to redirect to, when it differs.