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

# CLI

> Install the sail command-line tool, plus every command grouped by area

The `sail` CLI manages Sailboxes and apps from the terminal. It is a single
native binary with no runtime dependencies. Run `sail --help` or
`sail <command> --help` for the same information at the prompt, and see the
[Sailboxes guide](/sailboxes) for what you can do with it.

## Install

<Tabs>
  <Tab title="macOS and Linux">
    ```bash theme={null}
    curl -fsSL https://cli.sailresearch.com/install.sh | sh
    ```

    Installs the latest `sail` into `~/.sail/bin`. If that directory is not
    on your `PATH`, the installer adds it to your shell startup files and
    prints the line to run in the current shell.
  </Tab>

  <Tab title="Windows">
    ```powershell theme={null}
    irm https://cli.sailresearch.com/install.ps1 | iex
    ```

    Installs `sail.exe` into `%LOCALAPPDATA%\sail\bin` and puts that
    directory at the front of your user `PATH`. Restart your shell afterward.
  </Tab>

  <Tab title="pip">
    ```bash theme={null}
    pip install sail
    ```

    The Python SDK ships the CLI: `sail` is on your `PATH` in that
    environment, and it stays current with `pip install -U sail`.
  </Tab>
</Tabs>

To pin a version, set `SAIL_CLI_VERSION` for the installer, substituting the
release you want for `X.Y.Z`:

```bash theme={null}
curl -fsSL https://cli.sailresearch.com/install.sh | SAIL_CLI_VERSION=X.Y.Z sh
```

`SAIL_HOME` relocates sail's home directory, and `SAIL_INSTALL_DIR` installs a
copy at an exact path for provisioning scripts.

### Update

```bash theme={null}
sail update
```

Downloads the latest release and replaces the binary you ran. Sail warns when
your CLI version is nearing the end of its support window, and rejects one
past it with an update error before any operation runs. Upgrading a Sailbox
is a different operation: `sail box upgrade <sailbox>`.

## Interactive shell

For interactive use, `sail shell` is usually the most convenient option. It opens
a REPL on your machine that accepts every command below without the leading
`sail` (so `box list`, `box create ...`), and adds touches the one-shot commands
do not: line editing and history, a picker menu when you omit a Sailbox id, and
confirmation prompts.

```bash theme={null}
sail shell
```

The individual `sail <command>` subcommands take their arguments up front,
which suits scripts and agents (add `--json` for machine-readable output).

Mind the naming: `sail shell` is a shell for *managing* Sailboxes from your
machine. It is not a shell *inside* a box. To open a shell inside a running
Sailbox, use `sail box shell` (below).

## Authentication

```bash theme={null}
sail auth login [--api-key <key>]   # log in via the browser, or store a key with --api-key (or piped to stdin)
sail auth whoami                    # show the active key
sail auth logout                    # remove the stored key
```

Every command reads `SAIL_API_KEY`, falling back to the credential stored by
`sail auth login`. Add `--json` to any command for machine-readable output.
See [Configuration](/reference/sdk-configuration).

## Apps

```bash theme={null}
sail app find <name>     # find an app by name
sail app create <name>   # create an app (returns the existing one if present)
sail app list            # list apps in the current org
```

## Sailbox lifecycle

| Command                                                  | Description                                                                                                                                    |
| -------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| `sail box show <id>`                                     | Show a single Sailbox.                                                                                                                         |
| `sail box top`                                           | Live top-style view of Sailbox usage.                                                                                                          |
| `sail box list`                                          | List Sailboxes in the current org (see flags below).                                                                                           |
| `sail box terminate <id>`                                | Permanently terminate a Sailbox.                                                                                                               |
| `sail box sleep <id>`                                    | Checkpoint and release compute (`--wake-at` to schedule a wake).                                                                               |
| `sail box pause <id>`                                    | Freeze in place.                                                                                                                               |
| `sail box resume <id>`                                   | Resume a paused or sleeping Sailbox.                                                                                                           |
| `sail box checkpoint <id>`                               | Checkpoint a running Sailbox (`--name`, `--ttl-seconds`).                                                                                      |
| `sail box from-checkpoint <checkpoint-id> --name <name>` | Create a new Sailbox from a checkpoint, called `name`.                                                                                         |
| `sail box upgrade <id>`                                  | Upgrade the runtime (now if running, else at next wake).                                                                                       |
| `sail box auto-sleep <id> <value>`                       | Change when Sail may sleep it: `never`, `auto`, or 1 through 3600 idle seconds (`0` is the same as `auto`; other numeric values are rejected). |

