Commit graph hyperhive/docs/boundary.md
Author SHA1 Message Date
iris
720e5340de docs(boundary): fix answer-question path and nonexistent AgentRequest type 2026-08-15 12:45:22 +02:00
iris
c6eda124b1 docs(boundary): drop changelog framing, dedupe ReloadGatewayNginx explainer 2026-08-15 12:45:22 +02:00
atlas
98d895cf9e docs(gateway): describe what is, not what changed
Per review: docs represent current state. Every "used to" / "no longer"
clause this branch introduced is gone — including the History section in
network.md, which was a whole subsection about a sync mechanism that
doesn't exist.

Where the removed clause was carrying a real constraint, the constraint
stays and is stated in the present tense instead of as a delta: nothing
narrows what the gateway's nginx can reach except the directory
permissions in front of a socket, and nothing bounds `ReloadGatewayNginx`
except the hard-coded unit name. Those read as rules now rather than as
the story of how they came to be rules.
2026-08-11 18:09:51 +02:00
atlas
07852cabc1 feat(3088): move the gateway's nginx + dnsmasq onto the host
The gateway's nginx + dnsmasq no longer run in their own nspawn container.
`nix/host-modules/hive-gateway/default.nix` loses the
`containers.hive-gateway` wrapper and everything that existed only to punch
holes in it: `privateNetwork = false`, `CAP_NET_ADMIN`, five bind mounts,
its own `stateVersion`, `networking.firewall.enable = false`,
`networking.resolvconf.enable = false`, and the `hive-gateway-resolv`
path+service pair. 465 -> 303 lines.

The container never bought isolation here. It shared the host netns by
necessity — nginx binds the host's :80/:443, dnsmasq answers on the bridge —
so each of those settings was undoing a boundary the gateway could not
afford in the first place.

Four things made it more than a deletion, none of them visible in the nix
diff:

- The self-signed cert service also imports the hive CA leaf, so removing it
  with the container would have left nginx naming a missing cert file, which
  it refuses to load at all.
- The nginx reload is a hive-priv verb. It still needs root, but no longer
  for the reason its doc gave, and `--machine=` was both transport and
  scope — so the unit name is now hard-coded in the helper as the
  containment.
- The lifecycle verb named a container that stops existing.
- `journalctl -M hive-gateway` had no machine to enter.

Per the operator's ruling, the operator verb keeps working and agents lose
it. `InfraContainer` answered three questions that used to share an answer;
it now splits into `name()` (identity), `target()` (Container vs HostUnit),
`service_unit()` (the systemd unit), and `agent_restartable()`, which the
MCP restart path checks before the capability so the refusal cannot read as
"ask for infra_admin". `SIBLING_CONTAINERS` drops the gateway — it gates the
requests that name a container as a string — while `FromStr` still accepts
it, because that answers what a name is, not who may act on it. The
dashboard's gateway journal reads host journald filtered to `nginx.service`.

Prose was corrected where it only named a location, and re-argued where the
container was doing security work: a `0666` per-agent socket was safe
because only the gateway container had the directory bind-mounted. There is
no mount now, so the directory permissions are the whole of the access
control — the constraint holds, its mechanism doesn't.

Gate: nix fmt / clippy --all-targets -D warnings / cargo test all clean (710
tests); hivectl-cli.md regenerated from the clap tree. The nix eval was run
in both TLS shapes at this commit: every delta in the rendered
virtualHosts is one of the three intended path moves, dnsmasq settings are
byte-identical, and the absence probe flips true -> false with bindMounts
emptied.
2026-08-11 18:01:03 +02:00
atlas
289db00321 docs: move the socket-dir ownership rule to boundary.md
It was written into gateway.md, which only owns half the story: that
doc describes the web.sock path, and before this branch it never
mentioned agent.sock at all. Putting a rule shared by hive-c0re, the
harness and nginx inside the gateway walkthrough means someone asking
"why can't c0re dial agent.sock" has no reason to look there.

