21 KiB
User Configuration Guide
Comprehensive guide to managing user accounts in Athenix.
Table of Contents
- Overview
- Quick Start
- Defining Users
- Enabling Users on Hosts
- External User Configurations
- Password Management
- SSH Keys
- User Groups
- Examples
Overview
User accounts are defined in users.nix but are not enabled by default. Each host must explicitly enable users in inventory.nix.
Always-enabled users:
root- System administrator (enable: true)engr-ugaif- Innovation Factory default account (enable: true)
All other users are disabled by default and must be explicitly enabled per-host.
Quick Start
1. Define User in users.nix
athenix.users.myuser = {
description = "John Doe";
extraGroups = [ "wheel" "networkmanager" ];
shell = pkgs.zsh;
hashedPassword = "$6$..."; # Generate with: mkpasswd -m sha-512
opensshKeys = [ "ssh-ed25519 AAAA..." ];
};
2. Enable on Hosts in inventory.nix
nix-laptop = {
devices = 5;
overrides.athenix.users.myuser.enable = true;
};
3. Users can now log in
Users defined and enabled this way are automatically created on the system.
Defining Users
Define users in users.nix under athenix.users:
Inline User Definition
athenix.users.myuser = {
description = "My Full Name";
extraGroups = [ "wheel" "networkmanager" ];
shell = pkgs.zsh;
hashedPassword = "$6$...";
opensshKeys = [ "ssh-ed25519 AAAA..." ];
useZshTheme = true;
useNvimPlugins = true;
};
External User Configuration
Reference an external Git repository (recommended for personal dotfiles):
athenix.users.myuser.external = builtins.fetchGit {
url = "https://git.factory.uga.edu/username/dotfiles";
rev = "abc123..."; # Pin to specific commit
};
The external repository should contain:
user.nix(required) - User account options AND home-manager configurationnixos.nix(optional) - System-level configuration
See External User Configurations section below.
User Account Options
description
Full name or description of the user.
Type: String
athenix.users.myuser.description = "John Doe";
extraGroups
Additional Unix groups for the user. Default is empty.
Type: List of strings
Common groups:
"wheel"- Sudo access"networkmanager"- Network configuration"docker"- Docker and Podman access"video"- Video device access (GPU, displays)"audio"- Audio device access"input"- Input devices (keyboards, mice)"kvm"- KVM virtual machine access"libvirtd"- Libvirt daemon access
athenix.users.myuser.extraGroups = [
"wheel"
"networkmanager"
"docker"
"video"
];
shell
Login shell for the user.
Type: Package
Default: pkgs.bash
athenix.users.myuser.shell = pkgs.zsh;
# or
athenix.users.myuser.shell = pkgs.fish;
hashedPassword
Password hash for the user. Use ! to disable password login (SSH keys only).
Type: String (SHA-512 hash)
Generation:
# Generate a hashed password
mkpasswd -m sha-512
# Or interactively
mkpasswd -m sha-512 -c
athenix.users.myuser.hashedPassword = "$6$...";
# Disable password login (require SSH keys)
athenix.users.myuser.hashedPassword = "!";
opensshKeys
SSH public keys for remote access. Users without SSH keys require password login.
Type: List of strings
athenix.users.myuser.opensshKeys = [
"ssh-ed25519 AAAA... user@laptop"
"ssh-rsa AAAA... user@desktop"
];
Getting your SSH public key:
# Print your public key
cat ~/.ssh/id_ed25519.pub
# Generate a new key if needed
ssh-keygen -t ed25519 -C "user@host"
useZshTheme
Apply system Zsh theme configuration to this user (if using Zsh as shell).
Type: Boolean
Default: true
athenix.users.myuser.useZshTheme = true;
useNvimPlugins
Apply system Neovim configuration and plugins to this user.
Type: Boolean
Default: true
athenix.users.myuser.useNvimPlugins = true;
Enabling Users on Hosts
Users are not enabled by default. Enable them in inventory.nix:
Enable on All Devices in a Group
nix-laptop = {
devices = 5;
overrides.athenix.users.myuser.enable = true;
};
Enable on Specific Devices
nix-desktop = {
devices = {
"1".athenix.users.admin.enable = true;
"2".athenix.users.staff.enable = true;
"3".athenix.users.staff.enable = true;
};
};
Enable Multiple Users
nix-laptop = {
devices = 5;
overrides = {
athenix.users.student.enable = true;
athenix.users.teacher.enable = true;
};
};
Using athenix.forUser Convenience
Quick setup for single-user systems (especially WSL):
nix-wsl = {
devices = {
"alice".athenix.forUser = "alice-uga";
"bob".athenix.forUser = "bob-uga";
};
};
This automatically enables the user and sets it as the default WSL user.
External User Configurations
External user configurations (dotfiles) allow users to maintain their own home-manager setup in separate repositories.
Repository Structure
my-dotfiles/
├── user.nix # Required: User options + home-manager config
├── nixos.nix # Optional: System-level configuration
└── config/ # Optional: Your actual dotfiles
├── bashrc
├── zshrc
├── vimrc
└── ...
user.nix (Required)
This file must provide BOTH user account options AND home-manager configuration:
{ inputs, ... }:
{ config, lib, pkgs, osConfig ? null, ... }:
{
# ========== User Account Configuration ==========
# These options define the user account itself
athenix.users.myusername = {
description = "My Full Name";
extraGroups = [ "wheel" "docker" "networkmanager" ];
shell = pkgs.zsh;
hashedPassword = "!"; # SSH keys only
opensshKeys = [
"ssh-ed25519 AAAA... user@host"
];
useZshTheme = true;
useNvimPlugins = true;
};
# ========== Home Manager Configuration ==========
# User environment, packages, and dotfiles
home.packages = with pkgs; [
vim
ripgrep
fzf
] ++ lib.optional (osConfig.athenix.sw.type or null == "desktop") firefox;
programs.git = {
enable = true;
userName = "My Name";
userEmail = "me@example.com";
extraConfig = {
init.defaultBranch = "main";
core.editor = "vim";
};
};
programs.zsh = {
enable = true;
initExtra = ''
# Your Zsh configuration
'';
};
# Manage dotfiles
home.file.".config/zshrc".source = ./config/zshrc;
home.file.".config/bashrc".source = ./config/bashrc;
home.file.".vimrc".source = ./config/vimrc;
}
nixos.nix (Optional)
System-level configuration for this user (rarely needed):
{ inputs, ... }:
{ config, lib, pkgs, ... }:
{
# System-level configuration for this user
users.users.myusername.extraGroups = [ "docker" ];
environment.systemPackages = [ pkgs.docker ];
}
Using External User Configuration
In users.nix:
athenix.users.myuser.external = builtins.fetchGit {
url = "https://git.factory.uga.edu/username/dotfiles";
rev = "abc123..."; # Pin to specific commit
};
Then enable on hosts in inventory.nix:
nix-laptop = {
devices = 5;
overrides.athenix.users.myuser.enable = true;
};
External Module Parameters
The user.nix module receives:
inputs- All flake inputs (nixpkgs, home-manager, etc.)config- Home-manager configurationlib- Nixpkgs library functionspkgs- Package setosConfig- OS-level configuration (read-only, can be used for conditional setup)
Creating External User Configuration
Use the template:
nix flake init -t git+https://git.factory.uga.edu/UGA-Innovation-Factory/athenix.git#user
Password Management
Generate Password Hash
# Interactive (won't echo)
mkpasswd -m sha-512 -c
# From string
echo "mypassword" | mkpasswd -m sha-512 -s
Disable Password Login
Set hashedPassword = "!" and provide SSH keys:
athenix.users.myuser = {
description = "SSH-only user";
hashedPassword = "!";
opensshKeys = [ "ssh-ed25519 AAAA..." ];
};
Update User Password on Running System
# As the user
passwd
# As root (to change another user's password)
sudo passwd username
SSH Keys
Add SSH Keys to a User
athenix.users.myuser.opensshKeys = [
"ssh-ed25519 AAAA... user@laptop"
"ssh-ed25519 BBBB... user@desktop"
];
Get Your SSH Public Key
# Display your public key
cat ~/.ssh/id_ed25519.pub
# Or for RSA
cat ~/.ssh/id_rsa.pub
Generate New SSH Key
# Ed25519 (recommended)
ssh-keygen -t ed25519 -C "user@host"
# RSA (older systems)
ssh-keygen -t rsa -b 4096 -C "user@host"
User Groups
wheel
Allows passwordless sudo access.
athenix.users.myuser.extraGroups = [ "wheel" ];
networkmanager
Configure network connections (requires networkmanager to be enabled):
athenix.users.myuser.extraGroups = [ "networkmanager" ];
docker
Access Docker daemon (must have Docker enabled on system):
athenix.users.myuser.extraGroups = [ "docker" ];
video and audio
Access GPU and audio devices:
athenix.users.myuser.extraGroups = [ "video" "audio" ];
Examples
Example 1: Basic Lab User
# users.nix
athenix.users.student = {
description = "Student Account";
extraGroups = [ "networkmanager" ];
shell = pkgs.bash;
hashedPassword = "$6$...";
opensshKeys = []; # Password login only
};
# inventory.nix
nix-laptop = {
devices = 20;
overrides.athenix.users.student.enable = true;
};
Example 2: Developer with SSH Keys
# users.nix
athenix.users.developer = {
description = "Developer";
extraGroups = [ "wheel" "docker" "networkmanager" ];
shell = pkgs.zsh;
hashedPassword = "!";
opensshKeys = [
"ssh-ed25519 AAAA... dev@laptop"
];
useZshTheme = true;
useNvimPlugins = true;
};
# inventory.nix
nix-desktop = {
devices = 3;
overrides.athenix.users.developer.enable = true;
};
Example 3: WSL User with Dotfiles
# users.nix
athenix.users.alice.external = builtins.fetchGit {
url = "https://git.factory.uga.edu/alice/dotfiles";
rev = "abc123...";
};
# inventory.nix
nix-wsl = {
devices = {
"alice".athenix.forUser = "alice-uga";
};
};
Example 4: Multiple Users on Single System
# users.nix
athenix.users = {
admin = {
description = "System Administrator";
extraGroups = [ "wheel" ];
shell = pkgs.bash;
hashedPassword = "!";
opensshKeys = [ "ssh-ed25519 AAAA..." ];
};
guest = {
description = "Guest User";
extraGroups = [];
shell = pkgs.bash;
hashedPassword = "$6$...";
};
};
# inventory.nix
nix-desktop = {
devices = {
"admin-station" = {
athenix.users.admin.enable = true;
};
"guest-station" = {
athenix.users.guest.enable = true;
};
};
};
See Also
-
INVENTORY.md - Host configuration
-
NAMESPACE.md - All configuration options
-
EXTERNAL_MODULES.md - External modules in detail
-
README.md - Main documentation external = builtins.fetchGit { ... }; # External user module (see below)
=== 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`:
```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://git.factory.uga.edu/username/dotfiles";
rev = "abc123..."; # Pin to specific commit
};
};
External Repository Structure
dotfiles/
├── user.nix # Required: User options AND home-manager config
├── nixos.nix # Optional: System-level configuration
└── config/ # Optional: Your dotfiles
├── bashrc
├── vimrc
└── ...
At least user.nix should be present for a functional user module.
user.nix (required):
{ inputs, ... }:
{ config, lib, pkgs, osConfig ? null, ... }:
{
# ========== User Account Configuration ==========
# These options define the user account itself
athenix.users.myuser = {
description = "My Full Name";
extraGroups = [ "wheel" "docker" ];
shell = pkgs.zsh;
hashedPassword = "!";
opensshKeys = [
"ssh-ed25519 AAAA... user@host"
];
useZshTheme = true;
useNvimPlugins = true;
};
# ========== Home Manager Configuration ==========
# User environment, packages, and dotfiles
home.packages = with pkgs; [
vim
ripgrep
] ++ lib.optional (osConfig.athenix.sw.type or null == "desktop") firefox;
programs.git = {
enable = true;
userName = "My Name";
userEmail = "me@example.com";
extraConfig = {
init.defaultBranch = "main";
};
};
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 serves a dual purpose and is imported in two contexts:
-
NixOS Module Context (User Options): The module is imported as a NixOS module where
athenix.users.<username>options are read to define the user account (description, shell, groups, SSH keys, etc.). These options override any defaults set inusers.nix. -
Home-Manager Context: The same module is imported into home-manager where
home.*,programs.*, andservices.*options configure the user's environment, packages, and dotfiles.
Key insight: A single user.nix file contains both account configuration AND home environment configuration. The system automatically imports it in the appropriate contexts.
Example: The user account options (like shell, extraGroups) are read during NixOS evaluation, while home-manager options (like home.packages, programs.git) are used when building the user's home environment.
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. For custom packages and environment configuration without external modules, create a local module and reference it with extraImports.
Create User Template
nix flake init -t git+https://git.factory.uga.edu/UGA-Innovation-Factory/athenix.git#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 = {
athenix.users.student.enable = true; # All 5 laptops get this user
};
};
Method 2: Enable per Device
nix-desktop = {
devices = {
"1".athenix.users.alice.enable = true;
"2".athenix.users.bob.enable = true;
"3" = {
athenix.users.alice.enable = true;
athenix.users.bob.enable = true;
};
};
};
Method 3: Convenience Option (athenix.forUser)
Quick setup for single-user systems:
nix-wsl = {
devices = {
"alice".athenix.forUser = "alice-user"; # Automatically enables alice-user
"bob".athenix.forUser = "bob-user";
};
};
This is equivalent to athenix.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 Configuration
developer = {
description = "Developer";
extraGroups = [ "wheel" "docker" ];
shell = pkgs.zsh;
hashedPassword = "$6$...";
external = builtins.fetchGit {
url = "https://git.factory.uga.edu/username/dotfiles";
rev = "abc123def456...";
};
};
WSL User
wsl-user = {
description = "WSL User";
extraGroups = [ "wheel" ];
shell = pkgs.zsh;
hashedPassword = "$6$...";
external = builtins.fetchGit {
url = "https://git.factory.uga.edu/username/dotfiles";
rev = "abc123...";
};
};
Enable in inventory.nix:
nix-wsl = {
devices."my-wsl".athenix.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
external = 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.athenix.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://git.factory.uga.edu/username/dotfiles
Verify structure:
- Must have
user.nixat repository root nixos.nixis optional- Check file permissions
Test with local path first:
external = /path/to/local/dotfiles;
See Also
- EXTERNAL_MODULES.md - External module guide
- INVENTORY.md - Host configuration guide
- NAMESPACE.md - Configuration options reference
- templates/user/ - User module template
- README.md - Main documentation