From 47cfd980fab454a836dfbc99512bdb3ee574a658 Mon Sep 17 00:00:00 2001 From: Erich Blume Date: Sun, 1 Mar 2026 12:11:50 -0800 Subject: [PATCH] C2(authentik-source-build): impl Go server derivation buildGoModule derivation for cmd/server with: - apiGoVendorHook for generated Go API client injection - substituteInPlace patches for lifecycle (authentik-django) and web asset paths (3 files: gounicorn.go, web/static.go, internal/web/static.go) - overrideModAttrs.postPatch="" to keep vendorHash stable - Parameterized webui input with placeholder for pre-webui-derivation builds - CGO_ENABLED=0, binary renamed from server to authentik - Verified on ringtail: builds in ~32s, --help works Co-Authored-By: Claude Opus 4.6 --- containers/authentik/authentik-server.nix | 64 +++++++++++++++++++++++ containers/authentik/test-build.nix | 2 + 2 files changed, 66 insertions(+) create mode 100644 containers/authentik/authentik-server.nix diff --git a/containers/authentik/authentik-server.nix b/containers/authentik/authentik-server.nix new file mode 100644 index 0000000..a99d9f8 --- /dev/null +++ b/containers/authentik/authentik-server.nix @@ -0,0 +1,64 @@ +# Authentik Go HTTP server binary +# +# Builds cmd/server from the authentik source using buildGoModule. +# The compiled binary serves the web UI, REST API, spawns gunicorn +# for the Django backend, and runs the embedded reverse proxy outpost. +# +# Two runtime path dependencies are baked in at compile time: +# - authentik-django: lifecycle scripts (gunicorn launcher) +# - webui: static web assets (dist/ and authentik/ directories) +# +# The apiGoVendorHook replaces vendored goauthentik.io/api/v3 with +# freshly generated client-go output, but only during the real build +# (not the FOD module-download phase), so vendorHash stays stable. +# +# Output: $out/bin/authentik +{ pkgs ? import { } +, sources ? import ./sources.nix { inherit pkgs; } +, authentik-django ? import ./authentik-django.nix { inherit pkgs sources; } +, webui ? null +}: + +let + apiGoVendorHook = import ./api-go-vendor-hook.nix { inherit pkgs sources; }; + + # Web assets path: use real webui derivation if provided, otherwise + # a placeholder directory. The placeholder allows the binary to compile + # and pass --help verification, but web serving won't work at runtime. + webAssetsPath = + if webui != null then webui + else pkgs.runCommand "webui-placeholder" { } '' + mkdir -p $out/dist $out/authentik + ''; +in + +pkgs.buildGoModule { + pname = "authentik-server"; + inherit (sources) version src meta; + + subPackages = [ "cmd/server" ]; + + nativeBuildInputs = [ apiGoVendorHook ]; + + env.CGO_ENABLED = 0; + + postPatch = '' + substituteInPlace internal/gounicorn/gounicorn.go \ + --replace-fail './lifecycle' "${authentik-django}/lifecycle" + substituteInPlace web/static.go \ + --replace-fail './web' "${webAssetsPath}" + substituteInPlace internal/web/static.go \ + --replace-fail './web' "${webAssetsPath}" + ''; + + # Clear postPatch during the module-download FOD phase so that + # substituteInPlace (which references authentik-django and webui + # store paths) doesn't affect vendorHash computation. + overrideModAttrs.postPatch = ""; + + vendorHash = "sha256-bdILiCQgDuzp+VJDVW3z2JxTtxlHkm9tmMHiA/Sx6ts="; + + postInstall = '' + mv $out/bin/server $out/bin/authentik + ''; +} diff --git a/containers/authentik/test-build.nix b/containers/authentik/test-build.nix index 6ece8df..aaeaced 100644 --- a/containers/authentik/test-build.nix +++ b/containers/authentik/test-build.nix @@ -6,6 +6,7 @@ # nix-build test-build.nix -A authentik-django --extra-experimental-features 'nix-command flakes' # nix-build test-build.nix -A client-go --extra-experimental-features 'nix-command flakes' # nix-build test-build.nix -A client-ts --extra-experimental-features 'nix-command flakes' +# nix-build test-build.nix -A authentik-server --extra-experimental-features 'nix-command flakes' let pkgs = (builtins.getFlake "nixpkgs").legacyPackages.x86_64-linux; sources = import ./sources.nix { inherit pkgs; }; @@ -15,4 +16,5 @@ in authentik-django = import ./authentik-django.nix { inherit pkgs sources; }; client-go = import ./client-go.nix { inherit pkgs sources; }; client-ts = import ./client-ts.nix { inherit pkgs sources; }; + authentik-server = import ./authentik-server.nix { inherit pkgs sources; }; }