Files
nixos-servers/docs/user-management.md
Torjus Håkestad 02270a0e4a
Some checks failed
Run nix flake check / flake-check (pull_request) Successful in 2m7s
Run nix flake check / flake-check (push) Failing after 16m31s
docs: update plans with Grafana OIDC progress
- auth-system-replacement.md: Mark OAuth2 client (Grafana) as completed,
  document key findings (PKCE, attribute paths, user requirements)
- monitoring-migration-victoriametrics.md: Note Grafana deployment on
  monitoring02 with Kanidm OIDC as test instance

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-08 20:28:10 +01:00

6.7 KiB

User Management with Kanidm

Central authentication for the homelab using Kanidm.

Overview

CLI Setup

The kanidm CLI is available in the devshell:

nix develop

# Login as idm_admin
kanidm login --name idm_admin --url https://auth.home.2rjus.net

User Management

POSIX users are managed imperatively via the kanidm CLI. This allows setting all attributes (including UNIX password) in one workflow.

Creating a POSIX User

# Create the person
kanidm person create <username> "<Display Name>"

# Add to groups
kanidm group add-members ssh-users <username>

# Enable POSIX (UID is auto-assigned)
kanidm person posix set <username>

# Set UNIX password (required for SSH login, min 10 characters)
kanidm person posix set-password <username>

# Optionally set login shell
kanidm person posix set <username> --shell /bin/zsh

Setting Email Address

Email is required for OAuth2/OIDC login (e.g., Grafana):

kanidm person update <username> --mail <email>

Example: Full User Creation

kanidm person create testuser "Test User"
kanidm person update testuser --mail testuser@home.2rjus.net
kanidm group add-members ssh-users testuser
kanidm group add-members users testuser  # Required for OAuth2 scopes
kanidm person posix set testuser
kanidm person posix set-password testuser
kanidm person get testuser

After creation, verify on a client host:

getent passwd testuser
ssh testuser@testvm01.home.2rjus.net

Viewing User Details

kanidm person get <username>

Removing a User

kanidm person delete <username>

Group Management

Groups for POSIX access are also managed via CLI.

Creating a POSIX Group

# Create the group
kanidm group create <group-name>

# Enable POSIX with a specific GID
kanidm group posix set <group-name> --gidnumber <gid>

Adding Members

kanidm group add-members <group-name> <username>

Viewing Group Details

kanidm group get <group-name>
kanidm group list-members <group-name>

Example: Full Group Creation

kanidm group create testgroup
kanidm group posix set testgroup --gidnumber 68010
kanidm group add-members testgroup testuser
kanidm group get testgroup

After creation, verify on a client host:

getent group testgroup

Current Groups

Group GID Purpose
ssh-users 68000 SSH login access
admins 68001 Administrative access
users 68002 General users

UID/GID Allocation

Kanidm auto-assigns UIDs/GIDs from its configured range. For manually assigned GIDs:

Range Purpose
65,536+ Users (auto-assigned)
68,000 - 68,999 Groups (manually assigned)

OAuth2/OIDC Login (Web Services)

For OAuth2/OIDC login to web services like Grafana, users need:

  1. Primary credential - Password set via credential update (separate from unix password)
  2. MFA - TOTP or passkey (Kanidm requires MFA for primary credentials)
  3. Group membership - Member of users group (for OAuth2 scope mapping)
  4. Email address - Set via person update --mail

Setting Up Primary Credential (Web Login)

The primary credential is different from the unix/POSIX password:

# Interactive credential setup
kanidm person credential update <username>

# In the interactive prompt:
# 1. Type 'password' to set a password
# 2. Type 'totp' to add TOTP (scan QR with authenticator app)
# 3. Type 'commit' to save

Verifying OAuth2 Readiness

kanidm person get <username>

Check for:

  • mail: - Email address set
  • memberof: - Includes users@home.2rjus.net
  • Primary credential status (check via credential updatestatus)

PAM/NSS Client Configuration

Enable central authentication on a host:

homelab.kanidm.enable = true;

This configures:

  • services.kanidm.enablePam = true
  • Client connection to auth.home.2rjus.net
  • Login authorization for ssh-users group
  • Short usernames (torjus instead of torjus@home.2rjus.net)
  • Home directory symlinks (/home/torjus → UUID-based directory)

Enabled Hosts

  • testvm01, testvm02, testvm03 (test tier)

Options

homelab.kanidm = {
  enable = true;
  server = "https://auth.home.2rjus.net";  # default
  allowedLoginGroups = [ "ssh-users" ];     # default
};

Home Directories

Home directories use UUID-based paths for stability (so renaming a user doesn't require moving their home directory). Symlinks provide convenient access:

/home/torjus -> /home/e4f4c56c-4aee-4c20-846f-90cb69807733

The symlinks are created by kanidm-unixd-tasks on first login.

Testing

Verify NSS Resolution

# Check user resolution
getent passwd <username>

# Check group resolution
getent group <group-name>

Test SSH Login

ssh <username>@<hostname>.home.2rjus.net

Troubleshooting

"PAM user mismatch" error

SSH fails with "fatal: PAM user mismatch" in logs. This happens when Kanidm returns usernames in SPN format (torjus@home.2rjus.net) but SSH expects short names (torjus).

Solution: Configure uid_attr_map = "name" in unixSettings (already set in our module).

Check current format:

getent passwd torjus
# Should show: torjus:x:65536:...
# NOT: torjus@home.2rjus.net:x:65536:...

User resolves but SSH fails immediately

The user's login group (e.g., ssh-users) likely doesn't have POSIX enabled:

# Check if group has POSIX
getent group ssh-users

# If empty, enable POSIX on the server
kanidm group posix set ssh-users --gidnumber 68000

User doesn't resolve via getent

  1. Check kanidm-unixd service is running:

    systemctl status kanidm-unixd
    
  2. Check unixd can reach server:

    kanidm-unix status
    # Should show: system: online, Kanidm: online
    
  3. Check client can reach server:

    curl -s https://auth.home.2rjus.net/status
    
  4. Check user has POSIX enabled on server:

    kanidm person get <username>
    
  5. Restart nscd to clear stale cache:

    systemctl restart nscd
    
  6. Invalidate kanidm cache:

    kanidm-unix cache-invalidate
    

Changes not taking effect after deployment

NixOS uses nsncd (a Rust reimplementation of nscd) for NSS caching. After deploying kanidm-unixd config changes, you may need to restart both services:

systemctl restart kanidm-unixd
systemctl restart nscd

Test PAM authentication directly

Use the kanidm-unix CLI to test PAM auth without SSH:

kanidm-unix auth-test --name <username>