Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3e5ddbd2c0 | ||
|
|
ef2b3a735c | ||
|
|
b3b1c7b288 | ||
|
|
ef4dd67e9a |
1 changed files with 53 additions and 22 deletions
|
|
@ -29,27 +29,30 @@ let
|
||||||
directory = *
|
directory = *
|
||||||
'';
|
'';
|
||||||
|
|
||||||
# The `hive-c0re serve` config, written to the store as JSON and passed
|
# The `hive-c0re serve` config JSON. Keys are snake_case to match the
|
||||||
# via a single `--config` flag so the systemd ExecStart line stays short
|
# `ServeConfig` serde shape the daemon deserialises (the
|
||||||
# instead of carrying every host-level setting as its own flag (the
|
# container-injected HiveEnv fields, flattened, plus the hive-c0re-local
|
||||||
# context-window + model-price maps alone were escaped JSON blobs on the
|
# model_prices table); per-flag overrides still work for ad-hoc
|
||||||
# command line). Keys are snake_case to match the `ServeConfig` serde
|
# invocations.
|
||||||
# shape the daemon deserialises (the container-injected HiveEnv fields,
|
#
|
||||||
# flattened, plus the hive-c0re-local model_prices table); per-flag
|
# Written to `/etc/hyperhive/serve.json` (managed by
|
||||||
# overrides still work for ad-hoc invocations.
|
# `environment.etc`) rather than embedded as a store-path argument in
|
||||||
serveConfig = pkgs.writeText "hive-c0re-serve.json" (
|
# ExecStart. This keeps ExecStart byte-stable across deploys that only
|
||||||
builtins.toJSON {
|
# change hyperhive module files (gateway, frontend, unrelated nix
|
||||||
hyperhive_flake = cfg.hyperhiveFlake;
|
# modules) so systemd does NOT restart hive-c0re — and therefore does
|
||||||
hyperhive_docs_flake = cfg.hyperhiveDocs;
|
# NOT trigger a startup sweep that rebuilds every agent — unless the
|
||||||
nixpkgs_flake = cfg.nixpkgsFlake;
|
# c0re binary itself changes.
|
||||||
dashboard_port = cfg.dashboardPort;
|
serveConfigJson = builtins.toJSON {
|
||||||
operator_pronouns = cfg.operatorPronouns;
|
hyperhive_flake = cfg.hyperhiveFlake;
|
||||||
context_window_tokens = cfg.contextWindowTokens;
|
hyperhive_docs_flake = cfg.hyperhiveDocs;
|
||||||
agent_cpu_quota = cfg.agentCpuQuota;
|
nixpkgs_flake = cfg.nixpkgsFlake;
|
||||||
agent_memory_max = cfg.agentMemoryMax;
|
dashboard_port = cfg.dashboardPort;
|
||||||
model_prices = cfg.modelPrices;
|
operator_pronouns = cfg.operatorPronouns;
|
||||||
}
|
context_window_tokens = cfg.contextWindowTokens;
|
||||||
);
|
agent_cpu_quota = cfg.agentCpuQuota;
|
||||||
|
agent_memory_max = cfg.agentMemoryMax;
|
||||||
|
model_prices = cfg.modelPrices;
|
||||||
|
};
|
||||||
|
|
||||||
# Stylix theme integration (zero-op auto-detect). When the operator's
|
# Stylix theme integration (zero-op auto-detect). When the operator's
|
||||||
# host config has stylix enabled, generate a base16 `colors.css` from
|
# host config has stylix enabled, generate a base16 `colors.css` from
|
||||||
|
|
@ -776,6 +779,11 @@ in
|
||||||
pkgs.git
|
pkgs.git
|
||||||
];
|
];
|
||||||
|
|
||||||
|
# Serve config at a stable /etc path so hive-c0re's ExecStart
|
||||||
|
# doesn't embed a volatile store-path argument. See serveConfigJson
|
||||||
|
# above for the rationale.
|
||||||
|
environment.etc."hyperhive/serve.json".text = serveConfigJson;
|
||||||
|
|
||||||
# Pull the per-container toplevels into the host system closure.
|
# Pull the per-container toplevels into the host system closure.
|
||||||
# `system.extraDependencies` adds paths to the system build
|
# `system.extraDependencies` adds paths to the system build
|
||||||
# without referencing them at runtime — nixos-rebuild fetches /
|
# without referencing them at runtime — nixos-rebuild fetches /
|
||||||
|
|
@ -1049,7 +1057,7 @@ in
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
ExecStart = "${cfg.package}/bin/hive-c0re --socket /run/hyperhive/host.sock serve --config ${serveConfig}";
|
ExecStart = "${cfg.package}/bin/hive-c0re --socket /run/hyperhive/host.sock serve --config /etc/hyperhive/serve.json";
|
||||||
SyslogIdentifier = "hive-c0re";
|
SyslogIdentifier = "hive-c0re";
|
||||||
# Migrate hive-c0re's *own* state to the service user after an
|
# Migrate hive-c0re's *own* state to the service user after an
|
||||||
# upgrade from a root-run install (systemd's StateDirectory only
|
# upgrade from a root-run install (systemd's StateDirectory only
|
||||||
|
|
@ -1086,6 +1094,29 @@ in
|
||||||
RuntimeDirectoryPreserve = "yes";
|
RuntimeDirectoryPreserve = "yes";
|
||||||
StateDirectory = "hyperhive";
|
StateDirectory = "hyperhive";
|
||||||
StateDirectoryMode = "0750";
|
StateDirectoryMode = "0750";
|
||||||
|
# Sandboxing. hive-c0re is unprivileged (runs as hive-core, never
|
||||||
|
# setuid), makes HTTP requests to forge/matrix/Anthropic (keeps INET),
|
||||||
|
# and delegates all privileged ops to hive-priv via a Unix socket.
|
||||||
|
# These directives deny the subset of kernel capabilities it
|
||||||
|
# provably doesn't need without restricting its network or
|
||||||
|
# filesystem access (RestrictAddressFamilies deferred — needs a
|
||||||
|
# watched deploy to verify no AF_UNIX/AF_INET gaps in socket paths).
|
||||||
|
NoNewPrivileges = true; # already runs as unprivileged user
|
||||||
|
PrivateTmp = true; # uses StateDirectory for tmpfiles, not /tmp
|
||||||
|
ProtectHome = true; # HOME = /var/lib/hyperhive; no /home/* access needed
|
||||||
|
# "full" makes /usr, /etc, /boot read-only. Safe: c0re never
|
||||||
|
# writes to any of those paths directly — all /etc writes (e.g.
|
||||||
|
# /etc/nixos-containers) go through hive-priv, and reads from
|
||||||
|
# /etc/hyperhive/serve.json are read-only. "strict" (everything
|
||||||
|
# read-only) requires carefully auditing ReadWritePaths for every
|
||||||
|
# nix store path c0re touches and is deferred to a follow-up.
|
||||||
|
ProtectSystem = "full";
|
||||||
|
ProtectKernelTunables = true; # no sysctl writes
|
||||||
|
ProtectKernelLogs = true; # reads logs via systemd-journal group, not /dev/kmsg
|
||||||
|
ProtectControlGroups = true; # cgroup writes go through hive-priv, not c0re directly
|
||||||
|
RestrictNamespaces = true; # namespace creation goes through hive-priv
|
||||||
|
LockPersonality = true; # no personality changes needed
|
||||||
|
RestrictRealtime = true; # no real-time scheduling
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue