Multi-user
A glixos host can run home-manager configs for any number of users. Each
home-scope package is routed to a specific user; the default is
[settings] primary_user, and any package can override with its own
user field.
See ADR-010 for the design.
Choosing a target user
# Goes to settings.primary_user (alice on this host).
glix add --scope=home github:owner/pkg-greeting
# Explicit per-package override.
glix add --scope=home --user=bob github:owner/pkg-greeting --name=greeting-bob
glix set greeting-bob config.message="Hi, Bob."
The two packages must have distinct names. By convention, suffix the
override package with -<user> so it's obvious in glix list.
Making sure the user exists
importManifest happily routes packages to whatever user names appear in
the manifest, but home-manager will fail to evaluate if the user isn't
declared in NixOS. The init template declares your primary user:
# hosts/laptop/default.nix
users.users."@USER@" = {
isNormalUser = true;
extraGroups = [ "wheel" "networkmanager" ];
initialPassword = "changeme";
};
For additional users, either:
- Add a
users.users.bob = { ... };block inhosts/<host>/default.nix, or - Put it in a
shared/users.nixmodule imported from each host.
Either approach is normal NixOS; glix has no opinions here beyond "the user must exist when you rebuild".
Listing the routing
glix list
NAME SCOPE STATE USER FLAKE
greeting home enabled alice github:owner/pkg-greeting
greeting-bob home enabled bob github:owner/pkg-greeting
firefox system enabled github:NixOS/nixpkgs#firefox
glix show greeting-bob
name greeting-bob
flake github:owner/pkg-greeting
scope home
state enabled
user bob
host laptop
config
message = Hi, Bob.
Changing the target user
glix set greeting user=alice # set
glix set greeting user= # clear; fall back to primary_user
glix set validates that the value is a legal POSIX-ish ident
([A-Za-z][A-Za-z0-9_-]*).
Inside the manifest
A multi-user manifest looks like:
[settings]
default_scope = "home"
primary_user = "alice"
[packages.greeting]
flake = "github:owner/pkg-greeting"
scope = "home"
enabled = true
# no user field → routed to alice
[packages.greeting-bob]
flake = "github:owner/pkg-greeting"
scope = "home"
enabled = true
user = "bob"
[packages.greeting-bob.config]
message = "Hi, Bob."
What this generates in Nix
importManifest returns a homeModulesByUser attrset:
homeModulesByUser = {
alice = [ <pkg-greeting module wrapped with glixConfig = {}> ];
bob = [ <pkg-greeting module wrapped with glixConfig.message = "Hi, Bob."> ];
}
The host template feeds this directly to home-manager:
home-manager.users = lib.mapAttrs
(_: mods: { imports = mods ++ [ { home.stateVersion = "24.11"; } ]; })
manifest.homeModulesByUser;
So adding a new user takes nothing more than declaring them in NixOS and
running glix add --user=<name>.