> ## Documentation Index
> Fetch the complete documentation index at: https://docs.microsandbox.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# SSH

> Rust SDK - SSH API reference

Reach a running sandbox over SSH: open a native in-process SSH client, run exec requests, attach an interactive shell, transfer files over SFTP, or stand up a reusable SSH server endpoint. Requires the `ssh` feature. See [SSH](/sandboxes/ssh) for usage flows.

```toml theme={null}
microsandbox = { version = "0.5.8", features = ["ssh"] }
```

<p className="msb-label" id="typical-flow">Typical flow</p>

```rust theme={null}
use microsandbox::Sandbox;

let sb = Sandbox::builder("api")
    .image("python")
    .create()
    .await?;

let client = sb.ssh().connect().await?;      // 1. open an SSH client
let out = client.exec("python -V").await?;   // 2. run a command
println!("{}", String::from_utf8_lossy(&out.stdout));

client.close().await?;                       // 3. close the session
```

## Sandbox

#### <span className="msb-recv">sb.</span><span className="msb-hn">ssh()</span>

```rust theme={null}
fn ssh(&self) -> SandboxSshOps
```

<Accordion title="Example">
  ```rust theme={null}
  let client = sb.ssh().connect().await?;
  ```
</Accordion>

Return the SSH namespace for this sandbox. The namespace holds the SSH client and server helpers; nothing connects until you call [`connect`](#ssh-connect) or [`server`](#ssh-server).

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#sandboxsshops">SandboxSshOps</a></div>
    <div className="msb-param-desc">SSH namespace for this sandbox.</div>
  </div>
</div>

## SandboxSshOps

SSH namespace for a sandbox, obtained from [`sb.ssh()`](#sb-ssh). SSH is only supported on local sandboxes; calls error with `Unsupported` against a cloud backend.

#### <span className="msb-recv">ssh.</span><span className="msb-hn">connect()</span>

```rust theme={null}
async fn connect(&self) -> MicrosandboxResult<SshClient>
```

<Accordion title="Example">
  ```rust theme={null}
  let client = sb.ssh().connect().await?;
  let out = client.exec("uname -a").await?;
  ```
</Accordion>

Connect a native in-process SSH client to this sandbox. Generates an ephemeral Ed25519 client and host key pair, stands up an internal server bound to a duplex stream, and authenticates over public key. Uses default client options (user `root`, terminal from `$TERM`, SFTP enabled).

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#sshclient">SshClient</a></div>
    <div className="msb-param-desc">Connected SSH client session.</div>
  </div>
</div>

#### <span className="msb-recv">ssh.</span><span className="msb-hn">open\_client()</span>

```rust theme={null}
async fn open_client(&self) -> MicrosandboxResult<SshClient>
```

Alias for [`connect`](#ssh-connect).

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#sshclient">SshClient</a></div>
    <div className="msb-param-desc">Connected SSH client session.</div>
  </div>
</div>

#### <span className="msb-recv">ssh.</span><span className="msb-hn">connect\_with()</span>

```rust theme={null}
async fn connect_with(
    &self,
    f: impl FnOnce(SshClientOptionsBuilder) -> SshClientOptionsBuilder,
) -> MicrosandboxResult<SshClient>
```

<Accordion title="Example">
  ```rust theme={null}
  let client = sb.ssh().connect_with(|opts| opts
      .user("app")
      .term("xterm-256color")).await?;
  ```
</Accordion>

Connect a native in-process SSH client with custom options. The closure configures the login user, terminal name, and whether SFTP is enabled on the internal server.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>f</code><a className="msb-type" href="#sshclientoptionsbuilder">FnOnce(SshClientOptionsBuilder)</a></div>
    <div className="msb-param-desc">Configure user, terminal, and SFTP support.</div>
  </div>
</div>

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#sshclient">SshClient</a></div>
    <div className="msb-param-desc">Connected SSH client session.</div>
  </div>
</div>

#### <span className="msb-recv">ssh.</span><span className="msb-hn">open\_client\_with()</span>

```rust theme={null}
async fn open_client_with(
    &self,
    f: impl FnOnce(SshClientOptionsBuilder) -> SshClientOptionsBuilder,
) -> MicrosandboxResult<SshClient>
```

Alias for [`connect_with`](#ssh-connect_with).

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>f</code><a className="msb-type" href="#sshclientoptionsbuilder">FnOnce(SshClientOptionsBuilder)</a></div>
    <div className="msb-param-desc">Configure user, terminal, and SFTP support.</div>
  </div>
</div>

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#sshclient">SshClient</a></div>
    <div className="msb-param-desc">Connected SSH client session.</div>
  </div>
</div>

#### <span className="msb-recv">ssh.</span><span className="msb-hn">server()</span>

```rust theme={null}
async fn server(&self) -> MicrosandboxResult<SshServer>
```

<Accordion title="Example">
  ```rust theme={null}
  let server = sb.ssh().server().await?;
  let (client_io, server_io) = tokio::io::duplex(64 * 1024);
  server.serve(server_io).await?;
  ```
</Accordion>

Prepare a reusable SSH server endpoint for this sandbox. Loads or creates the host key and resolves authorized keys from the default authorized-keys file. The returned [`SshServer`](#sshserver) is cloneable and can serve many connections.

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#sshserver">SshServer</a></div>
    <div className="msb-param-desc">Reusable SSH server endpoint.</div>
  </div>
</div>

#### <span className="msb-recv">ssh.</span><span className="msb-hn">prepare\_server()</span>

```rust theme={null}
async fn prepare_server(&self) -> MicrosandboxResult<SshServer>
```

Alias for [`server`](#ssh-server).

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#sshserver">SshServer</a></div>
    <div className="msb-param-desc">Reusable SSH server endpoint.</div>
  </div>
</div>

#### <span className="msb-recv">ssh.</span><span className="msb-hn">server\_with()</span>

```rust theme={null}
async fn server_with(
    &self,
    f: impl FnOnce(SshServerOptionsBuilder) -> SshServerOptionsBuilder,
) -> MicrosandboxResult<SshServer>
```

<Accordion title="Example">
  ```rust theme={null}
  let server = sb.ssh().server_with(|opts| opts
      .authorized_key("ssh-ed25519 AAAAC3Nza...")
      .user("app")
      .sftp(false)).await?;
  ```
</Accordion>

Prepare a server endpoint with custom host-key, authorization, guest-user, or SFTP options. If no authorized keys are configured, the default authorized-keys file is loaded; an empty key set is an error.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>f</code><a className="msb-type" href="#sshserveroptionsbuilder">FnOnce(SshServerOptionsBuilder)</a></div>
    <div className="msb-param-desc">Configure host key, authorized keys, guest user, and SFTP.</div>
  </div>
</div>

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#sshserver">SshServer</a></div>
    <div className="msb-param-desc">Reusable SSH server endpoint.</div>
  </div>
</div>

#### <span className="msb-recv">ssh.</span><span className="msb-hn">prepare\_server\_with()</span>

```rust theme={null}
async fn prepare_server_with(
    &self,
    f: impl FnOnce(SshServerOptionsBuilder) -> SshServerOptionsBuilder,
) -> MicrosandboxResult<SshServer>
```

Alias for [`server_with`](#ssh-server_with).

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>f</code><a className="msb-type" href="#sshserveroptionsbuilder">FnOnce(SshServerOptionsBuilder)</a></div>
    <div className="msb-param-desc">Configure host key, authorized keys, guest user, and SFTP.</div>
  </div>
</div>

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#sshserver">SshServer</a></div>
    <div className="msb-param-desc">Reusable SSH server endpoint.</div>
  </div>
</div>

## SshClient

A connected, native in-process SSH client session, obtained from [`connect`](#ssh-connect) or [`connect_with`](#ssh-connect_with). Aborts its internal server task on drop.

#### <span className="msb-recv">client.</span><span className="msb-hn">exec()</span>

```rust theme={null}
async fn exec(&self, command: impl Into<String>) -> MicrosandboxResult<SshOutput>
```

<Accordion title="Example">
  ```rust theme={null}
  let out = client.exec("echo hello").await?;
  println!("exit {}: {}", out.status, String::from_utf8_lossy(&out.stdout));
  ```
</Accordion>

Run an SSH exec request and collect stdout, stderr, and the exit status. The command is run through the sandbox's configured shell (default `/bin/sh -c`). No PTY is requested.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>command</code><span className="msb-type">impl Into\<String></span></div>
    <div className="msb-param-desc">Command string sent through SSH.</div>
  </div>
</div>

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#sshoutput">SshOutput</a></div>
    <div className="msb-param-desc">Captured output and exit status.</div>
  </div>
</div>

#### <span className="msb-recv">client.</span><span className="msb-hn">exec\_with()</span>

```rust theme={null}
async fn exec_with(
    &self,
    command: impl Into<String>,
    f: impl FnOnce(SshExecOptionsBuilder) -> SshExecOptionsBuilder,
) -> MicrosandboxResult<SshOutput>
```

<Accordion title="Example">
  ```rust theme={null}
  let out = client.exec_with("top -bn1", |opts| opts.tty(true)).await?;
  ```
</Accordion>

Run an SSH exec request with options. The closure can request a PTY via [`tty`](#sshexecoptionsbuilder); when a PTY is allocated, stderr is folded into stdout.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>command</code><span className="msb-type">impl Into\<String></span></div>
    <div className="msb-param-desc">Command string sent through SSH.</div>
  </div>

  <div className="msb-param">
    <div className="msb-param-key"><code>f</code><a className="msb-type" href="#sshexecoptionsbuilder">FnOnce(SshExecOptionsBuilder)</a></div>
    <div className="msb-param-desc">Configure exec options.</div>
  </div>
</div>

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#sshoutput">SshOutput</a></div>
    <div className="msb-param-desc">Captured output and exit status.</div>
  </div>
</div>

#### <span className="msb-recv">client.</span><span className="msb-hn">attach()</span>

```rust theme={null}
async fn attach(&self) -> MicrosandboxResult<i32>
```

<Accordion title="Example">
  ```rust theme={null}
  let code = client.attach().await?;
  println!("shell exited with {code}");
  ```
</Accordion>

Attach the local terminal to an interactive SSH shell. Requests a PTY sized to the current terminal, puts the terminal into raw mode, forwards keystrokes, relays window-resize events, and returns when the shell exits or the default detach key sequence is typed.

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><span className="msb-type">i32</span></div>
    <div className="msb-param-desc">Shell exit code (128 if terminated by signal).</div>
  </div>
</div>

#### <span className="msb-recv">client.</span><span className="msb-hn">attach\_with()</span>

```rust theme={null}
async fn attach_with(
    &self,
    f: impl FnOnce(SshAttachOptionsBuilder) -> SshAttachOptionsBuilder,
) -> MicrosandboxResult<i32>
```

<Accordion title="Example">
  ```rust theme={null}
  let code = client.attach_with(|opts| opts
      .term("xterm-256color")
      .detach_keys("ctrl-p,ctrl-q")).await?;
  ```
</Accordion>

Attach an interactive shell with custom terminal and detach-key options.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>f</code><a className="msb-type" href="#sshattachoptionsbuilder">FnOnce(SshAttachOptionsBuilder)</a></div>
    <div className="msb-param-desc">Configure terminal name and detach keys.</div>
  </div>
</div>

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><span className="msb-type">i32</span></div>
    <div className="msb-param-desc">Shell exit code (128 if terminated by signal).</div>
  </div>
</div>

#### <span className="msb-recv">client.</span><span className="msb-hn">sftp()</span>

```rust theme={null}
async fn sftp(&self) -> MicrosandboxResult<SftpClient>
```

<Accordion title="Example">
  ```rust theme={null}
  let sftp = client.sftp().await?;
  let mut file = sftp.create("/tmp/hello.txt").await?;
  ```
</Accordion>

Open an SFTP client session over this SSH connection. Requests the `sftp` subsystem and returns a high-level SFTP session for reading, writing, and listing files inside the guest.

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#sftpclient">SftpClient</a></div>
    <div className="msb-param-desc">SFTP client session.</div>
  </div>
</div>

#### <span className="msb-recv">client.</span><span className="msb-hn">close()</span>

```rust theme={null}
async fn close(self) -> MicrosandboxResult<()>
```

<Accordion title="Example">
  ```rust theme={null}
  client.close().await?;
  ```
</Accordion>

Close this native SSH client session. Sends a disconnect and aborts the internal server task. Consumes the client.

## SshServer

A reusable SSH server endpoint for a sandbox, obtained from [`server`](#ssh-server) or [`server_with`](#ssh-server_with). Cloneable; each call to [`serve`](#server-serve) handles one connection.

#### <span className="msb-recv">server.</span><span className="msb-hn">serve()</span>

```rust theme={null}
async fn serve<S>(&self, stream: S) -> MicrosandboxResult<()>
where
    S: AsyncRead + AsyncWrite + Unpin + Send + 'static,
```

<Accordion title="Example">
  ```rust theme={null}
  let server = sb.ssh().server().await?;
  let (client_io, server_io) = tokio::io::duplex(64 * 1024);
  tokio::spawn(async move { server.serve(server_io).await });
  ```
</Accordion>

Serve one SSH connection over an ordered duplex stream. Runs the SSH handshake and session loop to completion. Returns when the connection closes.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>stream</code><span className="msb-type">S: AsyncRead + AsyncWrite</span></div>
    <div className="msb-param-desc">Ordered duplex SSH transport.</div>
  </div>
</div>

#### <span className="msb-recv">server.</span><span className="msb-hn">serve\_connection()</span>

```rust theme={null}
async fn serve_connection<S>(&self, stream: S) -> MicrosandboxResult<()>
where
    S: AsyncRead + AsyncWrite + Unpin + Send + 'static,
```

Alias for [`serve`](#server-serve).

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>stream</code><span className="msb-type">S: AsyncRead + AsyncWrite</span></div>
    <div className="msb-param-desc">Ordered duplex SSH transport.</div>
  </div>
</div>

## SshStdioStream

#### <span className="msb-recv">SshStdioStream::</span><span className="msb-hn">new()</span>

```rust theme={null}
fn new() -> Self
```

<Accordion title="Example">
  ```rust theme={null}
  use microsandbox::SshStdioStream;

  let server = sb.ssh().server().await?;
  server.serve(SshStdioStream::new()).await?;
  ```
</Accordion>

Create a stdio SSH transport stream backed by this process's stdin and stdout. Implements [`AsyncRead`](#sshstdiostream) and `AsyncWrite`, so it can be passed straight to [`serve`](#server-serve) to bridge an SSH connection over the parent process's standard streams. Also available via `Default`.

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#sshstdiostream">SshStdioStream</a></div>
    <div className="msb-param-desc">Duplex stream over stdin/stdout.</div>
  </div>
</div>

## Constants

#### <span className="msb-recv" /><span className="msb-hn">DEFAULT\_SSH\_HOST</span>

```rust theme={null}
pub const DEFAULT_SSH_HOST: &str = "127.0.0.1";
```

Default SSH listener host used by the CLI adapter when binding a sandbox SSH endpoint.

#### <span className="msb-recv" /><span className="msb-hn">DEFAULT\_SSH\_PORT</span>

```rust theme={null}
pub const DEFAULT_SSH_PORT: u16 = 2222;
```

Default SSH listener port used by the CLI adapter when binding a sandbox SSH endpoint.

## Types

### SshOutput

<p className="msb-backref">Returned by <a href="#client-exec">client.exec()</a>, <a href="#client-exec_with">client.exec\_with()</a></p>

Output from an SSH exec request.

| Field    | Type    | Description                                                         |
| -------- | ------- | ------------------------------------------------------------------- |
| `status` | `i32`   | Exit status code.                                                   |
| `stdout` | `Bytes` | Captured stdout bytes.                                              |
| `stderr` | `Bytes` | Captured stderr bytes (folded into stdout when a PTY is allocated). |

### SandboxSshOps

<p className="msb-backref">Returned by <a href="#sb-ssh">sb.ssh()</a></p>

SSH namespace for a sandbox. Cheap to clone; holds a clone of the sandbox.

| Method                                              | Returns     | Description                   |
| --------------------------------------------------- | ----------- | ----------------------------- |
| [`connect()`](#ssh-connect)                         | `SshClient` | Open a client with defaults.  |
| [`open_client()`](#ssh-open_client)                 | `SshClient` | Alias of `connect()`.         |
| [`connect_with()`](#ssh-connect_with)               | `SshClient` | Open a client with options.   |
| [`open_client_with()`](#ssh-open_client_with)       | `SshClient` | Alias of `connect_with()`.    |
| [`server()`](#ssh-server)                           | `SshServer` | Prepare a server endpoint.    |
| [`prepare_server()`](#ssh-prepare_server)           | `SshServer` | Alias of `server()`.          |
| [`server_with()`](#ssh-server_with)                 | `SshServer` | Server endpoint with options. |
| [`prepare_server_with()`](#ssh-prepare_server_with) | `SshServer` | Alias of `server_with()`.     |

### SshClient

<p className="msb-backref">Returned by <a href="#ssh-connect">ssh.connect()</a>, <a href="#ssh-connect_with">ssh.connect\_with()</a></p>

Native in-process SSH client session. Aborts its internal server task on drop.

| Method                                 | Returns      | Description           |
| -------------------------------------- | ------------ | --------------------- |
| [`exec()`](#client-exec)               | `SshOutput`  | Run a command.        |
| [`exec_with()`](#client-exec_with)     | `SshOutput`  | Run with options.     |
| [`attach()`](#client-attach)           | `i32`        | Interactive shell.    |
| [`attach_with()`](#client-attach_with) | `i32`        | Attach with options.  |
| [`sftp()`](#client-sftp)               | `SftpClient` | Open an SFTP session. |
| [`close()`](#client-close)             | `()`         | Close the session.    |

### SshServer

<p className="msb-backref">Returned by <a href="#ssh-server">ssh.server()</a>, <a href="#ssh-server_with">ssh.server\_with()</a></p>

Reusable SSH server endpoint for a sandbox. Cloneable.

| Method                                           | Returns | Description           |
| ------------------------------------------------ | ------- | --------------------- |
| [`serve()`](#server-serve)                       | `()`    | Serve one connection. |
| [`serve_connection()`](#server-serve_connection) | `()`    | Alias of `serve()`.   |

### SftpClient

<p className="msb-backref">Returned by <a href="#client-sftp">client.sftp()</a></p>

High-level SFTP client session.

```rust theme={null}
pub type SftpClient = russh_sftp::client::SftpSession;
```

### SshStdioStream

<p className="msb-backref">Used by <a href="#server-serve">server.serve()</a></p>

Ordered duplex stream backed by this process's stdin and stdout. Implements `AsyncRead` and `AsyncWrite`.

| Method                        | Returns          | Description                      |
| ----------------------------- | ---------------- | -------------------------------- |
| [`new()`](#sshstdiostreamnew) | `SshStdioStream` | Create a stdio transport stream. |

### SshClientOptionsBuilder

<p className="msb-backref">Used by <a href="#ssh-connect_with">ssh.connect\_with()</a></p>

Builder for SSH client options. Defaults: user `root`, terminal from `$TERM` (falling back to `xterm`), SFTP enabled.

| Method    | Parameters          | Description                                                    |
| --------- | ------------------- | -------------------------------------------------------------- |
| `user()`  | `impl Into<String>` | SSH login user. Default `root`.                                |
| `term()`  | `impl Into<String>` | Terminal name for interactive sessions.                        |
| `sftp()`  | `bool`              | Enable or disable SFTP on the internal server. Default `true`. |
| `build()` |                     | Finalize the options.                                          |

### SshExecOptionsBuilder

<p className="msb-backref">Used by <a href="#client-exec_with">client.exec\_with()</a></p>

Builder for SSH exec options.

| Method    | Parameters | Description                                          |
| --------- | ---------- | ---------------------------------------------------- |
| `tty()`   | `bool`     | Request a PTY for the exec channel. Default `false`. |
| `build()` |            | Finalize the options.                                |

### SshAttachOptionsBuilder

<p className="msb-backref">Used by <a href="#client-attach_with">client.attach\_with()</a></p>

Builder for interactive SSH attach options. Default terminal comes from `$TERM` (falling back to `xterm`); detach keys default to the standard sequence.

| Method          | Parameters          | Description                  |
| --------------- | ------------------- | ---------------------------- |
| `term()`        | `impl Into<String>` | Terminal name for the shell. |
| `detach_keys()` | `impl Into<String>` | Detach key sequence.         |
| `build()`       |                     | Finalize the options.        |

### SshServerOptionsBuilder

<p className="msb-backref">Used by <a href="#ssh-server_with">ssh.server\_with()</a></p>

Builder for SSH server options. SFTP is enabled by default; when no authorized keys are provided, the default authorized-keys file is loaded.

| Method                   | Parameters           | Description                                     |
| ------------------------ | -------------------- | ----------------------------------------------- |
| `host_key_path()`        | `impl Into<PathBuf>` | Override the host private key path.             |
| `host_key()`             | `PrivateKey`         | Use an in-memory host private key.              |
| `authorized_keys_path()` | `impl Into<PathBuf>` | Override the authorized-keys path.              |
| `authorized_key()`       | `impl Into<String>`  | Add one in-memory authorized public key.        |
| `user()`                 | `impl Into<String>`  | Override the guest user used for exec requests. |
| `sftp()`                 | `bool`               | Enable or disable SFTP. Default `true`.         |
| `build()`                |                      | Finalize the options.                           |
