Saphan StudioDocs
Deployment

Air-gapped installation (Enterprise)

A signed package, installed system-wide on a host with no network path to anything — what it puts on the machine, and what still needs your hand afterwards.

Air-gapped Enterprise deployments get installation packages. Everywhere else a machine is installed with one line from the internet (an install, end to end); a machine with no route to the internet is installed from a package instead.

You receive one file — a .deb or an .rpm — carry it in by whatever means your estate allows, and install it with the tool your distribution already trusts. Nothing in this route reaches the network at any point. It also installs system-wide, into /usr/bin, where the one-line install puts the payload under a single operator's home.

you receivesaphan_<version>_<arch>.deb or saphan-<version>-1.<arch>.rpm
it installsthe machine payload, system-wide, into /usr/bin
it needsdpkg or rpm, and root. No network, no toolchain, no checkout
supported architecturesamd64 / arm64 (the rpm names them x86_64 / aarch64 — you never spell those yourself)

What a package contains — and what it deliberately does not

/usr/bin/saphan
/usr/bin/saphan-agent
/usr/bin/saphan-gateway

That is the whole payload of a deb or an rpm: three binaries, mode 0755, and nothing else — no configuration files, no maintainer scripts, no service unit, and nothing that reads or writes a user's home.

That is a deliberate boundary rather than an unfinished package. Per-seat identity and configuration are minted by verbs, per user; a package that reached into a user's home would break that, and a package that installed and enabled a service would start something on your host without asking. ⇒ Installing is one act and running is another, and the second one is yours.

Supervision is a verb, not a package artifact. Whether a machine runs Saphan under an init system is decided after the install, by an explicit act, so the package stays the same file on a host that supervises and on a host that does not. The daemon paths a supervised process uses come from the --system flag at run time (Per-user vs system-wide state), never from anything the package put there.

The paths, and how they compare to a network install

Measured against the installer's own source rather than described:

routewhere the three binaries land
this package/usr/bin/saphan · /usr/bin/saphan-agent · /usr/bin/saphan-gateway
the network bootstrap$HOME/.saphan/bin/per user, and --prefix overrides it
the macOS installer/usr/local/bin/

The binary NAMES are identical on every route; the prefix is not, and that is by design — the bootstrap installs for one user and a package installs for the machine. If you need a network install to land exactly where this package does, name the prefix:

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

Two things follow from doing that, and both bite quietly. It needs root, and the mode of the directory matters: if the install directory is group- or world-writable, saphan refuses to start and says why — the refusal names binary custody rather than a permission error. The bootstrap sets mode 0755 on the binary and on the install directory explicitly for that reason, and warns when it cannot.

And a package therefore installs no authorization server. saphan-oauth is not in the file list above, and no release artifact carries it at all — see Central servers. For an air-gapped site that is the sharpest consequence on this page: a host that must serve authorization cannot get that program by any route this document can describe, so plan the identity path of an air-gapped deployment around what Identity says the engine will accept, and settle it before the machines arrive.

Installing and upgrading on the target

sudo dpkg -i saphan_<version>_amd64.deb # or: sudo rpm -i saphan-<version>-1.x86_64.rpm
saphan version

Upgrading is the same command with the newer file — the binaries are replaced in place and the package version advances:

sudo dpkg -i saphan_<newer>_amd64.deb # or: sudo rpm -U …

Install first, then observe. A running process keeps the binary it started with; anything you measure before the new package is installed is measuring the old one.

What an air-gapped fleet still needs from you

The package gets the programs onto the machine. Three things it cannot bring, named here because an air-gapped plan that discovers them late is an expensive plan:

  1. A record store. Saphan keeps law and evidence in CouchDB, and the databases are created by hand — CouchDB: the one step that is left to your hand. That step needs no internet, only the database host.
  2. Somewhere for the agents' models to come from. An air-gapped fleet cannot dial a vendor's API, so its lanes point at model endpoints inside your own network. A lane is a section of configuration: an endpoint address and the name of the credential variable, never the credential itself (Configuration).
  3. The first-run wizard, reached locally. /setup is served on loopback and set up in a browser on the machine itself or over a forwarded port — no outside network is involved (First run).

Proven, and not yet proven

Honest state at the time of writing, so nobody reads more into it than was measured:

  • deb / linux-amd64 — built, contents and metadata inspected, dpkg -i installed, upgrade A→B verified swapping the binary, cleanly removable.
  • linux-arm64 — built and confirmed to be a real ARM aarch64 static binary. Not installed on an arm64 device: the fleet currently has no arm64 Linux host to install it on.
  • rpm — produced for both arches and its metadata and file list verified with rpm -qpi / rpm -qpl. Not installed on an rpm-family distribution, because the fleet has no such host.

On this page