| Filename | Latest commit message | Latest commit date |
|---|---|---|
Upstream's ExecStartPre re-registers only when .runner is absent, the labels changed, or the registration token hash changed -- never when the instance URL changed. So writing a fresh token and restarting the runner registers only if the hash happens to differ, which is Forgejo's choice to make: whether the admin registration-token endpoint mints a new token per request or hands back a stable one is not ours to depend on. hive-c0re already decides correctly -- ensure_ci_runner_registered only reaches this helper once it has concluded the credentials are absent or stale -- but the remediation was a no-op, so re-registration was requested every boot and never happened. Remove .runner before the restart so upstream takes its absence branch, the one it evaluates unconditionally. NotFound is success; any other error propagates rather than reporting Ok for a registration that never ran. |
||
| .. | ||
| 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.