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 minted by you, so that Sail knows who the creator is. A service key,
which belongs to the organization rather than to a member, cannot create or
operate one.
Make a web server public
A Sailbox accepts no 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.
At create time, pass the same allowlist on the port:
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 the same command tightens
or relaxes access. An app name does not have to exist yet, and names from
other organizations never match.
For a Sailbox to pass an app-name allowlist, its request must carry the
identity headers the SDK provides. Inside the calling Sailbox:
From outside, such as a test driving several Sailboxes, fetch the headers for
a Sailbox you own with source_sb.ingress_auth_headers()
(sourceSb.ingressAuthHeaders() in TypeScript).
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 carry no app identity, so a TCP allowlist holds addresses
and ranges only. 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
Reach for 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.