9 cfg = config.services.authelia;
11 format = pkgs.formats.yaml { };
18 enable = mkEnableOption "Authelia instance";
24 Name is used as a suffix for the service name, user, and group.
25 By default it takes the value you use for `<instance>` in:
26 {option}`services.authelia.<instance>`
30 package = mkPackageOption pkgs "authelia" { };
33 default = "authelia-${name}";
35 description = "The name of the user for this authelia instance.";
39 default = "authelia-${name}";
41 description = "The name of the group for this authelia instance.";
46 It is recommended you keep your secrets separate from the configuration.
47 It's especially important to keep the raw secrets out of your nix configuration,
48 as the values will be preserved in your nix store.
49 This attribute allows you to configure the location of secret files to be loaded at runtime.
51 https://www.authelia.com/configuration/methods/secrets/
54 type = types.submodule {
60 Configuring authelia's secret files via the secrets attribute set
61 is intended to be convenient and help catch cases where values are required
63 If a user wants to set these values themselves and bypass the validation they can set this value to true.
69 jwtSecretFile = mkOption {
70 type = types.nullOr types.path;
73 Path to your JWT secret used during identity verificaton.
77 oidcIssuerPrivateKeyFile = mkOption {
78 type = types.nullOr types.path;
81 Path to your private key file used to encrypt OIDC JWTs.
85 oidcHmacSecretFile = mkOption {
86 type = types.nullOr types.path;
89 Path to your HMAC secret used to sign OIDC JWTs.
93 sessionSecretFile = mkOption {
94 type = types.nullOr types.path;
97 Path to your session secret. Only used when redis is used as session storage.
102 storageEncryptionKeyFile = mkOption {
103 type = types.nullOr types.path;
106 Path to your storage encryption key.
113 environmentVariables = mkOption {
114 type = types.attrsOf types.str;
116 Additional environment variables to provide to authelia.
117 If you are providing secrets please consider the options under {option}`services.authelia.<instance>.secrets`
118 or make sure you use the `_FILE` suffix.
119 If you provide the raw secret rather than the location of a secret file that secret will be preserved in the nix store.
120 For more details: https://www.authelia.com/configuration/methods/secrets/
125 settings = mkOption {
127 Your Authelia config.yml as a Nix attribute set.
128 There are several values that are defined and documented in nix such as `default_2fa_method`,
129 but additional items can also be included.
131 https://github.com/authelia/authelia/blob/master/config.template.yml
137 default_2fa_method = "totp";
139 server.disable_healthcheck = true;
142 type = types.submodule {
143 freeformType = format.type;
154 description = "The theme to display.";
157 default_2fa_method = mkOption {
165 example = "webauthn";
167 Default 2FA method for new users and fallback for preferred but disabled methods.
174 default = "tcp://:9091/";
175 example = "unix:///var/run/authelia.sock?path=authelia&umask=0117";
176 description = "The address to listen on.";
191 description = "Level of verbosity for logs.";
201 description = "Format the logs are written as.";
204 file_path = mkOption {
205 type = types.nullOr types.path;
207 example = "/var/log/authelia/authelia.log";
208 description = "File path where the logs will be written. If not set logs are written to stdout.";
211 keep_stdout = mkOption {
215 description = "Whether to also log to stdout when a `file_path` is defined.";
225 description = "Enable Metrics.";
230 default = "tcp://127.0.0.1:9959";
231 example = "tcp://0.0.0.0:8888";
232 description = "The address to listen on for metrics. This should be on a different port to the main `server.port` value.";
240 settingsFiles = mkOption {
241 type = types.listOf types.path;
244 "/etc/authelia/config.yml"
245 "/etc/authelia/access-control.yml"
246 "/etc/authelia/config/"
249 Here you can provide authelia with configuration files or directories.
250 It is possible to give authelia multiple files and use the nix generated configuration
251 file set via {option}`services.authelia.<instance>.settings`.
257 writeOidcJwksConfigFile =
258 oidcIssuerPrivateKeyFile:
259 pkgs.writeText "oidc-jwks.yaml" ''
263 - key: {{ secret "${oidcIssuerPrivateKeyFile}" | mindent 10 "|" | msquote }}
266 # Remove an attribute in a nested set
267 # https://discourse.nixos.org/t/modify-an-attrset-in-nix/29919/5
270 lib.updateManyAttrsByPath [
272 path = lib.init pathList;
273 update = old: lib.filterAttrs (n: v: n != (lib.last pathList)) old;
278 options.services.authelia.instances =
282 type = types.attrsOf (types.submodule autheliaOpts);
284 Multi-domain protection currently requires multiple instances of Authelia.
285 If you don't require multiple instances of Authelia you can define just the one.
287 https://www.authelia.com/roadmap/active/multi-domain-protection/
293 secrets.storageEncryptionKeyFile = "/etc/authelia/storageEncryptionKeyFile";
294 secrets.jwtSecretFile = "/etc/authelia/jwtSecretFile";
297 default_2fa_method = "totp";
299 server.disable_healthcheck = true;
304 secrets.storageEncryptionKeyFile = "/mnt/pre-prod/authelia/storageEncryptionKeyFile";
305 secrets.jwtSecretFile = "/mnt/pre-prod/jwtSecretFile";
308 default_2fa_method = "webauthn";
309 server.host = "0.0.0.0";
313 test.secrets.manual = true;
314 test.settings.theme = "grey";
315 test.settings.server.disable_healthcheck = true;
316 test.settingsFiles = [ "/mnt/test/authelia" "/mnt/test-authelia.conf" ];
324 mkInstanceServiceConfig =
330 instance.settings.server ? host
331 || instance.settings.server ? port
332 || instance.settings.server ? path
335 # Old settings are used: display a warning and remove the default value of server.address
336 # as authelia does not allow both old and new settings to be set
338 "Please replace services.authelia.instances.${instance.name}.settings.{host,port,path} with services.authelia.instances.${instance.name}.settings.address, before release 5.0.0"
340 removeAttrByPath instance.settings [
348 execCommand = "${instance.package}/bin/authelia";
349 configFile = format.generate "config.yml" cleanedSettings;
350 oidcJwksConfigFile = lib.optional (instance.secrets.oidcIssuerPrivateKeyFile != null) (
351 writeOidcJwksConfigFile instance.secrets.oidcIssuerPrivateKeyFile
353 configArg = "--config ${
354 builtins.concatStringsSep "," (
357 instance.settingsFiles
364 description = "Authelia authentication and authorization server";
365 wantedBy = [ "multi-user.target" ];
366 after = [ "network-online.target" ]; # Checks SMTP notifier creds during startup
367 wants = [ "network-online.target" ];
369 (lib.filterAttrs (_: v: v != null) {
370 X_AUTHELIA_CONFIG_FILTERS = lib.mkIf (oidcJwksConfigFile != [ ]) "template";
371 AUTHELIA_IDENTITY_VALIDATION_RESET_PASSWORD_JWT_SECRET_FILE = instance.secrets.jwtSecretFile;
372 AUTHELIA_STORAGE_ENCRYPTION_KEY_FILE = instance.secrets.storageEncryptionKeyFile;
373 AUTHELIA_SESSION_SECRET_FILE = instance.secrets.sessionSecretFile;
374 AUTHELIA_IDENTITY_PROVIDERS_OIDC_HMAC_SECRET_FILE = instance.secrets.oidcHmacSecretFile;
376 // instance.environmentVariables;
378 preStart = "${execCommand} ${configArg} validate-config";
380 User = instance.user;
381 Group = instance.group;
382 ExecStart = "${execCommand} ${configArg}";
385 StateDirectory = "authelia-${instance.name}";
386 StateDirectoryMode = "0700";
389 AmbientCapabilities = "";
390 CapabilityBoundingSet = "";
392 LockPersonality = true;
393 MemoryDenyWriteExecute = true;
394 NoNewPrivileges = true;
397 PrivateDevices = true;
401 ProtectControlGroups = true;
402 ProtectHome = "read-only";
403 ProtectHostname = true;
404 ProtectKernelLogs = true;
405 ProtectKernelModules = true;
406 ProtectKernelTunables = true;
407 ProtectProc = "noaccess";
408 ProtectSystem = "strict";
410 RestrictAddressFamilies = [
415 RestrictNamespaces = true;
416 RestrictRealtime = true;
417 RestrictSUIDSGID = true;
419 SystemCallArchitectures = "native";
420 SystemCallErrorNumber = "EPERM";
433 mkInstanceUsersConfig = instance: {
434 groups."authelia-${instance.name}" = lib.mkIf (instance.group == "authelia-${instance.name}") {
435 name = "authelia-${instance.name}";
437 users."authelia-${instance.name}" = lib.mkIf (instance.user == "authelia-${instance.name}") {
438 name = "authelia-${instance.name}";
440 group = instance.group;
443 instances = lib.attrValues cfg.instances;
446 assertions = lib.flatten (
447 lib.flip lib.mapAttrsToList cfg.instances (
451 instance.secrets.manual
452 || (instance.secrets.jwtSecretFile != null && instance.secrets.storageEncryptionKeyFile != null);
454 Authelia requires a JWT Secret and a Storage Encryption Key to work.
455 Either set them like so:
456 services.authelia.${name}.secrets.jwtSecretFile = /my/path/to/jwtsecret;
457 services.authelia.${name}.secrets.storageEncryptionKeyFile = /my/path/to/encryptionkey;
458 Or set services.authelia.${name}.secrets.manual = true and provide them yourself via
459 environmentVariables or settingsFiles.
460 Do not include raw secrets in nix settings.
467 systemd.services = lib.mkMerge (
470 lib.mkIf instance.enable {
471 "authelia-${instance.name}" = mkInstanceServiceConfig instance;
475 users = lib.mkMerge (
476 map (instance: lib.mkIf instance.enable (mkInstanceUsersConfig instance)) instances