Saphan StudioDocs
Security/Egress control

Preparing a machine

How a machine comes to carry the wall: the probe, what its answers mean, and how to fix a host that cannot.

A machine carries the egress wall only when its record says it can, and only one command writes that record: the probe. It measures by doing — it performs the real act on the host and records what happened. It never installs anything and never accepts a typed value.

Probe the machine

Run the probe from a shell that is not itself confined, then read the result:

saphan machine probe-confinement <machine> --probed-by <actor> --workspace <root>
saphan machine list --workspace <root>

For a remote machine the probe runs over that machine's own ssh connection; for the local machine it runs in place. It records two things on the machine's signed record: its filesystem confinement and its egress rung.

the record showsmeaning
netns with netns-redirect = yesLinux: the network wall can be raised. Runs are carried
netns with netns-redirect = nothe kernel let the probe create a namespace but refused to make it routable. Remote and container runs are refused; a local run starts and its wall fails before the agent starts, printing the remedy — see below
netns with netns-redirect = unmeasuredthe probe could not run the test, usually because a tool is missing. Remote and container runs are refused — see below
seatbelt-network-deny (with seatbelt confinement)macOS: the CONNECT door can be used. Runs are carried
(unprobed) or <none recorded>nobody has measured this machine. Runs are refused
cgroup-v2, separate-uidrecognised levers this release cannot raise. Runs are refused by name

Probe again after any change to the host. Fixing a host is not enough on its own: only the probe updates the record.

Linux: netns-redirect = no

On Ubuntu 24.04 and related distributions, AppArmor lets an unprivileged process create a user namespace and then denies it the capabilities it needs inside. The sysctl kernel.apparmor_restrict_unprivileged_userns=1 is the usual cause. Two remedies:

  • Admit only the agent binary. Install an AppArmor profile that grants userns to the saphan-agent binary alone. The run's refusal prints the exact profile and the commands to install it. Nothing else on the host is affected.
  • Lift the restriction host-wide: set the sysctl to 0. This affects every process on the host; weigh it as a host-wide security trade.

Then probe again.

Linux: netns-redirect = unmeasured

The host lacks a tool the probe needs. Install iptables, iproute2 (the ip command) and util-linux (the unshare command), then probe again.

A remote Mac

A Mac reached over ssh is carried by the CONNECT door, which is started on that Mac before the agent's sandbox. Two conditions:

  1. The Mac runs the current saphan. Install the same build your dispatching machine runs; an older build cannot publish the door's address, and the run is refused as far-darwin-door-unavailable with a message that says which of the two problems it found.
  2. The Mac has been probed. Its record must show seatbelt-network-deny with seatbelt confinement.

The door is stopped when the run ends, and in any case at its maximum lifetime.

⚠ On any remote machine the door's socket lives under the remote home directory, so a long home path can exceed the 103-byte socket-path limit; the run is then refused as confinement-unavailable and the message says how many bytes the home path may have.

Containers

A local container run is carried by the container bridge when the host's record shows netns-redirect = yes and the installation runs the agent harness:

saphan config set run.harness saphan-agent

run.harness is one switch for the whole installation. Set it back to legacy to return.

⚠ A container run on a remote machine is refused in this release, and so is a container run under the legacy harness.

Remote Linux

A Linux machine reached over ssh is carried by the network wall when its record shows netns and netns-redirect = yes, its confinement is landlock, and it runs the same saphan and saphan-agent build as the dispatching machine. An older build is refused as legacy-far-wall-unavailable, or under the agent harness as harness-far-door-lacks-policy-file.

On this page