# services/authelia.nix — Native Authelia SSO # Secrets live in /var/secrets/authelia (root:authelia-main, 640) — see readme. # # Users live in /var/lib/authelia-users so guildhall-join (services/ # guildhall-join.nix) can add invited players; Authelia only reads it and # reloads on change. Groups decide reach: `household` gets the shared home # sites, `guildhall` gets the game and nothing else. { config, lib, pkgs, ... }: let admin = [ "user:fred" ]; household = [ "group:household" ]; usersDir = "/var/lib/authelia-users"; usersFile = "${usersDir}/users_database.yml"; # One-time move out of Authelia's private state dir, then the same # ownership on every start: guildhall-join writes, authelia-users reads. prepareUsers = pkgs.writeShellScript "authelia-users-prepare" '' set -eu ${pkgs.coreutils}/bin/install -d -m 0750 -o guildhall-join -g authelia-users ${usersDir} if [ ! -e ${usersFile} ]; then ${pkgs.coreutils}/bin/cp /var/lib/authelia-main/users_database.yml ${usersFile} fi ${pkgs.coreutils}/bin/chown guildhall-join:authelia-users ${usersFile} ${pkgs.coreutils}/bin/chmod 0640 ${usersFile} ''; in { config = lib.mkIf (config.networking.hostName == "FredOS-Mediaserver") { services.authelia.instances.main = { enable = true; secrets = { jwtSecretFile = "/var/secrets/authelia/jwt_secret"; storageEncryptionKeyFile = "/var/secrets/authelia/storage_encryption_key"; sessionSecretFile = "/var/secrets/authelia/session_secret"; }; settings = { theme = "dark"; server.address = "tcp://127.0.0.1:9091/"; log = { level = "info"; format = "text"; }; authentication_backend.file = { path = usersFile; watch = true; }; access_control = { default_policy = "deny"; # Admin tools are fred-only (`admin`), the shared home sites need # the household group, and invited players only reach the game. rules = [ { domain = "frigate.nordhammer.it"; policy = "one_factor"; subject = household; } { domain = "camera.nordhammer.it"; policy = "one_factor"; subject = household; } # { domain = "7dtd.nordhammer.it"; policy = "one_factor"; } # 7DTD disabled { domain = "adguard.nordhammer.it"; policy = "one_factor"; subject = admin; } { domain = "router.nordhammer.it"; policy = "one_factor"; subject = admin; } { domain = "sonarr.nordhammer.it"; policy = "one_factor"; subject = admin; } { domain = "radarr.nordhammer.it"; policy = "one_factor"; subject = admin; } { domain = "bazarr.nordhammer.it"; policy = "one_factor"; subject = admin; } { domain = "prowlarr.nordhammer.it"; policy = "one_factor"; subject = admin; } { domain = "torrent.nordhammer.it"; policy = "one_factor"; subject = admin; } { domain = "profilarr.nordhammer.it"; policy = "one_factor"; subject = admin; } { domain = "shelfarr.nordhammer.it"; policy = "one_factor"; subject = admin; } { domain = "sabnzbd.nordhammer.it"; policy = "one_factor"; subject = admin; } { domain = "code.nordhammer.it"; policy = "one_factor"; subject = admin; } { domain = "reddit.nordhammer.it"; policy = "one_factor"; subject = household; } { domain = "panel.nordhammer.it"; policy = "one_factor"; subject = admin; } { domain = "stardew.nordhammer.it"; policy = "one_factor"; subject = household; } { domain = "guildhall.nordhammer.it"; policy = "one_factor"; } # Health data: only the two people the app knows about. { domain = "flowtrack.nordhammer.it"; policy = "one_factor"; subject = [ "user:kayla" "user:fred" ]; } ]; }; session = { cookies = [{ domain = "nordhammer.it"; authelia_url = "https://auth.nordhammer.it"; }]; # Long enough that the home-screen Flowtrack app on a phone does not # ask for a login every time it opens. expiration = "30d"; inactivity = "7d"; }; storage.local.path = "/var/lib/authelia-main/db.sqlite3"; notifier.filesystem.filename = "/var/lib/authelia-main/notification.txt"; }; }; # First, before the module's validate-config pre-start. systemd.services.authelia-main.serviceConfig.ExecStartPre = lib.mkBefore [ "+${prepareUsers}" ]; }; }