P1 of the storage backend: hives push agent snapshots over the WireGuard mesh that swarm.nix already brings up. No controller dependency — a btrfs subvolume tree, a socket-activated receiver, and the existing mesh. The mesh is the authentication. Cryptokey routing already binds a peer's source address to its public key (allowedIPs = [ peer.wireguardAddress ]), so the store adds no key material and no certs; anything else would authenticate the same fact twice. Destination is keyed per AGENT, not per hive: after a migration the same agent's next incremental send arrives from a different hive, and a per-hive prefix would split its snapshot chain and break the incremental parent lookup — the exact case this store exists to serve. The sender unavoidably contributes the agent name (a btrfs stream carries no such notion, and the subvolume name inside it is the sender's). So the receiver owns the destination root and VALIDATES the sender-supplied leaf against a whitelist charset — no slash, no dot, so neither traversal nor an absolute path can survive it. ListenStream binds this host's mesh address, never a wildcard, and that is asserted rather than commented: bound to 0.0.0.0 the socket would be an unauthenticated remote write into agent state. swarm.nix: the mesh config moves off the c0re.enable gate onto swarm.wireguard.enable. The mesh is host networking, not a c0re feature — a swarm host that runs no hive (this store) previously got no wg-hive interface at all. Nothing in that block was c0re-specific; the peer data c0re consumes is rendered in hive-c0re and stays gated there. Confinement is deliberately not in the module: it is a property of the deployment (a dedicated VM, or a container in the all-local case). The systemd hardening is defence in depth only — btrfs receive needs CAP_SYS_ADMIN, which can mount() its way out of the namespace those directives set up. The `dedicated` option turns "this host runs nothing else" into an assertion the build checks instead of an assumption the deployer remembers.
27 lines
935 B
Nix
27 lines
935 B
Nix
# The full hyperhive host stack, pulled together in one place — this
|
|
# is what the flake exports as `nixosModules.default` (wrapped with
|
|
# the package/source wiring; see flake.nix). One import covers
|
|
# everything; `services.hyperhive.enable = true` turns the stack on.
|
|
#
|
|
# The forge is mandatory — hive-c0re mirrors every agent's applied
|
|
# config repo into it and it's the canonical store for the meta flake
|
|
# + `internal/*` repos, so there's no enable toggle; it deploys with
|
|
# hyperhive itself. hive-matrix is opt-in (off by default). All
|
|
# subsystems rely on `services.hyperhive.domain`, which is required
|
|
# (asserted in hive-network.nix) whenever hyperhive is enabled.
|
|
{
|
|
imports = [
|
|
./hyperhive.nix
|
|
./hive-c0re
|
|
./hive-ci.nix
|
|
./hive-forge
|
|
./hive-gateway
|
|
./hive-matrix.nix
|
|
./hive-network.nix
|
|
./hive-priv.nix
|
|
./hive-snapshot-store.nix
|
|
./hive-tls.nix
|
|
./otel.nix
|
|
./swarm.nix
|
|
];
|
|
}
|