2026-10-07 21:14:55 -07:00
|
|
|
|
{
|
|
|
|
|
|
executor,
|
|
|
|
|
|
enable,
|
|
|
|
|
|
controlGroup,
|
2026-10-11 12:59:12 -07:00
|
|
|
|
authorityUser ? "quixos-graph",
|
|
|
|
|
|
engineDirectory ? "/run/quixos-restricted-engines",
|
|
|
|
|
|
firstUid ? 610000,
|
|
|
|
|
|
identityCount ? 64,
|
|
|
|
|
|
wrapperName ? "quixos-restricted-engine",
|
2026-10-07 21:14:55 -07:00
|
|
|
|
}:
|
|
|
|
|
|
{ config, lib, ... }:
|
|
|
|
|
|
{
|
|
|
|
|
|
config = lib.mkIf enable {
|
|
|
|
|
|
assertions = [
|
|
|
|
|
|
{
|
2026-10-11 12:59:12 -07:00
|
|
|
|
assertion = lib.all (
|
|
|
|
|
|
user: user.uid == null || user.uid < firstUid || user.uid >= firstUid + identityCount
|
|
|
|
|
|
) (builtins.attrValues config.users.users);
|
|
|
|
|
|
message = "UIDs ${toString firstUid}–${
|
|
|
|
|
|
toString (firstUid + identityCount - 1)
|
|
|
|
|
|
} are reserved for restricted engine identities.";
|
|
|
|
|
|
}
|
|
|
|
|
|
{
|
|
|
|
|
|
assertion = lib.all (
|
|
|
|
|
|
group: group.gid == null || group.gid < firstUid || group.gid >= firstUid + identityCount
|
|
|
|
|
|
) (builtins.attrValues config.users.groups);
|
|
|
|
|
|
message = "Restricted engine GIDs must not overlap host groups.";
|
2026-10-07 21:14:55 -07:00
|
|
|
|
}
|
|
|
|
|
|
];
|
|
|
|
|
|
systemd.tmpfiles.rules = [
|
2026-10-11 12:59:12 -07:00
|
|
|
|
"d ${engineDirectory} 0711 ${authorityUser} ${controlGroup} -"
|
2026-10-07 21:14:55 -07:00
|
|
|
|
];
|
2026-10-11 12:59:12 -07:00
|
|
|
|
security.wrappers.${wrapperName} = {
|
|
|
|
|
|
source = "${
|
|
|
|
|
|
executor.mkIdentityLauncher {
|
|
|
|
|
|
inherit
|
|
|
|
|
|
authorityUser
|
|
|
|
|
|
engineDirectory
|
|
|
|
|
|
firstUid
|
|
|
|
|
|
identityCount
|
|
|
|
|
|
;
|
|
|
|
|
|
}
|
|
|
|
|
|
}/bin/quixos-restricted-engine";
|
2026-10-07 21:14:55 -07:00
|
|
|
|
owner = "root";
|
|
|
|
|
|
group = controlGroup;
|
|
|
|
|
|
permissions = "u+rx,g+rx,o-rwx";
|
|
|
|
|
|
setuid = true;
|
|
|
|
|
|
};
|
|
|
|
|
|
};
|
|
|
|
|
|
}
|