Watch
0
0
Fork
You've already forked hyperhive
0

feat(#903): expose hyperhive.user.uid + gid options for optional UID pinning

This commit is contained in:
atlas 2026-06-03 17:20:08 +02:00 • committed by mara
commit 0d5f7e00b6

View file

@ -132,9 +132,42 @@ in
Constraints match `useradd`'s NAME_REGEX: lowercase / `_` start,
total length ≤ 31, no special characters. UID is auto-assigned
by NixOS; no `uid =` override surface (intentional — pinning
across rebuilds isn't a concern when the home and state dirs
stay bind-mounted from the host).
by NixOS unless `hyperhive.user.uid` is explicitly set.
'';
};
options.hyperhive.user.uid = lib.mkOption {
type = lib.types.nullOr lib.types.int;
default = null;
example = 1100;
description = ''
Optional fixed UID for the per-agent unix user. `null` (default)
lets NixOS auto-assign from the normal-user range (≥ 1000),
which is the right default for most deployments — the UID stays
stable across container rebuilds because each container only has
one normal user and the assignment is written into the container's
`/etc/passwd` at activation time.
Set an explicit value only when the host needs a predictable UID
for the agent's state files — e.g. if an operator script
references files by numeric UID, or to keep ownership stable
across full container destroy + recreate on a fresh host.
Values must be in `[1000, 60000)`. Using UIDs < 1000 clashes with
system accounts and is rejected by NixOS.
'';
};
options.hyperhive.user.gid = lib.mkOption {
type = lib.types.nullOr lib.types.int;
default = null;
example = 1100;
description = ''
Optional fixed GID for the per-agent unix group. `null` (default)
lets NixOS auto-assign. When `uid` is set, setting `gid` to the
same value keeps uid == gid (the conventional Unix pattern for
per-user groups). Has no effect unless also setting
`hyperhive.user.uid`.
'';
};
@ -1063,14 +1096,35 @@ in
`..` path segments.
'';
}
{
assertion =
config.hyperhive.user.uid == null
|| (config.hyperhive.user.uid >= 1000 && config.hyperhive.user.uid < 60000);
message = ''
hyperhive.user.uid must be in [1000, 60000) — values below
1000 clash with system accounts; values ≥ 60000 are reserved
by NixOS for dynamic allocation. Leave unset (null) to let
NixOS auto-assign.
'';
}
{
assertion =
config.hyperhive.user.gid == null
|| (config.hyperhive.user.gid >= 1000 && config.hyperhive.user.gid < 60000);
message = ''
hyperhive.user.gid must be in [1000, 60000) — same range
constraint as hyperhive.user.uid.
'';
}
];
# Per-agent unix user. Runs the hive harness +
# co-process daemons under a non-root principal. UID auto-assigned by
# NixOS. The container activation script (hive-agent-user-migrate)
# chowns the bind-mounted state dir — including credential files
# written by hive-c0re before the container was built — to this user
# on every boot, so agent processes can always read their own tokens.
# NixOS unless `hyperhive.user.uid` is set. The container activation
# script (hive-agent-user-migrate) chowns the bind-mounted state dir
# — including credential files written by hive-c0re before the
# container was built — to this user on every boot, so agent
# processes can always read their own tokens.
users.users.${userName} = {
isNormalUser = true;
home = homeDir;
@ -1082,8 +1136,15 @@ in
# the system default for the root user too (see SHELL env
# var declaration below).
shell = pkgs.bashInteractive;
}
// lib.optionalAttrs (config.hyperhive.user.uid != null) {
uid = config.hyperhive.user.uid;
};
users.groups.${userName} = { };
users.groups.${userName} =
{ }
// lib.optionalAttrs (config.hyperhive.user.gid != null) {
gid = config.hyperhive.user.gid;
};
# `NOPASSWD: ALL` for the agent user. Lets claude's Bash tool
# keep working with anything that expected root (systemctl,