Skip to main content
There are two things to control: who can operate a Sailbox, and who can reach the services it exposes.

Choose who can operate the Sailbox

Every Sailbox has a visibility, fixed for its life:
  • Org (the default) lets anyone in your organization run commands, copy files, SSH in, and pause, sleep, checkpoint, or terminate it.
  • Private restricts all of that to you. Your organization can still see the Sailbox in listings, but cannot act on it. An org admin can override that for commands and lifecycle operations by giving a reason, which is recorded in the audit log. Creating one requires an API key created by your user, so that Sail can identify the creator. A service key, which belongs to the organization rather than to a member, cannot create or operate one.
Code running inside a Sailbox can read that Sailbox, sleep it, schedule its wake, and manage its cron jobs without an API key. See guest identity.

Make a web server public

A Sailbox does not accept inbound traffic until you expose a port. Exposing an HTTP port gives it a public HTTPS URL that anyone can reach, with TLS handled for you. Nothing inside the Sailbox needs to know about certificates or hostnames.
In the SDKs, expose and unexpose add and remove ports on a running Sailbox: sb.expose(8080) in Python, await sb.expose(8080) in TypeScript, sb.expose(8080, IngressProtocol::Http, &[]).await? in Rust. Add or remove ports on a running Sailbox with sail box expose <id> <port> and sail box unexpose <id> <port>. sail box listeners <id> shows what is exposed. HTTP and WebSocket traffic both work, and a sleeping Sailbox wakes when a request arrives. To serve on your own hostname, see Custom Domains.

Restrict who can reach it

Pass an allowlist when you expose a port. An entry is an address or range, or the name of a Sail app, which admits authenticated requests from Sailboxes in that app. Anything else fails before it reaches the Sailbox.
Pass the same allowlist on the port when you create the Sailbox: ingress_ports=[sail.IngressPort(8080, allowlist=[...])] in Python, ingressPorts: [{ guestPort: 8080, protocol: "http", allowlist: [...] }] in TypeScript, and the allowlist field of IngressPort in Rust. Re-exposing a port replaces its whole allowlist, so you can use the same command to tighten or relax access. An app name does not have to exist yet, and names from other organizations never match. An app-name allowlist matches on the identity of the calling Sailbox. When one Sailbox calls another Sailbox’s listener, Sail adds the calling Sailbox’s identity to the request, so a request from an allowlisted Sailbox is accepted.

Raw TCP ports

Expose a port as raw TCP for protocols other than HTTP, such as Postgres or a custom server. You get a public host and port.
A raw TCP port has no platform-side authentication. Whatever is listening inside the Sailbox is the only access control, so make sure it requires credentials.
Raw TCP connections have no app identity, so a TCP allowlist can contain only addresses and ranges. Exposing a well-known unauthenticated port such as Postgres, MySQL, or Redis without an allowlist is rejected. Pass --allowlist 0.0.0.0/0 --allowlist ::/0 to confirm you want it open to everyone.

Connect with a shell

The quickest way into a Sailbox is sail box shell. It opens an interactive terminal over the same channel the CLI uses to run commands.
While the shell is open, servers the Sailbox runs on localhost and links it opens are forwarded to your machine, so you can develop against it without exposing anything. Pass --no-forward to turn that off.

SSH access

Use SSH when you need a real SSH endpoint rather than a terminal: scp and rsync, an editor’s remote mode, or port forwarding you control. Enabling it exposes port 22, which counts against your organization’s raw TCP limit. SSH is organization-scoped. Enabling it exposes port 22, and the Sailbox trusts your organization’s certificate authority, so anyone in the org can connect with a short-lived certificate for their own key. There are no per-Sailbox keys to hand out. A private Sailbox is the exception: its SSH server accepts only its creator’s certificates.
The SDK call enables SSH on the Sailbox. To connect from a machine, run sail box ssh alias <id> there once. The CLI’s enable does that for you.