# SSH Tunnel Connections in DBX: Key and Password Authentication Methods

> Explore SSH tunnel authentication methods in DBX including private key files and passwords. Learn to secure your DBX connections with detailed configuration insights.

- Repository: [skyler/dbx](https://github.com/t8y2/dbx)
- Tags: how-to-guide
- Published: 2026-07-05

---

**DBX supports four SSH tunnel authentication methods—private key files, plaintext passwords, SSH agent sockets, and automatic probing—controlled by the `auth_method` field in the `SshTunnelConfig` struct.**

DBX implements SSH tunneling as a first-class transport layer, enabling database drivers to reach remote servers through secure bastion hops. The tunnel configuration is defined in [`crates/dbx-core/src/models/connection.rs`](https://github.com/t8y2/dbx/blob/main/crates/dbx-core/src/models/connection.rs) and processed by the `TunnelManager` in [`crates/dbx-core/src/db/ssh_tunnel.rs`](https://github.com/t8y2/dbx/blob/main/crates/dbx-core/src/db/ssh_tunnel.rs), supporting both explicit authentication selection and legacy fallback behavior.

## Core SSH Tunnel Configuration Structure

The `SshTunnelConfig` struct stores all parameters required to establish an SSH tunnel, including host details, timeouts, and authentication credentials.

```rust
pub struct SshTunnelConfig {
    pub id: String,
    pub name: String,
    pub enabled: bool,
    pub host: String,                 // SSH server
    pub port: u16,                    // default 22
    pub user: String,                 // SSH login name
    pub password: String,             // password (if used)
    pub key_path: String,             // path to private key file
    pub key_passphrase: String,       // optional passphrase for the key
    pub connect_timeout_secs: u64,
    pub expose_lan: bool,
    pub use_ssh_agent: bool,
    pub ssh_agent_sock_path: String,
    /// Login method: `"password"`, `"key"`, `"agent"`, or `"none"`.
    pub auth_method: String,
}

```

*Source:* [`crates/dbx-core/src/models/connection.rs`](https://github.com/t8y2/dbx/blob/main/crates/dbx-core/src/models/connection.rs) (lines 138-176)

The `auth_method` field determines which credential type the backend attempts during connection. When left empty, DBX probes credentials in the order **key → password → agent** for backward compatibility.

## SSH Authentication Methods in DBX

DBX supports four distinct authentication strategies via the `auth_method` string:

- ** `"key"` ** – Loads the private key file specified in `key_path` and decrypts it using `key_passphrase` if provided.
- ** `"password"` ** – Transmits the plaintext password stored in the `password` field to the SSH daemon.
- ** `"agent"` ** – Connects to an SSH agent using `ssh_agent_sock_path` or the `$SSH_AUTH_SOCK` environment variable when `use_ssh_agent` is enabled.
- ** `"none"` or empty ** – Triggers automatic probing of non-empty credential fields in fallback order.

The authentication selection logic in [`crates/dbx-core/src/db/ssh_tunnel.rs`](https://github.com/t8y2/dbx/blob/main/crates/dbx-core/src/db/ssh_tunnel.rs) evaluates these conditions:

```rust
let try_key = auth_method.is_empty() && !ssh_key_path.is_empty() || auth_method == "key";
let try_password = auth_method.is_empty() && !ssh_password.is_empty() || auth_method == "password";
let try_agent = auth_method.is_empty() && use_ssh_agent || auth_method == "agent";

```

*Source:* [`crates/dbx-core/src/db/ssh_tunnel.rs`](https://github.com/t8y2/dbx/blob/main/crates/dbx-core/src/db/ssh_tunnel.rs) (lines 101-104)

The UI enforces explicit selection through the **Tunnel / Proxy → SSH Tunnel** dialog, presenting tabs for "Private Key (Recommended)" and "Password" as documented in `docs/content/docs/ssh-tunnel.mdx`.

## How DBX Establishes SSH Tunnel Connections

The tunnel creation process follows a structured flow from configuration to local port binding:

1. **Configuration Input** – The user supplies host, port, user, and authentication credentials through the UI or programmatic config.
2. **Chain Planning** – For multi-hop bastion setups, the `plan_chain` function walks each hop and returns a vector of `PlannedTunnel` structs describing the connection path.
   *Source:* [`crates/dbx-core/src/db/ssh_tunnel.rs`](https://github.com/t8y2/dbx/blob/main/crates/dbx-core/src/db/ssh_tunnel.rs) (lines 8-19)
3. **Client Initialization** – The `TunnelManager` opens an SSH client (`ssh_client_config`) for each hop, applying the selected `auth_method` using the `russh` library.
4. **Port Binding** – Once authenticated, DBX binds a local port and points the database driver at `127.0.0.1:<local-port>`, forwarding all traffic through the encrypted tunnel to the target host.

The high-level `open_ssh_tunnel` method orchestrates this process, accepting a connection identifier, configuration array, and target database host/port.

## SSH Tunnel Configuration Examples

### Key-Based Authentication

Configure a tunnel using a private key with optional passphrase protection:

```rust
use dbx_core::models::connection::SshTunnelConfig;

let ssh_cfg = SshTunnelConfig {
    id: "my_ssh".into(),
    name: "Bastion".into(),
    enabled: true,
    host: "bastion.example.com".into(),
    port: 22,
    user: "alice".into(),
    password: "".into(),               // not used
    key_path: "~/.ssh/id_rsa".into(),
    key_passphrase: "my‑passphrase".into(),
    connect_timeout_secs: 5,
    expose_lan: false,
    use_ssh_agent: false,
    ssh_agent_sock_path: "".into(),
    auth_method: "key".into(),        // forces key authentication
};

```

### Password-Based Authentication

Configure a tunnel using plaintext password authentication:

```rust
let ssh_cfg = SshTunnelConfig {
    id: "my_ssh".into(),
    name: "Bastion".into(),
    enabled: true,
    host: "bastion.example.com".into(),
    port: 22,
    user: "bob".into(),
    password: "s3cr3t".into(),
    key_path: "".into(),
    key_passphrase: "".into(),
    connect_timeout_secs: 5,
    expose_lan: false,
    use_ssh_agent: false,
    ssh_agent_sock_path: "".into(),
    auth_method: "password".into(),
};

```

### Opening the Tunnel

Use `TunnelManager` to establish the connection and bind the local port:

```rust
use dbx_core::db::ssh_tunnel::TunnelManager;

#[tokio::main]
async fn main() {
    let manager = TunnelManager::new();
    // `connection_id` is an arbitrary identifier for the DBX connection.
    manager
        .open_ssh_tunnel("my_connection", &[ssh_cfg], "db.internal", 5432)
        .await
        .expect("failed to open SSH tunnel");
}

```

### Connecting Through the Tunnel

Point your database driver at the local bound port to route through the SSH tunnel:

```rust
let pg_conn_str = "postgresql://alice@127.0.0.1:54321/mydb";
let (client, connection) = tokio_postgres::connect(pg_conn_str, tokio_postgres::NoTls).await?;

```

## Summary

- **DBX supports four SSH authentication methods**—key files, passwords, SSH agents, and automatic probing—configured via `SshTunnelConfig.auth_method`.
- **The `auth_method` field** explicitly selects the strategy; when empty, DBX falls back to probing key, then password, then agent.
- **Core implementation** resides in [`crates/dbx-core/src/db/ssh_tunnel.rs`](https://github.com/t8y2/dbx/blob/main/crates/dbx-core/src/db/ssh_tunnel.rs), using `plan_chain` for multi-hop routing and `TunnelManager` for connection handling.
- **Configuration structure** is defined in [`crates/dbx-core/src/models/connection.rs`](https://github.com/t8y2/dbx/blob/main/crates/dbx-core/src/models/connection.rs) with fields for keys, passphrases, passwords, and agent sockets.
- **Database connectivity** is achieved by binding a local port that forwards through the established SSH tunnel to the remote database host.

## Frequently Asked Questions

### What authentication methods does DBX support for SSH tunnel connections?

DBX supports four methods: private key files (`"key"`), plaintext passwords (`"password"`), SSH agent sockets (`"agent"`), and automatic probing (`"none"` or empty string). The `auth_method` field in `SshTunnelConfig` explicitly selects the method, with the UI offering "Private Key" and "Password" tabs for user configuration.

### How does DBX handle SSH authentication if I don't specify an auth_method?

When `auth_method` is empty, DBX implements backward-compatible probing logic that attempts authentication in the following order: private key (if `key_path` is non-empty), password (if `password` is non-empty), and finally SSH agent (if `use_ssh_agent` is true). This logic is implemented in [`crates/dbx-core/src/db/ssh_tunnel.rs`](https://github.com/t8y2/dbx/blob/main/crates/dbx-core/src/db/ssh_tunnel.rs).

### Can DBX use SSH agent forwarding for tunnel authentication?

Yes, DBX supports SSH agent authentication by setting `auth_method` to `"agent"` and either specifying `ssh_agent_sock_path` or enabling `use_ssh_agent` to default to the `$SSH_AUTH_SOCK` environment variable. This allows keyless authentication using locally loaded SSH keys without exposing private key files to DBX.

### Where is the SSH tunnel logic implemented in the DBX source code?

The primary implementation is in [`crates/dbx-core/src/db/ssh_tunnel.rs`](https://github.com/t8y2/dbx/blob/main/crates/dbx-core/src/db/ssh_tunnel.rs), containing the `TunnelManager`, `plan_chain` function for multi-hop routing, and authentication method selection logic. The configuration struct is defined in [`crates/dbx-core/src/models/connection.rs`](https://github.com/t8y2/dbx/blob/main/crates/dbx-core/src/models/connection.rs) (lines 138-176), while transport layer orchestration appears in [`crates/dbx-core/src/db/transport_layer_tunnel.rs`](https://github.com/t8y2/dbx/blob/main/crates/dbx-core/src/db/transport_layer_tunnel.rs).