boundary.md already covers who may touch what across the trust boundary
-- including the sibling case of hive-priv's socket getting its mode
from the unit rather than the process -- so the rule lives there now,
with the three principals as a table. gateway.md keeps a two-line note
about the one fact it needs (nginx traverses via o=--x) and links out.
2026-08-04 01:00:48 +02:00
atlas
30a2a2e9de feat(#2641): sudoless hivectl via a hive-admin group on the host socket
The host admin socket `/run/hyperhive/host.sock` was `0660 root:root` (no
SocketGroup), so hivectl needed sudo. Group-own it by a new `hive-admin`
group and add a `services.hyperhive.c0re.adminUsers` allowlist: listed users
join `hive-admin` and drive hivectl without root.

- `SocketGroup = "hive-admin"`, `SocketMode = "0660"` on the hive-c0re.socket
  unit.
- `/run/hyperhive` -> `0751` (traverse-only, no listing) so the group can reach
  the socket path; the socket's own `0660 hive-admin` mode gates the
  connection, and the per-agent subdirs keep their own restrictive perms.
- Empty `adminUsers` (the default) leaves `hive-admin` memberless -> root-only,
  as before.

The admin socket is full hive control (spawn/kill/destroy/deploy), so
`adminUsers` is an explicit, opt-in trust grant. Documented in
docs/boundary.md (host admin socket access) + docs/tools/hivectl.md.
2026-07-22 22:50:27 +02:00
sock
6c95933775 docs(security): ci netns, knowledge .git tmpfs, matrix id/secret split
Security fixes landed without updating the security-model docs; bring them
current as present-tense invariants:

- security.md: matrix identities are public / cross-agent-readable via
  GetAgentMeta while the token stays private; name validation extends to
  GetAgentMeta; the nix-build blast radius has a network dimension (hive-ci
  netns) alongside the 0600 token policy.
- boundary.md: the core dashboard /api has no app-layer auth — protection is
  the gateway plus network isolation; stated as a standing invariant.
- ci.md: hive-ci runs in its own private netns behind the bridge, reaches the
  forge via the gateway, and cannot reach host-loopback (dashboard/forge port).
- knowledge.md: /knowledge excludes .git via tmpfs so the core token in
  .git/config isn't readable by agents.

Refs #2308, #2310, #2313.
2026-07-10 19:17:17 +02:00
atlas
480b35aac4 docs(boundary): update to reflect always-on network isolation
All three area:ops pillars are now complete: network isolation is
always on (private netns, no shared-netns mode), the gateway is live,
and hive-c0re runs as the unprivileged hive-core user.

- Rewrite the intro to say the boundary is enforced, not aspirational
- Update 'Why network isolation is the load-bearing step' section to
  use past tense for the shared-netns world and note completion
- Mark network isolation as Complete in the sequencing list
2026-07-04 20:58:55 +02:00
atlas
8406a45275 feat(#1997): add prettier markdown formatter to treefmt
- .prettierrc: proseWrap=preserve (no prose reflow)
- .prettierignore: exclude hivectl-cli.md (auto-generated) + 11 docs
  with multi-line list-item continuations prettier would strip to col 0
  (CommonMark limitation in prettier's list handling)
- format 16 markdown files: cosmetic only (*→_, table alignment,
  heading normalisation) — verified no broken continuations, idempotent
2026-07-02 23:33:11 +02:00
damocles
fb1f7efbe4 docs: move privsep socket-activation + child-state rw rationale out of code comments 2026-06-08 21:58:12 +02:00
iris
a960dcf91a docs(boundary): rewrite sequencing list as prose, drop checklist markers 2026-06-05 18:40:44 +02:00
iris
28df69286d docs(security): document hive-priv privilege separation model 2026-06-05 18:40:44 +02:00
damocles
4715e88fff docs: move backlog to forge issue tracker, extract boundary doc 2026-05-20 12:19:16 +02:00