# Synara A multi-provider web GUI for coding agents. One account, many hosts: clients reach any of the user's hosts directly (LAN, SSH, Tailscale) or through a cloud relay. ## Language ### Hosts & Environments **Host**: A user's machine running a Synara server, registered on their account. Host = Environment, 1:1 — the environment id is the host's stable identity; one machine runs one Synara environment. _Avoid_: device (that's a client), remote host (all hosts are the same entity, reachable or not) **Environment**: The running Synara server instance a host is. Not modeled separately from Host; there is deliberately no multi-environment-per-machine concept. **Owner**: The user who registered a host. Hosts are user-owned; the org is tenancy, not automatic shared ownership. **Discoverability**: A per-host toggle controlled by its owner, on by default. Off: only the owner sees the host. On: the entire org sees and can use it — visibility and usability are the same switch; there is no finer-grained grant. _Avoid_: sharing, visibility (as separate concepts from usability) **Reachability**: Whether a client can currently reach a host — learned by attempting (the probe race), never stored or pushed. There is no live presence state; host lists show reachability as of the last probe, and `lastSeenAt` is historical metadata. _Avoid_: presence, heartbeat, online/offline (as stored state) ### Reaching a host **Transport**: One of the ways a client reaches a host: loopback, LAN, Tailscale, SSH (desktop-only), or Relay. SSH direct and the relay coexist; SSH is not merely a bootstrap mechanism. **Relay**: The cloud rendezvous: a dumb WebSocket pipe that pairs one client socket with one host socket and forwards opaque frames. Hosts dial out; nothing listens on the user's network. There is one relay per deployment — relay reachability is derived from presence, not stored as an endpoint. **Relay Grant**: A short-lived (~60s), single-use, host-scoped signed token the API issues to an authorized client; the relay verifies it statelessly and splices exactly one session. The API owns the splice authorization; the host mints the actual session credential (see Host Keypair). **Splice**: The relay pairing one client data socket with one host data socket, 1:1 per session — no multiplexing. The host dials a fresh data socket per session, signaled over its control socket. **Endpoint**: A URL a host self-reports to the directory for a direct transport (LAN, Tailscale), reported at startup and on address change (latest set replaces, no TTL). Probe candidates, not guarantees — stale entries are harmless because clients race them. Hosts also advertise on the local network via mDNS so same-network clients find them without the directory. The relay is not an endpoint. **Control Socket**: A host's supervisor-kept persistent connection to the relay, used for splice signaling. Hosts hold one; clients hold none — a client only contacts the relay to open a session. Distinct from a spliced data socket, which stays opaque end-to-end. **Host Keypair**: The Ed25519 keypair a host generates at registration; its public key lives in the directory. It is the host's _only_ credential: it proves link challenges, authenticates the host to the API, and mints session credentials — the cloud can authorize a splice but can never fabricate access to a host. Revocation = deleting the public key. **Directory**: The cloud's role with respect to hosts: identity, endpoints, presence, display metadata. Cloud is a directory + pipe; hosts own all state. ### Sync **Host Secrets**: Per-host configuration synced across the owner's devices end-to-end encrypted (SSH destination, launcher config, key-verification policy). The cloud stores ciphertext only, versioned whole-blob with last-write-wins (small version history kept for recovery). Secrets never cross user boundaries — SSH is therefore an owner-only transport; org members reach a discoverable host via relay, LAN, or Tailscale. **Session Credential**: The credential a client uses against a host, minted by the host itself: DPoP-bound to the client device's key thumbprint (a leaked credential is useless without the device key), ~1h TTL, re-minted via a fresh grant on expiry or reconnect. _Avoid_: host token (replaced by the Host Keypair as the host's credential) **Sync Key**: The random master key that encrypts Host Secrets. Generated by the owner's first device, handed to each new device during device pairing; the cloud never sees it. Losing all devices loses Host Secrets (re-enter them), never the hosts. Removing a device rotates the Sync Key: a surviving device re-encrypts Host Secrets so the removed device cannot decrypt future ciphertext. **Device**: A client the user signs in from (desktop app, iOS app). A device's identity is its **Device Key** — a non-exportable keypair in the platform keystore, registered on the account at pairing; session credentials are DPoP-bound to it. Devices hold the Sync Key; hosts do not need it to operate.