### `sail box create`

```bash theme={null}
sail box create --app <name> --name <name> [options]
```

| Option                        | Description                                                                                                                                                                                                                                                                                                                                                                                         |
| ----------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--app <name>`                | App name (created if missing). Required.                                                                                                                                                                                                                                                                                                                                                            |
| `--name <name>`               | Sailbox name within the app. Required.                                                                                                                                                                                                                                                                                                                                                              |
| `--arch <arm\|amd>`           | Base image architecture (default `amd`).                                                                                                                                                                                                                                                                                                                                                            |
| `--port <n>`                  | HTTP ingress port to expose. Repeatable.                                                                                                                                                                                                                                                                                                                                                            |
| `--size <s\|m\|l>`            | Resource size (default `m`): `s` = 1 vCPU, 16 GiB memory, 32 GiB disk; `m` = 4 vCPU, 32 GiB memory, 128 GiB disk; `l` = 8 vCPU, 64 GiB memory, 256 GiB disk. Ongoing billing is by usage; each size also has a one-time creation charge. `s` gives the fastest cold starts and resumes.                                                                                                             |
| `--memory-limit-gib <n>`      | Memory ceiling in whole GiB, within the size's range: 2-64 for `s`, 8-128 for `m`, 16-256 for `l`. The size's default when omitted.                                                                                                                                                                                                                                                                 |
| `--disk-limit-gib <n>`        | Disk ceiling in whole GiB, within the size's range: 8-128 for `s`, 32-512 for `m`, 64-1024 for `l`. The size's default when omitted.                                                                                                                                                                                                                                                                |
| `--visibility <org\|private>` | Who may operate the Sailbox: `org` (the default) lets anyone in your org; `private` restricts all access to you (creator-only) and requires a user-minted API key. An org admin can override some operations on a private Sailbox with a recorded reason.                                                                                                                                           |
| `--enable-ssh`                | Expose port 22, trust your org's CA, and start sshd.                                                                                                                                                                                                                                                                                                                                                |
| `--identity-file <path>`      | Local SSH key to authenticate with (implies `--enable-ssh`).                                                                                                                                                                                                                                                                                                                                        |
| `--auto-sleep <value>`        | When Sail may sleep it on its own: `auto` (sleep when fully idle, wake the moment anything needs it; the default), `never` (stays running unless you stop it yourself), or a whole number of idle seconds from 1 through 3600 that replaces the default (`0` is the same as `auto`; other numeric values are rejected).                                                                             |
| `--no-network`                | Create the Sailbox cut off from other hosts and the internet: no outbound connections, no name resolution, and no exposed ingress or SSH. Running commands is unaffected (`sail box exec` and `sail box shell` reach the Sailbox over a Sail-internal path, not its network), and mounted volumes still work.                                                                                       |
| `--allow-host <host>`         | Allow outbound access only to this destination (repeatable, up to 128): a hostname, a `*.` wildcard hostname, an IPv4 address, or an IPv4 range such as `203.0.113.0/24`. Only connections the Sailbox opens are limited, so `--enable-ssh` and `--port` still work. Conflicts with `--no-network`. See [Network policy](/sailboxes-network-policy) for the entry rules and what each entry allows. |

### `sail box list`

| Option              | Description                  |
| ------------------- | ---------------------------- |
| `--app <name>`      | Filter by app name.          |
| `--status <status>` | Filter by status.            |
| `--search <text>`   | Filter by id/name substring. |
| `--limit <n>`       | Maximum rows.                |
| `--offset <n>`      | Rows to skip.                |

### `sail box top`

| Option                | Description                                                   |
| --------------------- | ------------------------------------------------------------- |
| `--app <name>`        | Filter by app name.                                           |
| `--status <status>`   | Filter by status.                                             |
| `--search <text>`     | Filter by id/name substring.                                  |
| `--refresh <seconds>` | Refresh interval in seconds, 1 through 60 (default `2`).      |
| `--limit <n>`         | Maximum active rows to display, 1 through 200 (default `50`). |

## Run commands and connect

### `sail box exec`

Run a command in a Sailbox, streaming its output.

```bash theme={null}
sail box exec [options] <id> -- <command> [args...]
```

| Option              | Description                                                                                                                                                                        |
| ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--cwd <dir>`       | Working directory inside the guest.                                                                                                                                                |
| `--timeout <dur>`   | Kill the command after this long (e.g. `30s`, `5m`).                                                                                                                               |
| `-e`, `--env <K=V>` | Environment variable for the command (repeatable).                                                                                                                                 |
| `--user <spec>`     | Run as this user: a name or numeric uid, optionally with a group after a colon (`alice`, `1000`, `alice:staff`). Default: the image's `USER`, else root; pass `0:0` to force root. |
| `-i`, `--stdin`     | Pipe local stdin to the guest command.                                                                                                                                             |
| `-t`, `--tty`       | Run under a pseudo-terminal driven by your terminal.                                                                                                                               |
| `--no-forward`      | With `--tty`, turn off all local forwarding (browser, ports, paste/clipboard).                                                                                                     |
| `--background`      | Start the command and leave it running in the Sailbox, returning once the Sailbox has accepted it. Output is not captured.                                                         |

