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:
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 shows | meaning |
|---|---|
netns with netns-redirect = yes | Linux: the network wall can be raised. Runs are carried |
netns with netns-redirect = no | the 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 = unmeasured | the 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-uid | recognised 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
usernsto thesaphan-agentbinary 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:
- 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 asfar-darwin-door-unavailablewith a message that says which of the two problems it found. - The Mac has been probed. Its record must show
seatbelt-network-denywithseatbeltconfinement.
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:
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.