docs/sdk/go/ssh.mdx
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 for usage flows.
<div className="msb-glance"> <p className="msb-gl"><span className="msb-dot instance"></span>Methods<span className="msb-ct">20</span></p> <a className="msb-row" href="#sb-ssh"><span className="msb-rn">sb.SSH()</span><span className="msb-rg">SSH namespace for this sandbox</span></a> <a className="msb-row" href="#ssh-openclient"><span className="msb-rn">ssh.OpenClient()</span><span className="msb-rg">open a native client</span></a> <a className="msb-row" href="#ssh-prepareserver"><span className="msb-rn">ssh.PrepareServer()</span><span className="msb-rg">prepare a server endpoint</span></a> <a className="msb-row" href="#c-exec"><span className="msb-rn">c.Exec()</span><span className="msb-rg">run a command</span></a> <a className="msb-row" href="#c-attach"><span className="msb-rn">c.Attach()</span><span className="msb-rg">interactive shell</span></a> <a className="msb-row" href="#c-sftp"><span className="msb-rn">c.SFTP()</span><span className="msb-rg">open an SFTP session</span></a> <a className="msb-row" href="#c-close"><span className="msb-rn">c.Close()</span><span className="msb-rg">close the client</span></a> <a className="msb-row" href="#srv-serveconnection"><span className="msb-rn">srv.ServeConnection()</span><span className="msb-rg">serve one connection</span></a> <a className="msb-row" href="#srv-close"><span className="msb-rn">srv.Close()</span><span className="msb-rg">release the endpoint</span></a> <a className="msb-row" href="#o-success"><span className="msb-rn">o.Success()</span><span className="msb-rg">exit status was 0</span></a> <a className="msb-row" href="#sftpclient"><span className="msb-rn">sftp.Read()</span><span className="msb-rg">read a file</span></a> <a className="msb-row" href="#sftpclient"><span className="msb-rn">sftp.Write()</span><span className="msb-rg">write a file</span></a> <a className="msb-row" href="#sftpclient"><span className="msb-rn">sftp.Mkdir()</span><span className="msb-rg">create a directory</span></a> <a className="msb-row" href="#sftpclient"><span className="msb-rn">sftp.Rename()</span><span className="msb-rg">rename a path</span></a> <a className="msb-row" href="#sftpclient"><span className="msb-rn">sftp.RealPath()</span><span className="msb-rg">resolve a canonical path</span></a> <a className="msb-row" href="#sftpclient"><span className="msb-rn">sftp.Symlink()</span><span className="msb-rg">create a symlink</span></a> <a className="msb-row" href="#sftpclient"><span className="msb-rn">sftp.Close()</span><span className="msb-rg">+ 3 more in SFTPClient</span></a> <p className="msb-gl"><span className="msb-dot builder"></span>Options<span className="msb-ct">10</span></p> <div className="msb-chiprow"> <a className="msb-chip" href="#sshclientoption">WithSSHUser()</a> <a className="msb-chip" href="#sshclientoption">WithSSHTerm()</a> <a className="msb-chip" href="#sshclientoption">WithSSHClientSFTP()</a> <a className="msb-chip" href="#sshexecoption">WithSSHTTY()</a> <a className="msb-chip" href="#sshattachoption">WithSSHAttachTerm()</a> <a className="msb-chip" href="#sshattachoption">WithSSHDetachKeys()</a> <a className="msb-chip" href="#sshserveroption">WithSSHHostKeyPath()</a> <a className="msb-chip" href="#sshserveroption">WithSSHAuthorizedKeysPath()</a> <a className="msb-chip" href="#sshserveroption">WithSSHServerUser()</a> <a className="msb-chip" href="#sshserveroption">WithSSHServerSFTP()</a> </div> <p className="msb-gl"><span className="msb-dot type"></span>Types</p> <div className="msb-chiprow"> <a className="msb-typepill" href="#sandboxsshops">SandboxSSHOps</a> <a className="msb-typepill" href="#sshclient">SSHClient</a> <a className="msb-typepill" href="#sftpclient">SFTPClient</a> <a className="msb-typepill" href="#sshserver">SSHServer</a> <a className="msb-typepill" href="#sshoutput">SSHOutput</a> <a className="msb-typepill" href="#sshclientoption">SSHClientOption</a> <a className="msb-typepill" href="#sshexecoption">SSHExecOption</a> <a className="msb-typepill" href="#sshattachoption">SSHAttachOption</a> <a className="msb-typepill" href="#sshserveroption">SSHServerOption</a> </div> </div> <p className="msb-label" id="typical-flow">Typical flow</p>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)
func (s *Sandbox) SSH() *SandboxSSHOps
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> <Accordion title="Example">ssh := sb.SSH()
client, err := ssh.OpenClient(ctx)
func (ssh *SandboxSSHOps) OpenClient(ctx context.Context, opts ...SSHClientOption) (*SSHClient, error)
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.
client, err := sb.SSH().OpenClient(ctx,
m.WithSSHUser("app"),
m.WithSSHTerm("xterm-256color"),
)
if err != nil {
return err
}
defer client.Close(ctx)
func (ssh *SandboxSSHOps) PrepareServer(ctx context.Context, opts ...SSHServerOption) (*SSHServer, error)
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 can serve connections one at a time over the process's standard streams.
srv, err := sb.SSH().PrepareServer(ctx,
m.WithSSHAuthorizedKeysPath("/etc/msb/authorized_keys"),
)
if err != nil {
return err
}
defer srv.Close(ctx)
func (c *SSHClient) Exec(ctx context.Context, command string, opts ...SSHExecOption) (*SSHOutput, error)
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 is passed.
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)
func (c *SSHClient) Attach(ctx context.Context, opts ...SSHAttachOption) (int, error)
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> <Accordion title="Example">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)
func (c *SSHClient) SFTP(ctx context.Context) (*SFTPClient, error)
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> <Accordion title="Example">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
}
func (c *SSHClient) Close(ctx context.Context) error
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> <Accordion title="Example">defer client.Close(ctx)
func (srv *SSHServer) ServeConnection(ctx context.Context) error
Serve one SSH transport over this process's stdin and stdout. Returns when the connection ends. Call again on the same SSHServer to serve another connection.
srv, err := sb.SSH().PrepareServer(ctx)
if err != nil {
return err
}
defer srv.Close(ctx)
if err := srv.ServeConnection(ctx); err != nil {
return err
}
func (srv *SSHServer) Close(ctx context.Context) error
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> <Accordion title="Example">defer srv.Close(ctx)
func (o SSHOutput) Success() bool
Report whether the command exited with status 0.
out, err := client.Exec(ctx, "test -f /etc/passwd")
if err != nil {
return err
}
fmt.Println("present:", out.Success())
SSH operations namespace for a sandbox. Obtained via sb.SSH(). Holds no resources; it groups the client and server entry points.
| Method | Returns | Description |
|---|---|---|
OpenClient(ctx, opts...) | (*SSHClient, error) | Open a native in-process SSH client |
PrepareServer(ctx, opts...) | (*SSHServer, error) | Prepare a reusable SSH server endpoint |
A native in-process SSH client session. Obtained via OpenClient().
| Method | Returns | Description |
|---|---|---|
Exec(ctx, command, opts...) | (*SSHOutput, error) | Run a command and collect output |
Attach(ctx, opts...) | (int, error) | Bridge the local terminal to an interactive shell |
SFTP(ctx) | (*SFTPClient, error) | Open an SFTP session over this connection |
Close(ctx) | error | Close the session (consumes the handle) |
A high-level SFTP client session over an SSH connection. Obtained via 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) |
A prepared SSH server endpoint for a sandbox. Obtained via PrepareServer().
| Method | Returns | Description |
|---|---|---|
ServeConnection(ctx) | error | Serve one SSH transport over stdin/stdout |
Close(ctx) | error | Release the endpoint (consumes the handle) |
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() | bool | true when Status is 0 |
Functional option for 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 |
Functional option for Exec().
| Option | Description |
|---|---|
| WithSSHTTY(enabled) | Request a PTY for the exec channel |
Functional option for 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 |
Functional option for 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 |