Files
athenix/docs/USER_CONFIGURATION.md
UGA Innovation Factory f07ccc071e
All checks were successful
CI / Format Check (push) Successful in 6s
CI / Flake Check (push) Successful in 1m25s
CI / Evaluate Key Configurations (nix-builder) (push) Successful in 10s
CI / Evaluate Key Configurations (nix-desktop1) (push) Successful in 11s
CI / Evaluate Key Configurations (nix-laptop1) (push) Successful in 8s
CI / Evaluate Artifacts (installer-iso-nix-laptop1) (push) Successful in 16s
CI / Evaluate Artifacts (lxc-nix-builder) (push) Successful in 10s
docs: Copilot update all docs files
2026-01-05 10:05:41 -05:00

21 KiB

User Configuration Guide

Comprehensive guide to managing user accounts in Athenix.

Table of Contents

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 configuration
  • nixos.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 configuration
  • lib - Nixpkgs library functions
  • pkgs - Package set
  • osConfig - 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 functions
  • pkgs - Package set
  • osConfig - (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:

  1. 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 in users.nix.

  2. Home-Manager Context: The same module is imported into home-manager where home.*, programs.*, and services.* 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 inputs
  • config - NixOS configuration
  • lib - Nixpkgs library functions
  • pkgs - 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, or ssh-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.nix at repository root
  • nixos.nix is optional
  • Check file permissions

Test with local path first:

external = /path/to/local/dotfiles;

See Also