From 039fcdfd00cb0daaa8024f25e05c0063ff62f835 Mon Sep 17 00:00:00 2001 From: Maximilian Bosch Date: Tue, 16 Sep 2025 11:32:11 +0200 Subject: [PATCH 1/6] module: replace requiredBy with inverse requires IMHO that way it's easier to reason about what relationship exists here. --- module.nix | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/module.nix b/module.nix index 07ec79f..2104552 100644 --- a/module.nix +++ b/module.nix @@ -263,7 +263,6 @@ in systemd.services = { authentik-migrate = { - requiredBy = [ "authentik.service" ]; requires = lib.optionals cfg.createDatabase [ "postgresql.service" ]; wants = [ "network-online.target" ]; after = [ "network-online.target" ] ++ lib.optionals cfg.createDatabase [ "postgresql.service" ]; @@ -289,7 +288,6 @@ in ]; }; authentik-worker = { - requiredBy = [ "authentik.service" ]; wants = [ "network-online.target" ]; after = [ "network-online.target" ]; before = [ "authentik.service" ]; @@ -318,6 +316,10 @@ in authentik = { wantedBy = [ "multi-user.target" ]; wants = [ "network-online.target" ]; + requires = [ + "authentik-migrate.service" + "authentik-worker.service" + ]; after = [ "network-online.target" "redis-authentik.service" From 1c79d48248f01d7bb4ec36345334f162574aa2eb Mon Sep 17 00:00:00 2001 From: Maximilian Bosch Date: Wed, 17 Sep 2025 10:11:39 +0200 Subject: [PATCH 2/6] module: run migrations before attempting to start worker `manage.py` attempts migrations on its own[1], so try let's try to prevent another potential for races. [1] https://github.com/goauthentik/authentik/blob/version/2025.8.3/manage.py#L17-L24 --- module.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module.nix b/module.nix index 2104552..2e76d69 100644 --- a/module.nix +++ b/module.nix @@ -266,7 +266,7 @@ in requires = lib.optionals cfg.createDatabase [ "postgresql.service" ]; wants = [ "network-online.target" ]; after = [ "network-online.target" ] ++ lib.optionals cfg.createDatabase [ "postgresql.service" ]; - before = [ "authentik.service" ]; + before = [ "authentik.service" "authentik-migrate.service" ]; restartTriggers = [ config.environment.etc."authentik/config.yml".source ]; environment = mkMerge [ environment { TZ = tz; } ]; serviceConfig = mkMerge [ From 6a080328a3a79b7115f67df068cb86e6ea84212f Mon Sep 17 00:00:00 2001 From: Maximilian Bosch Date: Wed, 17 Sep 2025 10:16:05 +0200 Subject: [PATCH 3/6] module: override metrics & http address for worker Closes #72 So, #72 is about a segfault in the LDAP outpost, but this is the actual culprit[0]: * Both server & worker share the same configuration in this setup. * Since 2025.8 this means that both try to start a server for metrics at port 9300 and an HTTP server (in the worker case for healthchecks) at port 9000. * On upgrades, migrations are performed. Only the server waited for the migrations to finish, hence the worker started up earlier. As a result, it was quicker in binding port 9000 in ONLY this case (and thus, this was never reproducible on a second attempt!). Now, on port 9000 was NOT the authentik server, but something that returned an empty response for everything that's not the healthcheck. * As a result, the LDAP outpost got a response from what it believed was authentik, but actually `nil, nil` because of the empty response. Trying to dereference values from that response[1] caused the segfault. The fix is pretty easy, just override the listen ports via the environment. Unfortunately, the docs[2] are apparently not entirely correct[3], given the Python code it must be LISTEN__LISTEN_HTTP[4]. I added a test-case to ensure that the config is properly applied. [0] Reported as https://github.com/goauthentik/authentik/issues/16850 [1] https://github.com/goauthentik/authentik/blob/57e12cef068d655e3d55c7befd401c7e36f024b3/internal/outpost/ak/api.go#L95 [2] https://docs.goauthentik.io/install-config/configuration/#listen-settings [3] Reported as https://github.com/goauthentik/authentik/issues/16851 [4] https://github.com/goauthentik/authentik/blob/57e12cef068d655e3d55c7befd401c7e36f024b3/authentik/lib/config.py#L238 --- module.nix | 28 +++++++++++++++++++++++++++- tests/minimal-vmtest.nix | 7 +++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/module.nix b/module.nix index 2e76d69..b8c38cb 100644 --- a/module.nix +++ b/module.nix @@ -103,6 +103,25 @@ in ``` ''; }; + + worker = { + listenHTTP = mkOption { + type = types.str; + default = "[::1]:9001"; + description = '' + Listen address for the HTTP server of the worker. + Overrides the default listen setting that's also used by the server. + ''; + }; + listenMetrics = mkOption { + type = types.str; + default = "[::1]:9301"; + description = '' + Listen address for the metrics server of the worker. + Overrides the default listen setting that's also used by the server. + ''; + }; + }; }; # LDAP oupost @@ -295,7 +314,14 @@ in preStart = '' ln -svf ${config.services.authentik.authentikComponents.staticWorkdirDeps}/* /run/authentik/ ''; - environment = mkMerge [ environment { TZ = tz; } ]; + environment = mkMerge [ + environment + { + TZ = tz; + AUTHENTIK_LISTEN__LISTEN_HTTP = cfg.worker.listenHTTP; + AUTHENTIK_LISTEN__LISTEN_METRICS = cfg.worker.listenMetrics; + } + ]; serviceConfig = mkMerge [ serviceDefaults { diff --git a/tests/minimal-vmtest.nix b/tests/minimal-vmtest.nix index dfb7c52..12c35df 100644 --- a/tests/minimal-vmtest.nix +++ b/tests/minimal-vmtest.nix @@ -91,5 +91,12 @@ pkgs.nixosTest { machine.succeed("su - alice -c 'firefox http://localhost/' >&2 &") machine.wait_for_text("authentik") machine.screenshot("5_nginx_proxies_requests") + + with subtest("metrics & worker"): + machine.wait_for_open_port(9300) + machine.wait_for_open_port(9301) + + print(machine.succeed("curl -L localhost:9300/metrics | grep authentik_outpost_connection | grep 'Embedded'")) + print(machine.succeed("curl -L localhost:9301/metrics | grep authentik_tasks_total")) ''; } From 15d4d6f9fc7ac7911e3f3b941ab0ae0663126d80 Mon Sep 17 00:00:00 2001 From: Maximilian Bosch Date: Wed, 17 Sep 2025 10:22:14 +0200 Subject: [PATCH 4/6] module: fmt --- module.nix | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/module.nix b/module.nix index b8c38cb..58cd60d 100644 --- a/module.nix +++ b/module.nix @@ -287,7 +287,10 @@ in after = [ "network-online.target" ] ++ lib.optionals cfg.createDatabase [ "postgresql.service" ]; before = [ "authentik.service" "authentik-migrate.service" ]; restartTriggers = [ config.environment.etc."authentik/config.yml".source ]; - environment = mkMerge [ environment { TZ = tz; } ]; + environment = mkMerge [ + environment + { TZ = tz; } + ]; serviceConfig = mkMerge [ serviceDefaults { @@ -349,7 +352,8 @@ in after = [ "network-online.target" "redis-authentik.service" - ] ++ (lib.optionals cfg.createDatabase [ "postgresql.service" ]); + ] + ++ (lib.optionals cfg.createDatabase [ "postgresql.service" ]); restartTriggers = [ config.environment.etc."authentik/config.yml".source ]; preStart = '' ln -svf ${cfg.authentikComponents.staticWorkdirDeps}/* /var/lib/authentik/ @@ -357,7 +361,10 @@ in mkdir -p ${cfg.settings.storage.media.file.path} ''} ''; - environment = mkMerge [ environment { TZ = tz; } ]; + environment = mkMerge [ + environment + { TZ = tz; } + ]; serviceConfig = mkMerge [ serviceDefaults { From 0c6391c85e88ef8dd050bca811c1436d523b0fe3 Mon Sep 17 00:00:00 2001 From: Maximilian Bosch Date: Wed, 17 Sep 2025 10:27:14 +0200 Subject: [PATCH 5/6] module: also use non-conflicting ports for other outposts Incidentally I had parts of that already in my private config and immediately forgot. But now that we're at it, let's fix it up properly as well. --- module.nix | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/module.nix b/module.nix index 58cd60d..39620d0 100644 --- a/module.nix +++ b/module.nix @@ -128,6 +128,15 @@ in authentik-ldap = { enable = mkEnableOption "authentik LDAP outpost"; + listenMetrics = mkOption { + type = types.str; + default = "[::1]:9302"; + description = '' + Listen address for the metrics server of the LDAP outpost. + Overrides the default listen setting that's also used by the server. + ''; + }; + environmentFile = mkOption { type = types.nullOr pathToSecret; default = null; @@ -151,6 +160,31 @@ in authentik-proxy = { enable = mkEnableOption "authentik Proxy outpost"; + listenMetrics = mkOption { + type = types.str; + default = "[::1]:9303"; + description = '' + Listen address for the metrics server of the proxy outpost. + Overrides the default listen setting that's also used by the server. + ''; + }; + listenHTTPS = mkOption { + type = types.str; + default = "[::1]:9004"; + description = '' + Listen address for the HTTPS server of the proxy outpost. + Overrides the default listen setting that's also used by the server. + ''; + }; + listenHTTP = mkOption { + type = types.str; + default = "[::1]:9005"; + description = '' + Listen address for the HTTP server of the proxy outpost. + Overrides the default listen setting that's also used by the server. + ''; + }; + environmentFile = mkOption { type = types.nullOr pathToSecret; default = null; @@ -174,6 +208,15 @@ in authentik-radius = { enable = mkEnableOption "authentik RADIUS outpost"; + listenMetrics = mkOption { + type = types.str; + default = "[::1]:9306"; + description = '' + Listen address for the metrics server of the RADIUS outpost. + Overrides the default listen setting that's also used by the server. + ''; + }; + environmentFile = mkOption { type = types.nullOr pathToSecret; default = null; @@ -409,6 +452,7 @@ in "network-online.target" "authentik.service" ]; + environment.AUTHENTIK_LISTEN__METRICS = cfg.listenMetrics; serviceConfig = { RuntimeDirectory = "authentik-ldap"; UMask = "0027"; @@ -435,6 +479,11 @@ in "network-online.target" "authentik.service" ]; + environment = { + AUTHENTIK_LISTEN__METRICS = cfg.listenMetrics; + AUTHENTIK_LISTEN__HTTP = cfg.listenHTTP; + AUTHENTIK_LISTEN__HTTPS = cfg.listenHTTPS; + }; serviceConfig = { RuntimeDirectory = "authentik-proxy"; UMask = "0027"; @@ -461,6 +510,7 @@ in "network-online.target" "authentik.service" ]; + environment.AUTHENTIK_LISTEN__METRICS = cfg.listenMetrics; serviceConfig = { RuntimeDirectory = "authentik-radius"; UMask = "0027"; From c7ed264bc4240488808ef4f38acee82d3ec582ec Mon Sep 17 00:00:00 2001 From: Maximilian Bosch Date: Wed, 17 Sep 2025 10:38:12 +0200 Subject: [PATCH 6/6] update: 2025.8.2 -> 2025.8.3 ChangeLog: https://github.com/goauthentik/authentik/releases/tag/version%2F2025.8.3 --- flake.lock | 8 ++++---- flake.nix | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/flake.lock b/flake.lock index 60b3187..0694271 100644 --- a/flake.lock +++ b/flake.lock @@ -3,16 +3,16 @@ "authentik-src": { "flake": false, "locked": { - "lastModified": 1757951234, - "narHash": "sha256-4RU/mllgqoykXqeO67iodmhsgIrJqow0LitaQGLKS8Q=", + "lastModified": 1758035356, + "narHash": "sha256-DkvxDwHCfSqEpZ9rRXNR8MP0Mz/y1kHAr38exrHQ39c=", "owner": "goauthentik", "repo": "authentik", - "rev": "28ff5614006ceea21b2633da8c675eb75c6bacdd", + "rev": "680feaefa17934471a6b33ebc35caf5b64120404", "type": "github" }, "original": { "owner": "goauthentik", - "ref": "version/2025.8.2", + "ref": "version/2025.8.3", "repo": "authentik", "type": "github" } diff --git a/flake.nix b/flake.nix index 3821f73..8d7627d 100644 --- a/flake.nix +++ b/flake.nix @@ -42,7 +42,7 @@ }; authentik-src = { # change version string in outputs as well when updating - url = "github:goauthentik/authentik/version/2025.8.2"; + url = "github:goauthentik/authentik/version/2025.8.3"; flake = false; }; }; @@ -67,7 +67,7 @@ ... }: let - authentik-version = "2025.8.2"; # to pass to the drvs of some components + authentik-version = "2025.8.3"; # to pass to the drvs of some components in { systems = import inputs.systems;