From 6612c3febc04ec70773cba23a25d9a3c43432d45 Mon Sep 17 00:00:00 2001 From: Erich Blume Date: Sun, 1 Mar 2026 13:41:58 -0800 Subject: [PATCH] C2(authentik-source-build): finalize chain for merge - Add version = "2026.2.0" to default.nix for CI workflow version extraction - Update service-versions.yaml to 2026.2.0, mark reviewed 2026-03-01 - Update changelog entry to reflect completed work - Rewrite goal card as historical how-to documentation Co-Authored-By: Claude Opus 4.6 --- containers/authentik/default.nix | 2 + .../authentik-source-build.infra.md | 2 +- .../authentik/build-authentik-from-source.md | 70 +++++++------------ service-versions.yaml | 4 +- 4 files changed, 31 insertions(+), 47 deletions(-) diff --git a/containers/authentik/default.nix b/containers/authentik/default.nix index d441405..8c34cb9 100644 --- a/containers/authentik/default.nix +++ b/containers/authentik/default.nix @@ -11,6 +11,8 @@ let sources = import ./sources.nix { inherit pkgs; }; + # Duplicated from sources.nix so build-container-nix.yaml can grep it + version = "2026.2.0"; webui = import ./webui.nix { inherit pkgs sources; }; authentik-django = import ./authentik-django.nix { inherit pkgs sources webui; }; authentik-server = import ./authentik-server.nix { inherit pkgs sources authentik-django webui; }; diff --git a/docs/changelog.d/authentik-source-build.infra.md b/docs/changelog.d/authentik-source-build.infra.md index 8385723..757ad9e 100644 --- a/docs/changelog.d/authentik-source-build.infra.md +++ b/docs/changelog.d/authentik-source-build.infra.md @@ -1 +1 @@ -Start C2 Mikado chain: build authentik from a custom Nix derivation (from source) to replace nixpkgs dependency and gain full version control. +Build authentik 2026.2.0 from source via custom Nix derivation, replacing the nixpkgs `pkgs.authentik` dependency. Four components (API client generation, Python backend, web UI, Go server) assembled into a single container image with full supply chain control via forge mirrors. diff --git a/docs/how-to/authentik/build-authentik-from-source.md b/docs/how-to/authentik/build-authentik-from-source.md index 09119a2..fdf1f8c 100644 --- a/docs/how-to/authentik/build-authentik-from-source.md +++ b/docs/how-to/authentik/build-authentik-from-source.md @@ -1,7 +1,6 @@ --- title: Build Authentik from Source modified: 2026-03-01 -branch: mikado/authentik-source-build requires: - authentik-go-server-derivation - authentik-web-ui-derivation @@ -14,75 +13,58 @@ tags: # Build Authentik from Source -Replace `pkgs.authentik` from nixpkgs with a custom Nix derivation that builds authentik from source. This removes the dependency on the nixpkgs packaging timeline and gives full version control. +Custom Nix derivation that builds authentik from source, replacing the `pkgs.authentik` nixpkgs dependency. This gives full version control independent of the nixpkgs release cycle. ## Motivation -The nix-container-builder runner on ringtail resolves `nixpkgs` via the NixOS nix registry, which pins to `nixos-25.11`. That channel lags behind upstream authentik releases — e.g. nixos-25.11 has 2025.10.1 while upstream is at 2026.2.0. Building from source lets us target any release. - -Target version: **2026.2.0** (latest stable, released 2026-02-24). Notable changes from the nixpkgs reference (2025.12.4): requires Python 3.14, Go 1.25.5. - -This also serves as practice for packaging services from source using Nix, relying on nixpkgs only for satellite dependencies (Python interpreter, Node.js, Go toolchain, system libraries). +The nix-container-builder runner on ringtail resolves `nixpkgs` via the NixOS nix registry, which pins to `nixos-25.11`. That channel lags behind upstream authentik releases. Building from source lets us target any release by updating `sources.nix`. ## Architecture -Authentik has four build components that must be assembled: +Authentik has four build components assembled by `containers/authentik/default.nix`: -1. **API client generation** — Go and TypeScript bindings generated from `schema.yml` (OpenAPI) -2. **Python backend** (`authentik-django`) — Django application with 60+ Python dependencies, installed via `uv` from PyPI rather than nixpkgs (see [[authentik-python-backend-derivation]]) -3. **Web UI** — Lit-based TypeScript frontend built with Rollup -4. **Go server** — HTTP server binary (`cmd/server`) that serves the web UI and spawns gunicorn for Django +1. **API client generation** (`client-go.nix`, `client-ts.nix`) — Go and TypeScript bindings generated from `schema.yml` (OpenAPI) +2. **Python backend** (`authentik-django.nix`) — Django application with 60+ Python dependencies installed via `uv` from PyPI (see [[authentik-python-backend-derivation]]) +3. **Web UI** (`webui.nix`) — Lit-based TypeScript frontend built with esbuild + rollup +4. **Go server** (`authentik-server.nix`) — HTTP server binary that serves the web UI and spawns gunicorn for Django -The final package is the `ak` bash wrapper that orchestrates Go server + Python worker. +The `ak` wrapper script in `default.nix` sets PATH/VIRTUAL_ENV and delegates to `lifecycle/ak`, which dispatches `server` to the Go binary and everything else to Python/Django. -**Python packaging strategy:** Nix provides the Python 3.14 interpreter and system libraries. Python packages are installed from PyPI using `uv`, locked by authentik's `uv.lock`. This avoids nixpkgs' Python 3.14 compatibility issues (many packages in nixos-25.11's python314 set fail to build) and aligns with upstream's build process. +**Python packaging strategy:** Nix provides the Python 3.14 interpreter and system libraries. Python packages are installed from PyPI using `uv`, locked by authentik's `uv.lock`. This avoids nixpkgs' Python 3.14 compatibility issues and aligns with upstream's build process. ## Source -Forge mirrors (all derivations should fetch from forge, not GitHub): +All derivations fetch from forge mirrors for supply chain control: - https://forge.ops.eblu.me/mirrors/authentik (upstream: `goauthentik/authentik`) - https://forge.ops.eblu.me/mirrors/authentik-client-go (upstream: `goauthentik/client-go`) -- https://forge.ops.eblu.me/mirrors/authentik-django-rest-framework (upstream: `authentik-community/django-rest-framework`) -Reference derivation: [nixpkgs `pkgs/by-name/au/authentik/package.nix`](https://github.com/NixOS/nixpkgs/tree/master/pkgs/by-name/au/authentik) — targets 2025.12.4, we are porting to 2026.2.0 so hashes and some deps will differ. +Version and hashes are centralized in `containers/authentik/sources.nix`. + +## Updating to a New Version + +1. Update `version` in `sources.nix` and `default.nix` +2. Update `src` and `client-go-src` hashes in `sources.nix` (use `nix-prefetch-git` on ringtail) +3. Rebuild `python-deps.nix` FOD — hash changes when `uv.lock` changes +4. Rebuild `webui-deps.nix` FOD — hash changes when `package-lock.json` or platform-specific npm binaries change +5. Recompute `vendorHash` in `authentik-server.nix` if Go dependencies changed +6. Test on ringtail: `nix-build test-build.nix -A assembled` +7. Build and push the container via CI ## Testing -Nix derivations target `x86_64-linux` and can't be built on macOS. Test incrementally on ringtail: +Nix derivations target `x86_64-linux`. Test incrementally on ringtail: ```fish -# Copy derivation files to a temp dir on ringtail set tmpdir (ssh ringtail 'mktemp -d /tmp/authentik-test.XXXXXX') -scp containers/authentik/*.nix containers/authentik/*.patch ringtail:$tmpdir/ - -# Write a test-build.nix that instantiates components, then: -ssh ringtail "cd $tmpdir && nix-build test-build.nix -A --extra-experimental-features 'nix-command flakes'" - -# Clean up +scp containers/authentik/*.nix ringtail:$tmpdir/ +ssh ringtail "cd $tmpdir && nix-build test-build.nix -A assembled --extra-experimental-features 'nix-command flakes'" ssh ringtail "rm -rf $tmpdir" ``` -Use `builtins.getFlake "nixpkgs"` instead of `` (ringtail uses flakes, no NIX_PATH). - -Prefetch hashes for `fetchgit` sources: -```fish -ssh ringtail 'nix shell nixpkgs#nix-prefetch-git --extra-experimental-features "nix-command flakes" -c nix-prefetch-git --url --rev --quiet' -``` - -## What to Do - -Once all prerequisites are complete: - -1. Assemble the component derivations into a final `ak`-wrapped package in `containers/authentik/` -2. Update `containers/authentik/default.nix` to use the custom derivation instead of `pkgs.authentik` -3. Test locally via Dagger before pushing to CI: `dagger call build-nix --src=. --container-name=authentik` -4. Build and push the container: `mise run container-build-and-release authentik` -5. Update `argocd/manifests/authentik/kustomization.yaml` with the new image tag -6. Update `service-versions.yaml` with the new version -7. Verify deployment: ArgoCD sync, UI login, OAuth2 flows +`test-build.nix` provides both individual component targets and a fully-wired `assembled` target. ## Related -- [[build-authentik-container]] — Current nixpkgs-based build (to be replaced) +- [[build-authentik-container]] — Container build reference - [[deploy-authentik]] — Parent deployment goal - [[agent-change-process]] — C2 methodology diff --git a/service-versions.yaml b/service-versions.yaml index d64f8d3..fa5e24f 100644 --- a/service-versions.yaml +++ b/service-versions.yaml @@ -131,8 +131,8 @@ services: - name: authentik type: argocd - last-reviewed: null - current-version: "2025.10.1" + last-reviewed: "2026-03-01" + current-version: "2026.2.0" upstream-source: https://github.com/goauthentik/authentik/releases - name: navidrome