# User Configuration Guide Comprehensive guide to managing user accounts in Athenix. ## Table of Contents - [Overview](#overview) - [Quick Start](#quick-start) - [Defining Users](#defining-users) - [Enabling Users on Hosts](#enabling-users-on-hosts) - [External User Configurations](#external-user-configurations) - [Password Management](#password-management) - [SSH Keys](#ssh-keys) - [User Groups](#user-groups) - [Examples](#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 ```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 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 ```nix 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): ```nix 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](#external-user-configurations) section below. ## User Account Options ### `description` Full name or description of the user. **Type:** String ```nix 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 ```nix athenix.users.myuser.extraGroups = [ "wheel" "networkmanager" "docker" "video" ]; ``` ### `shell` Login shell for the user. **Type:** Package **Default:** `pkgs.bash` ```nix 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:** ```bash # Generate a hashed password mkpasswd -m sha-512 # Or interactively mkpasswd -m sha-512 -c ``` ```nix 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 ```nix athenix.users.myuser.opensshKeys = [ "ssh-ed25519 AAAA... user@laptop" "ssh-rsa AAAA... user@desktop" ]; ``` **Getting your SSH public key:** ```bash # 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` ```nix athenix.users.myuser.useZshTheme = true; ``` ### `useNvimPlugins` Apply system Neovim configuration and plugins to this user. **Type:** Boolean **Default:** `true` ```nix 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 nix-laptop = { devices = 5; overrides.athenix.users.myuser.enable = true; }; ``` ### Enable on Specific Devices ```nix 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 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 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: ```nix { 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): ```nix { 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`: ```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 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: ```bash nix flake init -t git+https://git.factory.uga.edu/UGA-Innovation-Factory/athenix.git#user ``` ## Password Management ### Generate Password Hash ```bash # 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: ```nix athenix.users.myuser = { description = "SSH-only user"; hashedPassword = "!"; opensshKeys = [ "ssh-ed25519 AAAA..." ]; }; ``` ### Update User Password on Running System ```bash # As the user passwd # As root (to change another user's password) sudo passwd username ``` ## SSH Keys ### Add SSH Keys to a User ```nix athenix.users.myuser.opensshKeys = [ "ssh-ed25519 AAAA... user@laptop" "ssh-ed25519 BBBB... user@desktop" ]; ``` ### Get Your SSH Public Key ```bash # Display your public key cat ~/.ssh/id_ed25519.pub # Or for RSA cat ~/.ssh/id_rsa.pub ``` ### Generate New SSH Key ```bash # 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. ```nix athenix.users.myuser.extraGroups = [ "wheel" ]; ``` ### networkmanager Configure network connections (requires `networkmanager` to be enabled): ```nix athenix.users.myuser.extraGroups = [ "networkmanager" ]; ``` ### docker Access Docker daemon (must have Docker enabled on system): ```nix athenix.users.myuser.extraGroups = [ "docker" ]; ``` ### video and audio Access GPU and audio devices: ```nix athenix.users.myuser.extraGroups = [ "video" "audio" ]; ``` ## Examples ### Example 1: Basic Lab User ```nix # 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 ```nix # 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 ```nix # 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 ```nix # 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](INVENTORY.md) - Host configuration - [NAMESPACE.md](NAMESPACE.md) - All configuration options - [EXTERNAL_MODULES.md](EXTERNAL_MODULES.md) - External modules in detail - [README.md](../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):** ```nix { 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):** ```nix { 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.` 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):** ```nix 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 ```bash nix flake init -t git+https://git.factory.uga.edu/UGA-Innovation-Factory/athenix.git#user ``` See [templates/user/README.md](../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 nix-laptop = { devices = 5; overrides = { athenix.users.student.enable = true; # All 5 laptops get this user }; }; ``` ### Method 2: Enable per Device ```nix 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 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 ```bash mkpasswd -m sha-512 # Enter password when prompted # Copy the output hash ``` ### In users.nix ```nix myuser = { hashedPassword = "$6$rounds=656000$..."; # Paste hash here }; ``` ### Disable Password Login ```nix myuser = { hashedPassword = "!"; # Locks password, SSH key only opensshKeys = [ "ssh-ed25519 ..." ]; }; ``` ### Change Password Later On the system: ```bash sudo passwd myuser ``` Or regenerate hash and update `users.nix`. ## SSH Keys ### Adding SSH Keys ```nix myuser = { opensshKeys = [ "ssh-ed25519 AAAAC3Nza... user@laptop" "ssh-rsa AAAAB3NzaC1... user@desktop" ]; }; ``` ### Generate SSH Key ```bash 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: ```nix opensshKeys = [ "ssh-ed25519 ... user@work-laptop" "ssh-ed25519 ... user@home-desktop" "ssh-ed25519 ... user@tablet" ]; ``` ## Examples ### Basic User ```nix student = { description = "Student Account"; extraGroups = [ "networkmanager" ]; shell = pkgs.bash; hashedPassword = "$6$..."; }; ``` ### Admin User with SSH ```nix admin = { description = "System Administrator"; extraGroups = [ "wheel" "networkmanager" "docker" ]; shell = pkgs.zsh; hashedPassword = "$6$..."; opensshKeys = [ "ssh-ed25519 AAAA... admin@laptop" ]; }; ``` ### User with External Configuration ```nix 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 ```nix 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 nix-wsl = { devices."my-wsl".athenix.forUser = "wsl-user"; }; ``` ### User Without System Themes For users who want complete control over their shell/editor: ```nix 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:** ```bash nix eval .#nixosConfigurations.nix-laptop1.config.athenix.users.myuser.enable ``` **Check if user exists:** ```bash # On the system id myuser ``` ### SSH Key Not Working **Check key in configuration:** ```bash 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:** ```bash 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:** ```nix external = /path/to/local/dotfiles; ``` ## See Also - [EXTERNAL_MODULES.md](EXTERNAL_MODULES.md) - External module guide - [INVENTORY.md](INVENTORY.md) - Host configuration guide - [NAMESPACE.md](NAMESPACE.md) - Configuration options reference - [templates/user/](../templates/user/) - User module template - [README.md](../README.md) - Main documentation