{ pkgs, inputs, lib, config, ... }: with lib; let cfg = config.xyno.services.authentik; defaultAppOptions = { options = { name = mkOption { type = types.str; }; group = mkOption { type = types.nullOr types.str; default = null; }; groups = mkOption { type = types.listOf types.str; default = []; }; meta_description = mkOption { type = types.nullOr types.str; default = null; }; meta_icon = mkOption { type = types.nullOr types.str; default = null; }; meta_launch_url = mkOption { type = types.nullOr types.str; default = null; }; meta_publisher = mkOption { type = types.nullOr types.str; default = null; }; }; }; terrraformStateDir = "/var/lib/authentik-terraform-config"; environmentFileDir = "/run/authentik-terraform-config"; terranixConfig = inputs.terranix.lib.terranixConfiguration { system = pkgs.system; modules = [ ./authentik/provider.nix { inherit (cfg) oauthApps ldapApps proxyApps; stateFile = "${terrraformStateDir}/state.tfstate"; } ]; }; in { options.xyno.services.authentik.enable = mkEnableOption "enables the authentik SSO thing"; options.xyno.services.authentik.oauthApps = mkOption { default = { }; type = types.attrsOf ( types.submodule ( { name, ... }: ({ options = { environmentFile = mkOption { type = types.str; default = "${environmentFileDir}/${name}_environment"; }; } // defaultAppOptions.options; }) ) ); }; options.xyno.services.authentik.ldapApps = mkOption { default = { }; type = types.attrsOf (types.submodule (defaultAppOptions)); }; options.xyno.services.authentik.proxyApps = mkOption { default = { }; type = types.attrsOf ( types.submodule ({ options = { externalHost = mkOption { type = types.str; }; } // defaultAppOptions.options; }) ); }; config = lib.mkIf cfg.enable { environment.etc."authentik-config/config.tf.json".source = terranixConfig; xyno.impermanence.directories = [ terrraformStateDir ]; services.authentik = { enable = true; createDatabase = true; environmentFile = config.sops.secrets."authentik/env".path; }; systemd.services.authentik-ldap.after = [ "authentik-config.service" ]; services.authentik-ldap = { environmentFile = "${environmentFileDir}/ldap_config"; enable = true; }; systemd.services.authentik-proxy.after = [ "authentik-config.service" ]; services.authentik-proxy = { enable = true; environmentFile = "${environmentFileDir}/proxy_config"; }; systemd.services.authentik-config = { after = [ "authentik.service" ]; serviceConfig = { Type = "oneshot"; RemainAfterExit = true; StateDirectory = terrraformStateDir; }; script = '' umask u=rw,go= export PATH=$PATH:${pkgs.opentofu}/bin cd terrraformStateDir cp ${terranixConfig} ./main.tf.json source ${config.services.authentik.environmentFile} export AUTHENTIK_URL=http://localhost:9000 export AUTHENTIK_TOKEN=$AUTHENTIK_BOOTSTRAP_TOKEN tofu init tofu validate || exit 1 tofu apply tofu output -raw proxy_config > ${environmentFileDir}/proxy_config tofu output -raw ldap_config > ${environmentFileDir}/ldap_config ${concatStringsSep "\n" ( mapAttrsToList (n: v: "tofu output -raw ${n}_environment > ${v.environmentFile}") cfg.oauthApps )} ''; }; sops.secrets."authentik/env" = { }; services.caddy.extraConfig = '' (reverse_proxy_auth) { route { # always forward outpost path to actual outpost reverse_proxy /outpost.goauthentik.io/* http://[::1]:9000 { } forward_auth http://[::1]:9000 { uri /outpost.goauthentik.io/auth/caddy copy_headers X-Authentik-Username X-Copyparty-Group X-Authentik-Groups X-Authentik-Entitlements X-Authentik-Email X-Authentik-Name X-Authentik-Uid X-Authentik-Jwt X-Authentik-Meta-Jwks X-Authentik-Meta-Outpost X-Authentik-Meta-Provider X-Authentik-Meta-App X-Authentik-Meta-Version X-Grafana-Role } reverse_proxy {args[:]} } ''; }; }