Watch
0
0
Fork
You've already forked hyperhive
0

document the user namespace opt-in

This commit is contained in:
atlas 2026-11-01 13:53:41 +01:00 • committed by mara
commit da098b1a50

View file

@ -456,6 +456,43 @@ journal link to the host takes part; nspawn skips `--link-journal=try-guest`
in ephemeral mode without failing. The journal vanishes at stop, and with it
the lines written after the last push.
### User namespace (opt-in, per agent)
An agent named in `services.hyperhive.userns.agents` runs in its own user
namespace. Every other agent keeps the host's uids. The operator sets the list
in the host config; hive-priv reads it from its unit's environment, so an agent
can't switch it on or off.
- **On disk the data belongs to one host uid:gid**, `services.hyperhive.userns.dataOwner`
(default `60000:60000`). Inside the container that owner shows as the agent
user. hive-priv mounts the agent's `state/`, `harness/`, `work/` and
`claude/` dirs and its socket dir with `owneridmap`, and every other bind too
(config, `/knowledge`, the runtime dir), whose owner shows as root inside.
- **The container starts with `--private-users=pick --private-users-ownership=map`.**
nspawn idmaps the root at mount time, so a different range for `pick` never
walks or chowns it.
- **The move happens once.** The first `WriteNspawnFlags` that finds a listed
agent's container stopped chowns those four dirs to `dataOwner` (ownership
only; it removes or copies nothing), writes
`/var/lib/hive-priv/userns/<name>`, and creates the mount points in the root
template owned by the agent user. A later request with the marker present
chowns nothing. A running container waits for its next stop. The socket dir
is on a tmpfs, so `EnsureAgentSocketDir` hands it to `dataOwner` at every
start.
- **The agent's gid must equal its uid.** `owneridmap` maps the gid of a bind
with the uid map, so a group other than the uid's has no mapping and writes
fail. Pin `services.hyperhive.agent.user.uid` and `.gid` to one number in the
agent's config before listing it.
- **Leaving the list is manual.** hive-priv refuses to start an agent whose
marker exists but who is no longer on the list, and one whose `dataOwner`
changed. Chown the four dirs back, then delete the marker.
The pause marker needs nothing extra: hive-priv gives it the owner of the
`harness/` dir. hive-c0re still creates agent dirs and new subvolumes as
`hive-core`, and only the first namespaced start chowns them. A dir created
after the move, such as a recreated subvolume, stays `hive-core`'s and the
agent can't write to it.
### Cross-agent access to state
An agent holding the `manage_root_agent` permission gets every other