SSH tunneling
Some databases are not directly reachable from your laptop — they sit inside a private network, and the only way in is through an SSH bastion host. SeeKi can open that tunnel for you and route the database connection through it. You still write a single connection string; SeeKi handles the middle.
When you need this
Turn on tunneling if any of the following is true:
- The database host is an internal address you cannot ping from your laptop (
10.x.x.x,172.16.x.x, a private VPC endpoint). - The database is only accessible from a specific jump box your team already SSHs into.
- Your security policy forbids opening database ports to the outside world.
If you can already reach the database directly with psql from your laptop, you do not need a tunnel. Skip this page and use Connections.
How it works
When [ssh] is present in seeki.toml, SeeKi does this on startup:
- Picks an unused local port.
- Opens an SSH session to the bastion you named.
- Forwards that local port through the session to the database host and port.
- Connects to the database using the forwarded local port.
The tunnel stays open for the life of the SeeKi process and closes automatically when you stop it.
Authenticating to the bastion
SeeKi supports two practical choices: a private key on disk, or your running SSH agent. Password auth is defined in the schema but not yet implemented — stick to keys.
Option A · Private key file
Use when the key is unencrypted and sits at a known path.
[database]
kind = "postgres"
url = "postgres://reporting:s3cret@10.0.12.7:5432/autoconnect"
[ssh]
host = "bastion.example.com"
port = 22
username = "jlim"
auth_method = "key"
key_path = "/home/jlim/.ssh/id_ed25519"
Option B · SSH agent
Use when your key has a passphrase, or you already load keys into ssh-agent at login. This is the recommended choice for most teams.
[ssh]
host = "bastion.example.com"
port = 22
username = "jlim"
auth_method = "agent"
Before starting SeeKi, add the key to the agent:
ssh-add ~/.ssh/id_ed25519
The database URL in a tunnel
Write the URL as if SeeKi were running on the bastion itself. The host and port point at the database’s private address — the address the bastion uses, not your laptop. SeeKi rewrites the connection through the forwarded local port for you.
# "10.0.12.7" is the private address of the database,
# reachable from the bastion but not from your laptop.
url = "postgres://reporting:s3cret@10.0.12.7:5432/autoconnect"
First-time host check
The first time SeeKi connects to a new bastion, it adds that host’s fingerprint to your ~/.ssh/known_hosts. If the fingerprint changes later, SeeKi refuses to connect until you review and update the entry — the same behaviour as the regular ssh command.
Troubleshooting
| Symptom | Likely cause | What to try |
|---|---|---|
| SSH connection failed on startup | Wrong username, host unreachable, or firewall between you and the bastion. | Run ssh username@host in a separate terminal. Fix that first; SeeKi uses the same rules. |
| Passphrase-protected SSH keys are not supported | You set auth_method = "key" on a key that needs a passphrase. |
Load the key into the agent with ssh-add and switch to auth_method = "agent". |
| Port forward failed | The bastion can reach the database host, but the database is refusing the connection, or the address is wrong. | SSH into the bastion and try psql -h 10.0.12.7 -U reporting autoconnect. Fix the address or credentials. |
| Password-based SSH auth is not supported yet | You set auth_method = "password". |
Generate a key (ssh-keygen), install its public half on the bastion, and switch to auth_method = "key" or "agent". |
| Host key verification complains about a changed fingerprint | The bastion was rebuilt, or someone is intercepting the connection. | Check with your ops team before editing ~/.ssh/known_hosts. Do not ignore the warning. |
What’s next
- Connections — full shape of the PostgreSQL URL.
- Config reference:
[ssh]— every field in the tunnel block. - Troubleshooting — when SeeKi starts but the grid stays empty.