### `sail box run`

Create an ephemeral Sailbox, run a command, then terminate it. A shortcut for
`create` + `exec` + `terminate`; for workflows that reuse a Sailbox, use those
directly.

```bash theme={null}
sail box run --app <name> [options] -- <command> [args...]
```

Takes the same `create` flags (`--arch`, sizing, `--port`) plus `--name`
(default `run-<hex>`), `--cwd`, `--timeout`, `--env`, `--user`,
`--auto-sleep` (as on create; meaningful with `--keep`), `--no-network` and
`--allow-host` (as on create), and `--keep` (leave the Sailbox running instead
of terminating it). An exposed port is reachable while the command runs and
stays reachable afterwards only with `--keep`.

### `sail box shell`

```bash theme={null}
sail box shell <id> [--shell <path>] [--user <spec>] [--env <K=V>]... [--no-forward]
```

Open an interactive shell inside a running Sailbox. This is the simplest and
preferred way in: it runs a PTY over `exec`, so it opens no port and does not
count against your org's raw-TCP endpoint limit. (Not to be confused with `sail shell`,
the local REPL for managing boxes.)

The session runs as the image's `USER`, or as root when the image sets none:
the same identity `sail box exec` uses. `--user` opens it as someone else (a
name or numeric uid, optionally with a group after a colon, like `alice`,
`1000`, or `alice:staff`); `--user 0:0` forces root. `--env K=V` (or `-e`,
repeatable) adds environment variables to the session, as on `sail box exec`.

While the shell is open, the session forwards to your machine:

* **Browser opens.** When a program in the box opens a browser, the page opens
  in your local browser instead. This covers logins like `claude login`,
  `codex login`, and `gh auth login`. A login that redirects to a `localhost`
  callback completes end to end.
* **Localhost servers.** A server the box starts on `localhost` (say a dev
  server on port 3000) becomes reachable at `http://localhost:3000` on your
  machine. The same port is used on your machine, so if it is already in use
  locally that server is not forwarded.
* **Paste and drag-and-drop.** Files dragged onto the terminal upload to
  `/tmp/sail-drops` in the box and paste as their guest paths. Press Ctrl+V to
  forward your clipboard. On devbox images an image or text lands on the box's
  clipboard, so pasting a screenshot into `claude` or `codex` works as it does
  locally, and text copied inside the box is copied back to yours. On other
  images a Ctrl+V image uploads as a file and pastes its path, while text uses
  your terminal's own paste. Large uploads show a progress line; press Esc to
  cancel one.

Pass `--no-forward` to turn all of it off, for example for an untrusted or
automated session. `sail box exec --tty` forwards the same way and takes the
same flag.

### `sail box cp`

```bash theme={null}
sail box cp <src> <dst> [--recursive] [--user <spec>]
```

Copy a file or directory to or from a Sailbox; `<id>:<path>` denotes the
remote side. Uploaded files belong to the image's `USER`, or to root when the
image sets none: the same identity `sail box exec` runs commands as. `--user`
names a different owner for the file and any directories the upload creates (a
name or numeric uid, optionally with a group after a colon, like `alice`,
`1000`, or `alice:staff`); `--user 0:0` forces root. `--user` applies to
uploads only; downloaded files are owned by whoever runs the CLI.

