{ config, lib, ... }: let authelia = "authelia-procopius"; in { networking.firewall.allowedTCPPorts = [ 9091 ]; services = { authelia.instances.procopius = { enable = true; settings = { theme = "auto"; server = { buffers = { read = 16384; write = 16384; }; }; authentication_backend.ldap = { implementation = "lldap"; address = "ldap://localhost:3890"; base_dn = "dc=procopius,dc=dk"; user = "uid=authelia,ou=people,dc=procopius,dc=dk"; }; definitions = { network = { internal = [ "192.168.1.0/24" ]; }; }; access_control = { default_policy = "deny"; # We want this rule to be low priority so it doesn't override the others rules = lib.mkAfter [ { domain = [ "proxmox.procopius.dk" "traefik.procopius.dk" "prometheus.procopius.dk" "alertmanager.procopius.dk" ]; policy = "one_factor"; subject = [ ["group:server-admin"] ]; } # bypass /api and /ping { domain = ["*.procopius.dk"]; policy = "bypass"; resources = [ "^/api$" "^/api/" "^/ping$" ]; } # media { domain = [ "sonarr.procopius.dk" "radarr.procopius.dk" "readarr.procopius.dk" "lidarr.procopius.dk" "bazarr.procopius.dk" "prowlarr.procopius.dk" ]; policy = "one_factor"; subject = [ ["group:media-admin"] ]; } # authenticated { domain = [ "gatus.procopius.dk" ]; policy = "one_factor"; } # bypass auth internally # { # domain = [ # "gatus.procopius.dk" # "prometheus.procopius.dk" # "alertmanager.procopius.dk" # "sonarr.procopius.dk" # "radarr.procopius.dk" # "readarr.procopius.dk" # "lidarr.procopius.dk" # "bazarr.procopius.dk" # "prowlarr.procopius.dk" # ]; # policy = "bypass"; # networks = [ # "internal" # ]; # } ]; }; storage.postgres = { address = "unix:///run/postgresql"; database = authelia; username = authelia; # I'm using peer authentication, so this doesn't actually matter, but Authelia # complains if I don't have it. # https://github.com/authelia/authelia/discussions/7646 password = authelia; }; session = { redis.host = "/var/run/redis-procopius/redis.sock"; cookies = [ { domain = "procopius.dk"; authelia_url = "https://authelia.procopius.dk"; # The period of time the user can be inactive for before the session is destroyed inactivity = "1M"; # The period of time before the cookie expires and the session is destroyed expiration = "3M"; # The period of time before the cookie expires and the session is destroyed # when the remember me box is checked remember_me = "1y"; } ]; }; notifier.smtp = { address = "smtp://mail.procopius.dk"; username = "authelia@procopius.dk"; sender = "authelia@procopius.dk"; }; log.level = "info"; # identity_providers.oidc = { # # https://www.authelia.com/integration/openid-connect/openid-connect-1.0-claims/#restore-functionality-prior-to-claims-parameter # claims_policies = { # # karakeep.id_token = ["email"]; # }; # cors = { # endpoints = ["token"]; # allowed_origins_from_client_redirect_uris = true; # }; # authorization_policies.default = { # default_policy = "one_factor"; # rules = [ # { # policy = "deny"; # subject = "group:lldap_strict_readonly"; # } # ]; # }; # }; # Necessary for Traefik integration # See https://www.authelia.com/integration/proxies/traefik/#implementation server.endpoints.authz.forward-auth.implementation = "ForwardAuth"; }; # Templates don't work correctly when parsed from Nix, so our OIDC clients are defined here # settingsFiles = [./oidc_clients.yaml]; secrets = with config.sops; { jwtSecretFile = secrets."authelia/jwt_secret".path; # oidcIssuerPrivateKeyFile = secrets."authelia/jwks".path; # oidcHmacSecretFile = secrets."authelia/hmac_secret".path; sessionSecretFile = secrets."authelia/session_secret".path; storageEncryptionKeyFile = secrets."authelia/storage_encryption_key".path; }; environmentVariables = with config.sops; { AUTHELIA_AUTHENTICATION_BACKEND_LDAP_PASSWORD_FILE = secrets."authelia/lldap_authelia_password".path; AUTHELIA_NOTIFIER_SMTP_PASSWORD_FILE = secrets.smtp-password_authelia.path; }; }; }; # Give Authelia access to the Redis socket users.users.${authelia}.extraGroups = ["redis-procopius"]; systemd.services.${authelia} = let dependencies = [ "lldap.service" "postgresql.service" "redis-procopius.service" ]; in { # Authelia requires LLDAP, PostgreSQL, and Redis to be running after = dependencies; requires = dependencies; # Required for templating serviceConfig.Environment = "X_AUTHELIA_CONFIG_FILTERS=template"; }; sops.secrets = { "authelia/hmac_secret".owner = authelia; "authelia/jwks".owner = authelia; "authelia/jwt_secret".owner = authelia; "authelia/session_secret".owner = authelia; "authelia/storage_encryption_key".owner = authelia; # The password for the `authelia` LLDAP user "authelia/lldap_authelia_password".owner = authelia; smtp-password_authelia = { owner = authelia; key = "service_accounts/authelia/password"; }; }; }