> ## 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

> Go 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. See [SSH](/sandboxes/ssh) for usage flows.

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

```go theme={null}
import (
    "context"

    m "github.com/superradcompany/microsandbox/sdk/go"
)

ctx := context.Background()

client, err := sb.SSH().OpenClient(ctx)   // 1. open a native client
if err != nil {
    return err
}
defer client.Close(ctx)

out, err := client.Exec(ctx, "uname -a")  // 2. run a command
if err != nil {
    return err
}
fmt.Printf("%s (exit %d)\n", out.Stdout, out.Status)
```

## Methods

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

```go theme={null}
func (s *Sandbox) SSH() *SandboxSSHOps
```

<Accordion title="Example">
  ```go theme={null}
  ssh := sb.SSH()
  client, err := ssh.OpenClient(ctx)
  ```
</Accordion>

Return the SSH operations namespace for this sandbox. The namespace groups the client and server helpers; it holds no resources of its own.

<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 client and server helpers for this sandbox.</div>
  </div>
</div>

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

```go theme={null}
func (ssh *SandboxSSHOps) OpenClient(ctx context.Context, opts ...SSHClientOption) (*SSHClient, error)
```

<Accordion title="Example">
  ```go theme={null}
  client, err := sb.SSH().OpenClient(ctx,
      m.WithSSHUser("app"),
      m.WithSSHTerm("xterm-256color"),
  )
  if err != nil {
      return err
  }
  defer client.Close(ctx)
  ```
</Accordion>

Open 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. With no options it uses login user `root`, terminal from `$TERM` (falling back to `xterm`), and SFTP enabled.

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

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>ctx</code><span className="msb-type">context.Context</span></div>
    <div className="msb-param-desc">Cancels the connection attempt.</div>
  </div>

  <div className="msb-param">
    <div className="msb-param-key"><code>opts</code><a className="msb-type" href="#sshclientoption">...SSHClientOption</a></div>
    <div className="msb-param-desc">Login user, terminal name, and SFTP toggle.</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">Native SSH client session.</div>
  </div>

  <div className="msb-param">
    <div className="msb-param-key"><span className="msb-type">error</span></div>
    <div className="msb-param-desc">Typed microsandbox error.</div>
  </div>
</div>

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

```go theme={null}
func (ssh *SandboxSSHOps) PrepareServer(ctx context.Context, opts ...SSHServerOption) (*SSHServer, error)
```

<Accordion title="Example">
  ```go theme={null}
  srv, err := sb.SSH().PrepareServer(ctx,
      m.WithSSHAuthorizedKeysPath("/etc/msb/authorized_keys"),
  )
  if err != nil {
      return err
  }
  defer srv.Close(ctx)
  ```
