| Filename | Latest commit message | Latest commit date |
|---|---|---|
`nixos-container stop` exiting 0 does not mean machined has dropped the registration. A process sitting in the machine cgroup without being a child of the container's init never receives the shutdown's SIGTERM if it has been SIGSTOP'd, so the registration outlives the "successful" stop. Every later start then fails with "Failed to register machine: already exists", and machined re-persists the stale record across its own restart, so there is no cleaning it up afterwards. StopContainer now asks for the stop, waits for machined to release the name, escalates to SIGKILL if it hasn't, re-verifies, and fails loudly if the name is still held — so a caller is never told the stop worked and then walks into the confusing registration error. The probe resolves the name through machined's GetMachine, the same lookup that later rejects the registration, rather than checking the container's systemd unit: the unit going inactive while the name is still held is precisely the case being caught. Verify-and-escalate lives in the helper, not at a call site, so every stop gets it — dashboard, reconcile, destroy, cold-start fallback. The start path already distrusts its own exit code the same way; this is the missing half of that pair. |
||
| .. | ||
| src | ||
| Cargo.toml | ||
| README.md | ||
hive-priv
The minimal root privileged-helper for hive-c0re. It runs as root and
exposes a narrow unix socket at /run/hive/priv.sock that accepts PrivRequest
JSON lines and performs only the handful of operations that genuinely require
root — bind-mount edits, nsenter into a container, btrfs subvolume ops. All
coordination logic (broker, HTTP, scheduling) stays in the unprivileged
hive-c0re process, which delegates here.
Why it exists
Privsep. hive-c0re runs as the unprivileged hive-core user so a bug or a
prompt-injection in the large daemon can't directly wield root. The few root
operations it needs are funnelled through this small, auditable helper instead.
See docs/boundary.md and docs/security.md for the privilege boundary.
Security model
- Strict allowlist. Every request is validated against a container-name
allowlist before any filesystem or process operation — only names matching the
hive convention (
h-*, the manager container, known sibling service containers) are accepted. - No pass-through. Every
PrivRequestvariant maps to a single known operation; there is no arbitrary-command escape hatch. - Socket-activated, always. systemd binds
/run/hive/priv.sock(SocketGroup=hive-core,0660) and passes the listener as fd 3 (LISTEN_FDS); the helper requires this and has no self-bind fallback, so dev and prod take the identical path and the group grant always holds.
The wire contract (PrivRequest / response types) lives in the separate
hive-priv-sock crate so this root binary depends on just the protocol shapes,
not the whole daemon-shared crate.