User Provisioning (shani-user-setup)
User Provisioning
shani-user-setup automatically provisions every regular user (UID 1000–59999) with the correct groups, default shell, Flatpak remotes, Nix channels, and rootless container namespaces. It runs as root via a systemd path unit that watches /data/user-setup-needed, triggered by shani-deploy after every OS update and by the first-run wizard when a new user account is created.
---
What It Does
For each interactive user account on the system, shani-user-setup:
- Groups — adds the user to all groups listed in
/etc/shani-extra-groups, skipping any that don't exist - Default shell — sets the shell to Zsh (falling back to Bash if Zsh isn't installed), only if the current shell differs
- Flatpak remote — adds the
flathubremote for the user if not already present - Nix channel — adds the
nixpkgs-unstablechannel if no channel namednixpkgsexists (never overwrites an existing nixpkgs channel) - subuid/subgid ranges — allocates 65,536 sub-UIDs and sub-GIDs for rootless Podman/LXC/LXD if not already assigned
- Podman storage migration — runs
podman system migrateto upgrade the storage graph if/var/lib/containersis mounted
A stamp file at ~/.cache/shani/user-setup.stamp records the script mtime and extra-groups list. If the stamp matches, the expensive steps are skipped on subsequent runs. Set FORCE_SETUP=1 to bypass.
---
Extra Groups
The list of groups added to every user is read from a single file:
/etc/shani-extra-groups
Format: one comma-separated line, no spaces.
wheel,video,input,audio,kvm,storage,network,realtime,scanner,lp,cups,libvirt,lxd
Group Reference
| Group | Purpose | |-------|---------| | wheel | Sudo privileges for system administration | | input | Direct input device access (keyboards, mice, controllers) | | realtime | Real-time scheduling, HPET/RTC access for audio production and low-latency gaming | | video | GPU and video hardware access | | sys | Hardware monitoring and sensor access | | cups, lp | Printer management and job submission | | scanner | Scanner device access | | nixbld | Nix build users group — required for the Nix package manager daemon | | lxc, lxd | LXC/LXD container management without root | | kvm | Virtual machine management (KVM hardware access) | | libvirt | libvirt VM management via virsh and virt-manager |
This file is the single source of truth shared between shani-user-setup and the adduser/useradd wrappers. Editing it ensures that all future users (and any re-provisioning runs) get the same groups.
If the file is absent, shani-user-setup falls back to the built-in default group list.
# View current extra groups
cat /etc/shani-extra-groups
# Add a group (via /etc overlay — persists across updates)
sudo nano /etc/shani-extra-groups
# Force re-provisioning all users with the new group list
sudo FORCE_SETUP=1 shani-user-setup
---
Triggering
shani-user-setup runs when /data/user-setup-needed is created or modified:
# systemd path unit watches for this file
systemctl status shani-user-setup.path
# Trigger manually (e.g. after adding a new user)
sudo touch /data/user-setup-needed
shani-deploy writes this marker after every slot switch so new group assignments from the updated OS are applied on the next login.
---
Running Manually
# Provision all users (normal run)
sudo shani-user-setup
# Dry run — log what would change without making changes
sudo DRY_RUN=1 shani-user-setup
# Force full re-provisioning (ignore stamp file)
sudo FORCE_SETUP=1 shani-user-setup
---
Checking Status
# View provisioning logs
journalctl -t shani-user-setup -n 50
# Check path unit status
systemctl status shani-user-setup.path
systemctl status shani-user-setup.service
# Check if a user is in the required groups
id myuser
# Check subuid/subgid assignment
grep myuser /etc/subuid /etc/subgid
---
After a Factory Reset
After shani-reset, user accounts are gone (the /etc overlay is wiped). On the next boot:
- The first-run wizard creates a new user account
shani-user-setup.pathdetects the new account and triggers provisioning- The new user gets all groups, correct shell, and Flatpak/Nix setup automatically
Files in /home/<username> survive the reset (the @home subvolume is not wiped). Once the account is re-created with the same username, all personal files are immediately accessible.
---
Rootless Container Support
shani-user-setup allocates subUID/subGID ranges automatically, which are required for rootless Podman, Distrobox, LXC, and LXD.
The allocation algorithm finds the highest existing range end in /etc/subuid and allocates the next 65,536 IDs to avoid collisions. For example, with one existing user allocated at 100000–165535, a second user gets 165536–231071.
# Verify your subuid/subgid assignment
cat /etc/subuid
cat /etc/subgid
# Verify Podman rootless works
podman run --rm alpine echo hello
---
See Also
- Shell & Environment — Zsh configuration and shell tools
- Factory Reset — re-provisioning after a reset
- System Config — editing
/etc/shani-extra-groupsvia the overlay