Connecting through SSH tunnels
Most production databases sit behind a bastion. Quay opens its own
SSH tunnel — no ssh -L 5432:db:5432 bastion & background process,
no separate config to manage.
Where to set it up
Section titled “Where to set it up”In the connection edit modal, toggle Use SSH tunnel. Three new fields appear:
| Field | Notes |
|---|---|
| Bastion host | The jump-box address (bastion.example.com) |
| Port | 22 (default) |
| User | The SSH user on the bastion |
| Auth method | Key file / password / agent |
Quay opens the SSH connection, forwards the database port through
it, and connects to the database via the tunnel. Once the tunnel is
up, the rest of the connection (host / port / user / password) is
addressed against the bastion-side host — usually localhost or
the database’s internal hostname.
Auth methods
Section titled “Auth methods”Key file
Section titled “Key file”Point Quay at ~/.ssh/id_ed25519 (or any key path). Encrypted keys
prompt for the passphrase once per session. Quay stores the
passphrase only in memory — never to disk.
Password
Section titled “Password”Username + password. Stored in connections.json like any other
credential (mode 0600 plaintext — locked decision).
Agent (recommended for shared workstations)
Section titled “Agent (recommended for shared workstations)”If SSH_AUTH_SOCK is set in your environment, pick Agent. Quay
delegates to ssh-agent / 1Password / Yubikey-OpenSSH-bridge / etc.
No keys leave the agent.
Keepalive + auto-reconnect
Section titled “Keepalive + auto-reconnect”The tunnel sends a server-side keepalive ping every 30 seconds. If three consecutive pings fail, the tunnel marks itself unhealthy and tries to reconnect with exponential backoff (2s, 5s, 10s, 30s, 60s, then steady at 60s).
While reconnecting, the connection chip in the rail shows a yellow dot + a “reconnecting…” tooltip. Queries issued during the gap get a “tunnel reconnecting; retry in a moment” error rather than a silent stall.
TOFU host-keys
Section titled “TOFU host-keys”First connection to a bastion: Quay shows the bastion’s SSH host-key fingerprint + asks you to confirm. Subsequent connections verify against the cached fingerprint and warn if it changes — the standard “trust on first use” pattern.
The fingerprints live next to connections.json:
~/Library/Application Support/com.unclez.quay/known-hosts.json
(or ~/.config/quay/known-hosts.json on Linux). Same JSON format
as the rest, mode 0600, swappable in an emergency.
Multi-hop tunnels
Section titled “Multi-hop tunnels”Quay v0.3 supports a single hop. For multi-hop (me → bastion-1 → bastion-2 → db), use ssh’s ProxyJump in your local
~/.ssh/config and have Quay’s tunnel target the proxied host:
Host bastion-2 HostName 10.0.1.5 ProxyJump bastion-1Then in Quay’s tunnel host field: bastion-2. SSH-config-aware
connection is automatic when the host matches an entry in your
local config.
Multi-hop UI in Quay itself (without leaning on ~/.ssh/config) is
on the v0.4 roadmap.
SSH live health pill
Section titled “SSH live health pill”The connection chip shows the tunnel state at a glance:
- 🟢 Green dot — tunnel up, last keepalive ≤ 30s ago
- 🟡 Yellow dot — reconnecting (also visible in the chip’s tooltip)
- 🔴 Red dot — tunnel down + reconnect failed; Quay paused retries after the backoff ceiling. Click to manually retry.
The pill updates live as keepalives fire — no need to refresh or restart Quay to see the latest state.
Common errors
Section titled “Common errors”permission denied (publickey)— the bastion didn’t accept the offered key. Test the key withssh -i <keyfile> user@bastionto confirm.too many authentication failures— your agent has too many keys; SSH offered them all. AddIdentitiesOnly yesto your ssh-config for the bastion, or pick a specific key in Quay.connection timed out— the bastion isn’t reachable. Firewall? VPN not up? Check independently.host key verification failed— the bastion’s key changed. Either confirm the change is legitimate (the bastion was rebuilt) and re-trust through the chip’s “update host key” option, or someone’s MITMing you and you should investigate.