Saphan StudioDocs
Deployment

First run: setting the machine up at /setup

A machine with no owner is set up in a browser at /setup, or from a terminal with saphan install: the window, the screens, and the key that is shown once.

Every route ends the same way: the machine payload on disk. A machine with no owner is set up in a browser, at /setup — there is no owner yet, so there is nobody who could sign in to a console. The one-line install brings that page up for you and prints its address; if it did not (no terminal, --no-serve, or a package install), bring it up yourself:

mkdir -p ~/saphan
saphan bridge init --workspace ~/saphan
saphan bus reconcile --workspace ~/saphan     # the record must exist — see below
saphan-gateway start --workspace ~/saphan --listen localhost:8788 --detach
# then open http://localhost:8788/setup

Use localhost, never 127.0.0.1: a passkey cannot be bound to an IP address, so a console opened at the address form reads but can never sign.

The terminal is the other door. saphan install --workspace <folder> runs the same set-up steps from a shell and reports each as already done, done now, or not done with the reason — see saphan install. It needs no Saphan account, which the browser page does (screen 2 below).

The window is narrow by construction, and it is narrow in a specific direction. /setup serves only while this workspace's record exists and no console principal has ever existed in it. So:

the machine has/setup answerswhy
a record, never an owner200 — the setup pagethe first run, which is this page
a record and an owner, now or ever before404not 403: a 403 would tell an unauthenticated caller that a setup surface exists here
no record at all404⛔ deleting the record must not re-open an unauthenticated configuration surface

That last row is why bus reconcile comes first. It is also the answer to the obvious attack: you cannot get the page back by removing a file.

Remote machines

The console listens on loopback unless you give it the certificate set for direct mutual TLS, so to set up a machine you are not sitting at, forward the port — the same port on both ends, because the passkey ceremony is bound to the exact origin:

ssh -N -L 8788:localhost:8788 <user>@<that machine>
# then open http://localhost:8788/setup

⚠ If that port is taken on your computer and you forward another one, declare it first on the machine, or every passkey act from it is refused: saphan config set act_authority.webauthn_origins http://localhost:8788,http://localhost:<other port>.

The screens

There are eight, in this order. ⚠ The pictures below are of an earlier build and differ in detail from this release's screens; the text is the reference.

1 — Edition. This release installs Solo. Team and Enterprise are shown and cannot be chosen yet.

2 — Your account. You are the owner, and the owner is your Saphan account.

The account screen

⚠ This screen needs your Saphan account. Sign in to Saphan opens the Saphan portal in the browser and brings you back; the email it returns is your login to the console, and the name derived from it authors the commits agents make as you and signs your decisions. Without a reachable portal this screen cannot continue — set the machine up with saphan install in a terminal instead. The password floor is the engine's own number, and there is no reset email: if you lose it, you reset it from a terminal on that machine.

3 — Your root of trust. One key signs for everything Saphan Studio will ever say is yours.

The root-of-trust screen

The key is shown once, as 24 words. Save them as a file, or copy them into a password manager — Continue unlocks only after one of the two succeeded. Continuing deletes this machine's copy of the key, and what you saved is then the only one; the machine keeps only the public half. Prefer the file: a clipboard can sync to your other devices.

If this machine already has a root, the screen says so and carries on from there. A second root is not a step in setup — it would be a different key, and everything the first one signed would stop verifying.

4 — Where your work lives. One folder holds the record, the state and the worktrees.

The workspace screen

Check folder is not decoration: nothing existing is ever overwritten, and if something is in the way the check names the exact file.

5 — CouchDB. Saphan Studio keeps its signed rules and evidence there.

The CouchDB screen

The screen walks four steps: the database administrator's login and password; saving them to the credentials file; starting CouchDB on this machine — saphan infra up couchdb for Docker or Podman, or CouchDB's own package for Homebrew, Debian/Ubuntu or RHEL-family hosts followed by saphan infra couchdb-admin; and Test connection. If you already run an empty CouchDB, fill in the first step and go straight to the test.

The address is reached from the machine Saphan Studio runs on, not from the computer you are reading the page on — so localhost here means that machine. Continue unlocks only when the test passes. ⚠ The test refuses a CouchDB that already holds this product's databases — another installation's store, or the remains of one: drop them on that node, or point this installation somewhere else.

What this screen writes. The address lands in your configuration as channel.base_url and evidence.base_url. The login and password land in the credentials file beside the configuration, mode 0600, and the configuration records only the file's path and the variable's name:

filewhat it holds
~/.saphan/etc/saphan.confchannel.base_url, evidence.base_url, credentials.file (the credentials file's path) and channel.credential / evidence.credential (the variable's name, SAPHAN_COUCHDB_CREDENTIALS)
~/.saphan/etc/credentials.json, mode 0600SAPHAN_COUCHDB_CREDENTIALS = <login>:<password>

⛔ The configuration never carries the password itself — only the variable's name and the file's path, so the config file can be read, copied and reviewed without leaking anything. A machine-wide install keeps both under /opt/saphan/etc/ instead (Per-user vs system-wide state). The environment still wins: if SAPHAN_COUCHDB_CREDENTIALS is exported in the process that needs it, that value is used and the file is not read.

6 — Ready. Nothing has been created yet; this screen is the whole plan before the button.

The plan screen

It lists what will happen — your account and signing key, the folder with its bridge and record, this machine's identity, your configuration, your CouchDB databases with their access rules (CouchDB: the databases Saphan Studio creates), and starting Saphan Studio when you log in (at boot, machine-wide) once this machine is admitted. Then the choices: accepting the Terms and conditions is required and is recorded with the date and the version you read; starting at login is on by default; and letting agents commit their own work in this folder — a narrow permission for git add, commit, status and diff — is yours to give, per folder and reversibly, and your answer is recorded either way.

7 — This device's passkey. In the browser, a passkey is the only thing that signs a decision as you. The screen gives you a one-use code to register one from the console. You may skip it: the console then reads but does not sign, every decision shows the terminal line to run instead, and the last steps of the install — the ones that write to this machine's signed records — wait for your passkey. Add one later with saphan console device enrol --web on that machine.

8 — Done. A summary of what ran — account, workspace, database, passkey, console, and how it starts — and the console. From here on the machine has an owner, so /setup is closed and the address to use is /console.

If the page refuses

Every refusal on these screens names what it measured. The ones worth knowing in advance:

  • A 404 at /setup means the window is shut — read the table above; the usual cause on a fresh machine is that bus reconcile has not run.
  • Set up refuses with account-not-signed-in. No valid sign-in to your Saphan account is stored on this machine; go back to the account screen and sign in.
  • The CouchDB test fails while curl works from your desk. Almost always the address is being resolved from the wrong machine; see screen 5.
  • The passkey prompt never appears. The page was opened at 127.0.0.1 or at a forwarded port that was not declared; see Remote machines.

On this page