11 KiB
User Configuration Guide
Complete guide to managing user accounts in nixos-systems.
Table of Contents
- Overview
- Quick Start
- User Account Options
- External User Configurations
- Enabling Users on Hosts
- Password Management
- SSH Keys
- Examples
Overview
Users are defined in users.nix but are not enabled by default on all systems. Each system must explicitly enable users in inventory.nix.
Default enabled users:
root- System administratorengr-ugaif- Innovation Factory default account
Quick Start
1. Define User in users.nix
ugaif.users = {
myuser = {
description = "My Full Name";
extraGroups = [ "wheel" "networkmanager" ];
shell = pkgs.zsh;
hashedPassword = "$6$..."; # Generate with: mkpasswd -m sha-512
opensshKeys = [
"ssh-ed25519 AAAA... user@machine"
];
};
};
2. Enable User on Hosts
In inventory.nix:
nix-laptop = {
devices = 2;
overrides.ugaif.users.myuser.enable = true; # Enables on all nix-laptop hosts
};
# Or for specific devices
nix-desktop = {
devices = {
"1".ugaif.users.myuser.enable = true;
"2".ugaif.users.otheruser.enable = true;
};
};
# Or use convenience option
nix-wsl = {
devices."alice".ugaif.forUser = "alice-user"; # Automatically enables user
};
User Account Options
Each user in users.nix can have the following options:
username = {
# === Identity ===
description = "Full Name"; # User's full name
# === System Access ===
isNormalUser = true; # Default: true (false for root)
extraGroups = [ # Additional Unix groups
"wheel" # Sudo access
"networkmanager" # Network configuration
"docker" # Docker access
"video" # Video device access
"audio" # Audio device access
];
shell = pkgs.zsh; # Login shell (default: pkgs.bash)
hashedPassword = "$6$..."; # Hashed password (see below)
# === SSH Access ===
opensshKeys = [ # SSH public keys
"ssh-ed25519 AAAA... user@host"
"ssh-rsa AAAA... user@otherhost"
];
# === External Configuration ===
external = builtins.fetchGit { ... }; # External user module (see below)
# OR (if not using external config):
homePackages = with pkgs; [ # User packages
ripgrep
fd
bat
];
extraImports = [ ./my-module.nix ]; # Additional home-manager modules
# === Theme Integration ===
useZshTheme = true; # Apply system Zsh theme (default: true)
useNvimPlugins = true; # Apply system Neovim config (default: true)
# === System Enablement ===
enable = false; # Enable on this system (set in inventory.nix)
};
External User Configurations
Users can maintain their dotfiles and home-manager configuration in separate Git repositories.
Basic External Configuration
In users.nix:
myuser = {
# Basic options can be set here OR in the external module's user.nix
description = "My Name";
extraGroups = [ "wheel" ];
hashedPassword = "$6$...";
# Point to external configuration repository
external = builtins.fetchGit {
url = "https://github.com/username/dotfiles";
rev = "abc123..."; # Pin to specific commit
};
};
External Repository Structure
dotfiles/
├── user.nix # Optional: User options AND home-manager config
├── nixos.nix # Optional: System-level configuration
└── config/ # Optional: Your dotfiles
├── bashrc
├── vimrc
└── ...
Both .nix files are optional, but at least one should be present.
user.nix (optional):
{ inputs, ... }:
{ config, lib, pkgs, ... }:
{
# User account options (imported as NixOS module)
ugaif.users.myuser = {
description = "My Full Name";
extraGroups = [ "wheel" "docker" ];
shell = pkgs.zsh;
useZshTheme = true;
};
# Home-manager configuration (imported into home-manager)
home.packages = with pkgs; [
vim
ripgrep
];
programs.git = {
enable = true;
userName = "My Name";
userEmail = "me@example.com";
};
home.file.".bashrc".source = ./config/bashrc;
}
nixos.nix (optional):
{ inputs, ... }:
{ config, lib, pkgs, ... }:
{
# System-level configuration
users.users.myusername.extraGroups = [ "docker" ];
environment.systemPackages = [ pkgs.docker ];
}
What External Modules Receive
In user.nix:
inputs- Flake inputs (nixpkgs, home-manager, etc.)config- Configuration (NixOS or home-manager depending on import context)lib- Nixpkgs library functionspkgs- Package setosConfig- (home-manager context only) OS-level configuration
How External Modules Are Loaded
The user.nix module is used in two ways:
-
User Options (Data Extraction): The
ugaif.users.<username>options are extracted and loaded as data. The module is evaluated with minimal arguments to extract just the ugaif.users options, which override any defaults set inusers.nix(which useslib.mkDefault). -
Home-Manager Configuration: The entire module (including
home.*,programs.*,services.*options) is imported into home-manager as a configuration module.
This means you can define both user account settings AND home-manager configuration in a single file.
In nixos.nix:
inputs- Flake inputsconfig- NixOS configurationlib- Nixpkgs library functionspkgs- Package set
Alternative Configuration Methods
Local path (for testing):
external = /home/username/dev/dotfiles;
Note: User options can be set in users.nix OR in the external module's user.nix file.
No external config:
# Configure everything directly in users.nix
myuser = {
description = "My Name";
homePackages = with pkgs; [ vim git ];
# external is null by default
};
Create User Template
nix flake init -t github:UGA-Innovation-Factory/nixos-systems#user
See templates/user/README.md for complete template.
Enabling Users on Hosts
Users must be explicitly enabled on each host in inventory.nix.
Method 1: Enable in Overrides (All Devices)
nix-laptop = {
devices = 5;
overrides = {
ugaif.users.student.enable = true; # All 5 laptops get this user
};
};
Method 2: Enable per Device
nix-desktop = {
devices = {
"1".ugaif.users.alice.enable = true;
"2".ugaif.users.bob.enable = true;
"3" = {
ugaif.users.alice.enable = true;
ugaif.users.bob.enable = true;
};
};
};
Method 3: Convenience Option (ugaif.forUser)
Quick setup for single-user systems:
nix-wsl = {
devices = {
"alice".ugaif.forUser = "alice-user"; # Automatically enables alice-user
"bob".ugaif.forUser = "bob-user";
};
};
This is equivalent to ugaif.users.alice-user.enable = true.
Password Management
Generate Hashed Password
mkpasswd -m sha-512
# Enter password when prompted
# Copy the output hash
In users.nix
myuser = {
hashedPassword = "$6$rounds=656000$..."; # Paste hash here
};
Disable Password Login
myuser = {
hashedPassword = "!"; # Locks password, SSH key only
opensshKeys = [ "ssh-ed25519 ..." ];
};
Change Password Later
On the system:
sudo passwd myuser
Or regenerate hash and update users.nix.
SSH Keys
Adding SSH Keys
myuser = {
opensshKeys = [
"ssh-ed25519 AAAAC3Nza... user@laptop"
"ssh-rsa AAAAB3NzaC1... user@desktop"
];
};
Generate SSH Key
ssh-keygen -t ed25519 -C "user@hostname"
cat ~/.ssh/id_ed25519.pub # Copy this
Multiple Keys
Users can have multiple SSH keys for different machines:
opensshKeys = [
"ssh-ed25519 ... user@work-laptop"
"ssh-ed25519 ... user@home-desktop"
"ssh-ed25519 ... user@tablet"
];
Examples
Basic User
student = {
description = "Student Account";
extraGroups = [ "networkmanager" ];
shell = pkgs.bash;
hashedPassword = "$6$...";
};
Admin User with SSH
admin = {
description = "System Administrator";
extraGroups = [ "wheel" "networkmanager" "docker" ];
shell = pkgs.zsh;
hashedPassword = "$6$...";
opensshKeys = [
"ssh-ed25519 AAAA... admin@laptop"
];
};
User with External Dotfiles
developer = {
description = "Developer";
extraGroups = [ "wheel" "docker" ];
shell = pkgs.zsh;
hashedPassword = "$6$...";
home = builtins.fetchGit {
url = "https://github.com/username/dotfiles";
rev = "abc123def456...";
};
};
WSL User
wsl-user = {
description = "WSL User";
extraGroups = [ "wheel" ];
shell = pkgs.zsh;
hashedPassword = "$6$...";
home = builtins.fetchGit {
url = "https://github.com/username/dotfiles";
rev = "abc123...";
};
};
Enable in inventory.nix:
nix-wsl = {
devices."my-wsl".ugaif.forUser = "wsl-user";
};
User Without System Themes
For users who want complete control over their shell/editor:
poweruser = {
description = "Power User";
extraGroups = [ "wheel" ];
shell = pkgs.zsh;
hashedPassword = "$6$...";
useZshTheme = false; # Don't apply system theme
useNvimPlugins = false; # Don't apply system nvim config
home = builtins.fetchGit {
url = "https://github.com/username/custom-dotfiles";
rev = "abc123...";
};
};
Theme Integration
System Zsh Theme
When useZshTheme = true (default), the system applies:
- Oh My Posh with custom theme
- History substring search
- Vi mode (for non-root users)
- Zsh plugins (zplug)
Disable if you want full control in your dotfiles.
System Neovim Config
When useNvimPlugins = true (default), the system applies:
- LazyVim distribution
- TreeSitter parsers
- Language servers
Disable if you want to configure Neovim yourself.
Troubleshooting
User Can't Login
Check if enabled on host:
nix eval .#nixosConfigurations.nix-laptop1.config.ugaif.users.myuser.enable
Check if user exists:
# On the system
id myuser
SSH Key Not Working
Check key in configuration:
nix eval .#nixosConfigurations.nix-laptop1.config.users.users.myuser.openssh.authorizedKeys.keys
Verify key format:
- Should start with
ssh-ed25519,ssh-rsa, orssh-dss - Should be all on one line
- Should end with comment (optional)
External Config Not Loading
Check repository access:
git ls-remote https://github.com/username/dotfiles
Verify structure:
- Must have
home.nixat repository root nixos.nixis optional- Check file permissions
Test with local path first:
home = /path/to/local/dotfiles;
See Also
- docs/EXTERNAL_MODULES.md - External module guide
- docs/INVENTORY.md - Host configuration
- docs/NAMESPACE.md - Configuration options
- templates/user/ - User module template
- README.md - Main documentation