Saphan StudioDocs
Deployment

What the installer does

What the one line fetches, what it verifies before anything lands, and the admission request it makes for this machine.

One line installs a machine:

curl -fsSL https://saphan.ai/install.sh | sh

It detects the machine's OS and architecture, downloads the machine payload — {saphan,saphan-agent,saphan-gateway,saphan-server} — verifies each binary against the checksum manifest (refusing if anything doesn't match, with nothing installed), and installs them into ~/.saphan/bin/ (/opt/saphan/bin/ when run as root). The copy is a same-directory temp file and a rename, never an in-place overwrite — which on macOS can poison the per-inode code-signature cache and kill the next run.

The admission request it makes

Once the binaries are in place, the installer makes this machine's certificate signing request — the first act of admitting it to a fleet — without asking, the first time, when no device key exists on the machine yet:

<prefix>/saphan machine csr --machine <id> --csr-out ~/.saphan/machine/<id>.csr

It always runs saphan by its absolute install path, never a bare name off your PATH. The id is this host's short hostname; override it with --machine <id>. Carry the .csr file to the owner's machine and admit it there:

saphan machine admit --machine <id> --csr <file> --transport local|ssh

The engine guesses no default transport; name the one this machine actually uses (ssh also needs --ssh-host). See saphan machine admit.

  • With no controlling terminal — a provisioning run, CI — nothing is generated and the same machine csr command is printed to run later. --csr generates it anyway; --no-csr never does.
  • If a device key already exists on the machine, no new request is made — that machine has already begun its admission — and the line to re-issue one deliberately is printed instead.
  • With --agent-only there is no saphan on the machine to make the request; the command is printed to run from a machine that has it.

The full admission flow — what the request is, what machine admit checks, and the refusals you can meet — is Machines: enrollment and authentication.

Variants

A non-default install directory (it moves the binaries only; configuration, keys and logs stay where the install mode puts them):

curl -fsSL https://saphan.ai/install.sh | sh -s -- --prefix /opt/saphan/bin

A machine that only runs agent workloads does not need the full saphan CLI:

curl -fsSL https://saphan.ai/install.sh | sh -s -- --agent-only

A version a release channel names:

curl -fsSL https://saphan.ai/install.sh | sh -s -- --channel stable

From a distribution tree of your own — a directory, a file:// URL or an internal http(s) mirror laid out as SHA256SUMS plus <os>-<arch>/<binary>:

curl -fsSL https://saphan.ai/install.sh | sh -s -- --from https://mirror.example.internal/saphan

⚠ Every variant needs -s --. Without it the shell takes the flag and the script never sees it.

From a running server. saphan server serves the same payload on its own /get route, and once bound it prints a ready curl … | sh line naming its own address — that is how a fleet installs its machines from a build it holds rather than from the public source.

Already installed, and moving to a newer release? That is the same delivery run again, but every step has to be safe against a machine that is running work right now — Updating a fleet is on its own page.

On this page