Pass `--recursive` (`-r`) to copy a directory: the source directory's
contents land inside the destination directory, which is created if needed.
Copying a directory requires the flag. With `--recursive`, `--user` owns the
copied entries, the destination directory, and any missing parents the copy
creates.

## Networking

```bash theme={null}
sail box expose <id> <guest-port> [--tcp] [--allowlist <addr|app>]...  # expose a guest port at runtime
sail box unexpose <id> <guest-port>                                    # remove a runtime ingress port
sail box listeners <id>                                                # list a Sailbox's ingress listeners
sail box address <id> <guest-port>                                     # print the external address for one port
```

`--tcp` exposes raw TCP instead of HTTP. `--allowlist` restricts sources to an
address or a range (e.g. `203.0.113.0/24`), or, for HTTP listeners, a Sail app
name. Re-exposing a port replaces its whole list; omitting `--allowlist`
reopens the port. See [Access Control](/sailboxes-access-control) for the full model.

## Secrets and HTTP policies

Store a secret for your organization, create an HTTP policy that uses it, then
attach that policy to a Sailbox. See [Credential injection](/sailboxes-credentials)
for a complete example and [HTTP policies](/sailboxes-credentials#policies) for the
policy document format.

```bash theme={null}
sail secret set <name> [--from-env <variable>]  # prompt for a value, read an environment variable, or read piped input
sail secret show <name>                         # show the name and timestamps, never the value
sail secret list                                # list secret names and timestamps
sail secret delete <name>

sail http-policy create <name> --file <path>    # use --file - to read JSON from standard input
sail http-policy show <policy-id>
sail http-policy list [--search <text>] [--limit <n>] [--offset <n>]
sail http-policy rename <policy-id> <name>
sail http-policy delete <policy-id>

sail box http-policy show <sailbox-id>
sail box http-policy set <sailbox-id> <policy-id>
sail box http-policy clear <sailbox-id>
```

A Sailbox holds at most one policy; `set` replaces any policy already
attached.

## Custom domains

`sail box domain` serves a Sailbox HTTP listener on a hostname you own, with
TLS certificates obtained and renewed for you.

```bash theme={null}
sail box domain target                             # print the custom-domain and wildcard certificate targets
sail box domain attach <id> <domain> --port <guest-port>  # attach a domain to an exposed HTTP listener
sail box domain list <id>                          # list the domains attached to a Sailbox
sail box domain detach <id> <domain>               # stop routing a domain to the Sailbox
```

`attach` requires `--port` naming an exposed HTTP listener, and checks that
your DNS record points at your target first. See
[Custom domains](/sailboxes-custom-domains) for the DNS setup, apex-domain
options, and certificate behavior.

## SSH

`sail box ssh` sets up SSH access so you can reach a box as `ssh <name>.sail`.

For a quick interactive shell, prefer [`sail box shell`](#sail-box-shell): it
needs no open port. Reach for SSH when you need a real SSH endpoint rather than a
PTY over `exec`, such as `scp`/`rsync`, an editor's remote mode, or a devbox you
work in day to day. Enabling it exposes port 22 as a TCP ingress port, which
counts against your org's raw-TCP endpoint limit.

```bash theme={null}
sail box ssh enable <id> [--identity-file <path>] [--allowlist <addr>]... [--no-wait] [--timeout <dur>]
sail box ssh alias <id>... [--identity-file <path>]
sail box ssh disable <id>
```

* **enable**: turn on SSH for a box (expose port 22, install your org's CA, start
  sshd), certify your key on this machine, and add the `<name>.sail` shortcut.
  `--allowlist <addr>` restricts the sources allowed to reach port 22 to an
  address or a range (repeatable). Passing `--allowlist` replaces the port's
  current restriction. Omitting it on a first enable leaves port 22 open to
  any source; on a re-enable it keeps the existing restriction.
* **alias**: add `ssh <name>.sail` shortcuts for boxes already SSH-enabled
  elsewhere (e.g. from the SDK), without waking them.
* **disable**: stop SSH on a box and drop its local shortcut.

Only the public half of your key is certified; the private key is referenced in
your SSH config, never read.

## Configuration

Manage `~/.sail/config.toml`.

```bash theme={null}
sail config get [key]          # print one value, or the whole file
sail config set <key=value>... # set one or more entries
sail config unset <key>...     # remove one or more keys
sail config reset              # reset user-settable settings (run 'sail auth logout' to remove the stored key)
```
