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.
<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
ssh := sb.SSH()
client, err := ssh.OpenClient(ctx)
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>func (ssh *SandboxSSHOps) OpenClient(ctx context.Context, opts ...SSHClientOption) (*SSHClient, error)
client, err := sb.SSH().OpenClient(ctx,
m.WithSSHUser("app"),
m.WithSSHTerm("xterm-256color"),
)
if err != nil {
return err
}
defer client.Close(ctx)
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.
func (ssh *SandboxSSHOps) PrepareServer(ctx context.Context, opts ...SSHServerOption) (*SSHServer, error)
srv, err := sb.SSH().PrepareServer(ctx,
m.WithSSHAuthorizedKeysPath("/etc/msb/authorized_keys"),
)
if err != nil {
return err
}
defer srv.Close(ctx)
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.
func (c *SSHClient) Exec(ctx context.Context, command string, opts ...SSHExecOption) (*SSHOutput, error)
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)
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.
func (c *SSHClient) Attach(ctx context.Context, opts ...SSHAttachOption) (int, error)
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)
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>func (c *SSHClient) SFTP(ctx context.Context) (*SFTPClient, error)
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
}
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>func (c *SSHClient) Close(ctx context.Context) error
defer client.Close(ctx)
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>func (srv *SSHServer) ServeConnection(ctx context.Context) error
srv, err := sb.SSH().PrepareServer(ctx)
if err != nil {
return err
}
defer srv.Close(ctx)
if err := srv.ServeConnection(ctx); err != nil {
return err
}
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.
func (srv *SSHServer) Close(ctx context.Context) error
defer srv.Close(ctx)
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>func (o SSHOutput) Success() bool
out, err := client.Exec(ctx, "test -f /etc/passwd")
if err != nil {
return err
}
fmt.Println("present:", out.Success())
Report whether the command exited with status 0.
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 |