</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 unless overridden. The returned [`SSHServer`](#sshserver) can serve connections one at a time over the process's standard streams.

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

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>ctx</code><span className="msb-type">context.Context</span></div>
    <div className="msb-param-desc">Cancels server preparation.</div>
  </div>

  <div className="msb-param">
    <div className="msb-param-key"><code>opts</code><a className="msb-type" href="#sshserveroption">...SSHServerOption</a></div>
    <div className="msb-param-desc">Host key, authorized keys, guest user, and SFTP toggle.</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">Prepared server endpoint.</div>
  </div>

  <div className="msb-param">
    <div className="msb-param-key"><span className="msb-type">error</span></div>
    <div className="msb-param-desc">Typed microsandbox error.</div>
  </div>
</div>

#### <span className="msb-recv">c.</span><span className="msb-hn">Exec()</span>

```go theme={null}
func (c *SSHClient) Exec(ctx context.Context, command string, opts ...SSHExecOption) (*SSHOutput, error)
```

<Accordion title="Example">
  ```go theme={null}
  out, err := client.Exec(ctx, "python -V")
  if err != nil {
      return err
  }
  if !out.Success() {
      return fmt.Errorf("exit %d: %s", out.Status, out.Stderr)
  }
  fmt.Printf("%s", 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. No PTY is requested unless [`WithSSHTTY`](#sshexecoption) is passed.

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

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>ctx</code><span className="msb-type">context.Context</span></div>
    <div className="msb-param-desc">Cancels the exec request.</div>
  </div>

  <div className="msb-param">
    <div className="msb-param-key"><code>command</code><span className="msb-type">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>opts</code><a className="msb-type" href="#sshexecoption">...SSHExecOption</a></div>
    <div className="msb-param-desc">PTY toggle for the exec channel.</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 stdout, stderr, and exit status.</div>
  </div>

  <div className="msb-param">
    <div className="msb-param-key"><span className="msb-type">error</span></div>
    <div className="msb-param-desc">Typed microsandbox error.</div>
  </div>
</div>

#### <span className="msb-recv">c.</span><span className="msb-hn">Attach()</span>

```go theme={null}
func (c *SSHClient) Attach(ctx context.Context, opts ...SSHAttachOption) (int, error)
```

<Accordion title="Example">
  ```go theme={null}
  code, err := client.Attach(ctx,
      m.WithSSHAttachTerm("xterm-256color"),
      m.WithSSHDetachKeys("ctrl-p,ctrl-q"),
  )
  if err != nil {
      return err
  }
  fmt.Printf("shell exited with %d\n", code)
  ```
</Accordion>

Bridge 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 detach key sequence is typed.

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

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>ctx</code><span className="msb-type">context.Context</span></div>
    <div className="msb-param-desc">Cancels the attach session.</div>
  </div>

  <div className="msb-param">
    <div className="msb-param-key"><code>opts</code><a className="msb-type" href="#sshattachoption">...SSHAttachOption</a></div>
    <div className="msb-param-desc">Terminal name and detach key sequence.</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">int</span></div>
    <div className="msb-param-desc">Shell exit code (128 if terminated by signal).</div>
  </div>

  <div className="msb-param">
    <div className="msb-param-key"><span className="msb-type">error</span></div>
    <div className="msb-param-desc">Typed microsandbox error.</div>
  </div>
</div>

#### <span className="msb-recv">c.</span><span className="msb-hn">SFTP()</span>

```go theme={null}
func (c *SSHClient) SFTP(ctx context.Context) (*SFTPClient, error)
```

<Accordion title="Example">
  ```go theme={null}
  sftp, err := client.SFTP(ctx)
  if err != nil {
      return err
  }
  defer sftp.Close(ctx)

  if err := sftp.Write(ctx, "/tmp/hello.txt", []byte("hi")); err != nil {
      return err
  }
  ```
</Accordion>

Open an SFTP session over this SSH connection. Returns a high-level SFTP client for reading, writing, and managing files inside the guest. Requires SFTP enabled on the client (the default).

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

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>ctx</code><span className="msb-type">context.Context</span></div>
    <div className="msb-param-desc">Cancels opening the SFTP session.</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="#sftpclient">\*SFTPClient</a></div>
    <div className="msb-param-desc">SFTP client session.</div>
  </div>

  <div className="msb-param">
    <div className="msb-param-key"><span className="msb-type">error</span></div>
    <div className="msb-param-desc">Typed microsandbox error.</div>
  </div>
</div>

#### <span className="msb-recv">c.</span><span className="msb-hn">Close()</span>

```go theme={null}
func (c *SSHClient) Close(ctx context.Context) error
```

<Accordion title="Example">
  ```go theme={null}
  defer client.Close(ctx)
  ```
</Accordion>

Close this SSH client session. The handle is consumed; do not use it after closing.

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

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>ctx</code><span className="msb-type">context.Context</span></div>
    <div className="msb-param-desc">Cancels the close.</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">error</span></div>
    <div className="msb-param-desc">Typed microsandbox error.</div>
  </div>
</div>

#### <span className="msb-recv">srv.</span><span className="msb-hn">ServeConnection()</span>

```go theme={null}
func (srv *SSHServer) ServeConnection(ctx context.Context) error
```

<Accordion title="Example">
  ```go theme={null}
  srv, err := sb.SSH().PrepareServer(ctx)
  if err != nil {
      return err
  }
  defer srv.Close(ctx)

  if err := srv.ServeConnection(ctx); err != nil {
      return err
  }
  ```
</Accordion>

Serve one SSH transport over this process's stdin and stdout. Returns when the connection ends. Call again on the same [`SSHServer`](#sshserver) to serve another connection.

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

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>ctx</code><span className="msb-type">context.Context</span></div>
    <div className="msb-param-desc">Cancels serving the connection.</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">error</span></div>
    <div className="msb-param-desc">Typed microsandbox error.</div>
  </div>
</div>

#### <span className="msb-recv">srv.</span><span className="msb-hn">Close()</span>

```go theme={null}
func (srv *SSHServer) Close(ctx context.Context) error
```

<Accordion title="Example">
  ```go theme={null}
  defer srv.Close(ctx)
  ```
</Accordion>

Release this prepared server endpoint. The handle is consumed; do not use it after closing.

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

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>ctx</code><span className="msb-type">context.Context</span></div>
    <div className="msb-param-desc">Cancels the close.</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">error</span></div>
    <div className="msb-param-desc">Typed microsandbox error.</div>
  </div>
</div>

#### <span className="msb-recv">o.</span><span className="msb-hn">Success()</span>

```go theme={null}
func (o SSHOutput) Success() bool
```

<Accordion title="Example">
  ```go theme={null}
  out, err := client.Exec(ctx, "test -f /etc/passwd")
  if err != nil {
      return err
  }
  fmt.Println("present:", out.Success())
  ```
</Accordion>

Report whether the command exited with status `0`.

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

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><span className="msb-type">bool</span></div>
    <div className="msb-param-desc"><code>true</code> when <code>Status</code> is <code>0</code>.</div>
  </div>
</div>

## Types

### SandboxSSHOps

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

SSH operations namespace for a sandbox. Obtained via [`sb.SSH()`](#sb-ssh). Holds no resources; it groups the client and server entry points.

| Method                                              | Returns                                 | Description                            |
| --------------------------------------------------- | --------------------------------------- | -------------------------------------- |
| [`OpenClient(ctx, opts...)`](#ssh-openclient)       | `(`[`*SSHClient`](#sshclient)`, error)` | Open a native in-process SSH client    |
| [`PrepareServer(ctx, opts...)`](#ssh-prepareserver) | `(`[`*SSHServer`](#sshserver)`, error)` | Prepare a reusable SSH server endpoint |

### SSHClient

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

A native in-process SSH client session. Obtained via [`OpenClient()`](#ssh-openclient).

| Method                                   | Returns                                   | Description                                       |
| ---------------------------------------- | ----------------------------------------- | ------------------------------------------------- |
| [`Exec(ctx, command, opts...)`](#c-exec) | `(`[`*SSHOutput`](#sshoutput)`, error)`   | Run a command and collect output                  |
| [`Attach(ctx, opts...)`](#c-attach)      | `(int, error)`                            | Bridge the local terminal to an interactive shell |
| [`SFTP(ctx)`](#c-sftp)                   | `(`[`*SFTPClient`](#sftpclient)`, error)` | Open an SFTP session over this connection         |
| [`Close(ctx)`](#c-close)                 | `error`                                   | Close the session (consumes the handle)           |

### SFTPClient

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

A high-level SFTP client session over an SSH connection. Obtained via [`SFTP()`](#c-sftp).

| Method                         | Returns           | Description                                   |
| ------------------------------ | ----------------- | --------------------------------------------- |
| Read(ctx, path)                | `([]byte, error)` | Read a file into memory                       |
| Write(ctx, path, data)         | `error`           | Write a file, creating or truncating it       |
| Mkdir(ctx, path)               | `error`           | Create a directory                            |
| RemoveFile(ctx, path)          | `error`           | Remove a file                                 |
| RemoveDir(ctx, path)           | `error`           | Remove an empty directory                     |
| Rename(ctx, oldPath, newPath)  | `error`           | Rename a file or directory                    |
| RealPath(ctx, path)            | `(string, error)` | Resolve a path to its canonical absolute form |
| ReadLink(ctx, path)            | `(string, error)` | Read a symlink target                         |
| Symlink(ctx, target, linkPath) | `error`           | Create a symlink                              |
| Close(ctx)                     | `error`           | Close the session (consumes the handle)       |

### SSHServer

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

A prepared SSH server endpoint for a sandbox. Obtained via [`PrepareServer()`](#ssh-prepareserver).

| Method                                         | Returns | Description                                |
| ---------------------------------------------- | ------- | ------------------------------------------ |
| [`ServeConnection(ctx)`](#srv-serveconnection) | `error` | Serve one SSH transport over stdin/stdout  |
| [`Close(ctx)`](#srv-close)                     | `error` | Release the endpoint (consumes the handle) |

### SSHOutput

<p className="msb-backref">Returned by <a href="#c-exec">Exec()</a></p>

The output from an SSH exec request.

| Field / Method            | Type     | Description                 |
| ------------------------- | -------- | --------------------------- |
| Status                    | `int`    | Exit status code            |
| Stdout                    | `[]byte` | Captured stdout bytes       |
| Stderr                    | `[]byte` | Captured stderr bytes       |
| [`Success()`](#o-success) | `bool`   | `true` when `Status` is `0` |

### SSHClientOption

<p className="msb-backref">Used by <a href="#ssh-openclient">OpenClient()</a></p>

Functional option for [`OpenClient()`](#ssh-openclient). Defaults: user `root`, terminal from `$TERM` (falling back to `xterm`), SFTP enabled.

| Option                     | Description                                                   |
| -------------------------- | ------------------------------------------------------------- |
| WithSSHUser(user)          | SSH login user. Default `root`                                |
| WithSSHTerm(term)          | Terminal name for interactive sessions                        |
| WithSSHClientSFTP(enabled) | Enable or disable SFTP on the internal server. Default `true` |

### SSHExecOption

<p className="msb-backref">Used by <a href="#c-exec">Exec()</a></p>

Functional option for [`Exec()`](#c-exec).

| Option              | Description                        |
| ------------------- | ---------------------------------- |
| WithSSHTTY(enabled) | Request a PTY for the exec channel |

### SSHAttachOption

<p className="msb-backref">Used by <a href="#c-attach">Attach()</a></p>

Functional option for [`Attach()`](#c-attach). The default terminal comes from `$TERM` (falling back to `xterm`); detach keys default to the standard sequence.

| Option                  | Description                             |
| ----------------------- | --------------------------------------- |
| WithSSHAttachTerm(term) | Terminal name for the interactive shell |
| WithSSHDetachKeys(keys) | Detach key sequence                     |

### SSHServerOption

<p className="msb-backref">Used by <a href="#ssh-prepareserver">PrepareServer()</a></p>

Functional option for [`PrepareServer()`](#ssh-prepareserver). SFTP is enabled by default; when no authorized-keys path is provided, the default authorized-keys file is loaded.

| Option                          | Description                                                   |
| ------------------------------- | ------------------------------------------------------------- |
| WithSSHHostKeyPath(path)        | Override the host private key path                            |
| WithSSHAuthorizedKeysPath(path) | Override the authorized-keys path                             |
| WithSSHServerUser(user)         | Override the guest user used for SSH exec requests            |
| WithSSHServerSFTP(enabled)      | Enable or disable SFTP on the server endpoint. Default `true` |
