{ config, lib, masterDomain, securityTemplates, ... }: let cfg = config.os.srv.authelia; computedBaseDN = lib.concatStringsSep "," ( map (domainPart: "dc=${domainPart}") (lib.splitString "." masterDomain) ); in { options.os.srv.authelia.enable = lib.mkEnableOption "enables authelia authentication gateway instance"; config = lib.mkIf cfg.enable { assertions = [ { assertion = config.os.srv.sops.enable; message = "sops must be enabled for secure cryptographic token storage"; } { assertion = config.os.core.network.enableFirewall; message = "Requires firewall"; } ]; sops.secrets = { "authelia/jwt_secret" = { owner = "authelia-main"; group = "authelia-main"; restartUnits = [ "authelia-main.service" ]; }; "authelia/session_secret" = { owner = "authelia-main"; group = "authelia-main"; restartUnits = [ "authelia-main.service" ]; }; "authelia/encryption_key" = { owner = "authelia-main"; group = "authelia-main"; restartUnits = [ "authelia-main.service" ]; }; "authelia/oidc_hmac" = { owner = "authelia-main"; group = "authelia-main"; restartUnits = [ "authelia-main.service" ]; }; "authelia/oidc_private_key" = { owner = "authelia-main"; group = "authelia-main"; restartUnits = [ "authelia-main.service" ]; }; "postgres/authelia_password" = { owner = "authelia-main"; group = "authelia-main"; restartUnits = [ "authelia-main.service" ]; }; "redis/password" = { owner = "authelia-main"; group = "authelia-main"; restartUnits = [ "authelia-main.service" ]; }; }; services.authelia.instances.main = { enable = true; secrets = { jwtSecretFile = config.sops.secrets."authelia/jwt_secret".path; sessionSecretFile = config.sops.secrets."authelia/session_secret".path; storageEncryptionKeyFile = config.sops.secrets."authelia/encryption_key".path; oidcHmacSecretFile = config.sops.secrets."authelia/oidc_hmac".path; oidcIssuerPrivateKeyFile = config.sops.secrets."authelia/oidc_private_key".path; }; settings = { theme = "dark"; default_2fa_method = "totp"; log = { level = "info"; format = "json"; path = "/var/log/authelia/authelia.log"; keep_stdout = true; }; server.address = "tcp://127.0.0.1:9091"; telemetry.metrics = { enabled = true; address = "tcp://127.0.0.1:9959"; }; storage = { postgres = { host = config.os.core.network.ips.database-vm; port = 5432; database = "authelia"; username = "authelia"; timeout = "5s"; schema = "public"; }; }; session = { name = "authelia_session"; expiration = "1h"; inactivity = "15m"; remember_me = "1M"; provider = { redis = { host = config.os.core.network.ips.database-vm; port = 6379; database = 0; timeout = "5s"; }; }; }; authentication_backend = { ldap = { address = "ldap://${config.os.core.network.ips.gateway-vm}:3890"; implementation = "lldap"; base_dn = computedBaseDN; user = "uid=authelia,ou=people,${computedBaseDN}"; }; }; identity_providers = { oidc = { cors.allowed_origins = map (domain: "https://${domain}") ( builtins.attrNames config.os.cluster.nginxProxies ); clients = config.os.cluster.oidcClients; }; }; access_control = { default_policy = "deny"; rules = [ { domain = "auth.${masterDomain}"; policy = "bypass"; } ] ++ config.os.cluster.autheliaRules; }; session.domain = masterDomain; }; environmentVariables = { AUTHELIA_AUTHENTICATION_BACKEND_LDAP_PASSWORD_FILE = config.sops.secrets."lldap/password".path; AUTHELIA_SESSION_REDIS_PASSWORD_FILE = config.sops.secrets."redis/password".path; AUTHELIA_STORAGE_POSTGRES_PASSWORD_FILE = config.sops.secrets."postreg/authelia_password".path; }; }; os.cluster.nginxProxies."auth.${masterDomain}" = { enableACME = true; forceSSL = true; locations."/" = { proxyPass = "http://${config.os.core.network.ips.gateway-vm}:9091"; extraConfig = securityTemplates.restrictToInternal; }; }; networking.firewall.extraInputRules = '' ip saddr ${config.os.core.network.ips.monitor-vm} tcp dport 9959 accept ''; }; }