Files
dezky/infrastructure/production/fleet/authentik/README.md
T
Ronni Baslund 326b626fc6
ci / typecheck (map[dir:services/platform-api name:platform-api]) (push) Has been cancelled
ci / test (push) Has been cancelled
ci / typecheck (map[dir:apps/portal name:portal]) (push) Has been cancelled
ci / typecheck (map[dir:apps/website name:website]) (push) Has been cancelled
ci / typecheck (map[dir:apps/booking name:booking]) (push) Has been cancelled
feat(infra): full dezky rebrand of Authentik login (logo, favicon, bg, footer)
Brand CSS only reaches the flow shadow DOM via CSS vars (colors), not the
logo/favicon (deeper shadow root) or the "Powered by authentik" footer (light
DOM). So, dev-style: serve real dezky assets + sed the bundle.

- web-assets/: dezky-logo.svg, dezky-favicon.svg, dezky-bg.svg (carbon).
- server-rebrand.py: patches the authentik-server Deployment with an
  initContainer that copies /web/dist to an emptyDir, drops the svgs into
  assets/icons, and seds "Powered by authentik" -> "Powered by Dezky".
- brand.yaml: branding_logo / branding_favicon / branding_default_flow_background
  point at the served svgs; auth-flow title "Welcome to Dezky"; signal-green CSS.

Verified live: login now matches dev (logo, title, carbon bg, green button,
favicon, Powered by Dezky). Durability caveat documented (reverts on helm
upgrade).
2026-06-08 20:36:01 +02:00

5.3 KiB

fleet/authentik — identity provider (auth.dezky.eu)

Authentik, mirroring the dev docker-compose service but pointed at the in-cluster data tier. Deployed via the k3s Helm controller (helmchart.yaml, which mirrors values.yaml). Live at https://auth.dezky.eu (Let's Encrypt).

  • External Postgres (postgres.dezky-data, db/user authentik) + Redis (redis.dezky-data) — chart's bundled subcharts disabled.
  • Secrets via global.envFrom → the authentik-secret Secret (generated on-box; see secret.example.yaml). DB/Redis passwords match the dezky-data secrets.
  • Ingress: Traefik + cert-manager letsencrypt-prod.
  • error_reporting off, update-check off, bootstrap email admin@dezky.eu.

Deploy

# 1. secret (reads DB/Redis pw from dezky-data so they match; rest generated)
ADB=$(kubectl -n dezky-data get secret postgres-secret -o jsonpath='{.data.AUTHENTIK_DB_PASSWORD}' | base64 -d)
RDB=$(kubectl -n dezky-data get secret redis-secret    -o jsonpath='{.data.REDIS_PASSWORD}'        | base64 -d)
kubectl create namespace dezky-auth --dry-run=client -o yaml | kubectl apply -f -
kubectl -n dezky-auth create secret generic authentik-secret \
  --from-literal=AUTHENTIK_SECRET_KEY=$(openssl rand -hex 50) \
  --from-literal=AUTHENTIK_POSTGRESQL__PASSWORD="$ADB" \
  --from-literal=AUTHENTIK_REDIS__PASSWORD="$RDB" \
  --from-literal=AUTHENTIK_BOOTSTRAP_PASSWORD=$(openssl rand -hex 16) \
  --from-literal=AUTHENTIK_BOOTSTRAP_TOKEN=$(openssl rand -hex 32)
# 2. install
kubectl apply -f helmchart.yaml
kubectl -n dezky-auth rollout status deploy/authentik-server --timeout=300s

First login

# akadmin password (store in Bitwarden):
kubectl -n dezky-auth get secret authentik-secret -o jsonpath='{.data.AUTHENTIK_BOOTSTRAP_PASSWORD}' | base64 -d; echo

Log in at https://auth.dezky.eu as akadmin / that password.

Blueprints + branding (APPLIED)

blueprints/ holds prod blueprints (applied & successful on node1):

  • brand.yaml — dezky branding on the default brand (title + signal-green custom CSS). This is what puts the login page in dezky colors.
  • portal-application.yamldezky-portal OIDC app/provider (https://app.dezky.eu/api/auth/callback).
  • operator-application.yamldezky-operator OIDC app/provider (https://operator.dezky.eu/auth/oidc/callback) + dezky-platform-admins group + an access policy restricting operator login to that group.

Client secrets live in authentik-secret (PORTAL_OIDC_CLIENT_SECRET, OPERATOR_OIDC_CLIENT_SECRET) — the apps must reuse the SAME values.

Applying them (two gotchas, both handled)

  1. invalidation_flow is REQUIRED on OAuth2 providers in Authentik 2026.5 (dev's 2025.10 didn't need it) — both providers set it via !Find.
  2. ConfigMap mounts present files as symlinks, which Authentik's discovery won't read. So the worker uses an initContainer that copies the ConfigMap into an emptyDir as real files at /blueprints/custom:
    kubectl -n dezky-auth create configmap authentik-blueprints \
      --from-file=blueprints/ --dry-run=client -o yaml | kubectl apply -f -
    # patch worker: add bp-src(configMap) + bp-cust(emptyDir) + initContainer
    #   `cp -L /bp-src/*.yaml /bp-cust/`, mount bp-cust at /blueprints/custom
    kubectl -n dezky-auth rollout restart deploy/authentik-worker
    # apply each (or let discovery): ak apply_blueprint custom/<file>.yaml
    

    The chart's worker.volumes value did NOT take effect on this chart version, hence the direct Deployment patch. Caveat: a helm upgrade of Authentik reverts the patch — re-apply it (move it into a custom image or a post-render kustomize patch to make it durable). TODO.

Still deferred

  • Pin the chart version (currently latest → app 2026.5.2).
  • Durability: the server-rebrand Deployment patch + the brand image-field PATCH revert on a helm upgrade of Authentik — re-run them, or bake a custom image / post-render kustomize patch.

Brand custom CSS only reaches shadow DOM via CSS vars (so colors work), not the logo/favicon (deeper shadow root) or the "Powered by authentik" footer (light DOM). Those use dev's mechanism — real files + a bundle sed:

  • web-assets/dezky-logo.svg, dezky-favicon.svg, dezky-bg.svg (carbon).
  • ConfigMap authentik-web-assets is built from web-assets/.
  • server-rebrand.py patches the authentik-server Deployment: an initContainer copies /web/dist into an emptyDir, drops the 3 svgs into /web/dist/assets/icons/, and seds Powered by authentik -> Powered by Dezky. The server then serves the patched bundle.
  • The brand's branding_logo / branding_favicon / branding_default_flow_background point at those served svgs (carried in brand.yaml; if the blueprint leaves them default, PATCH the brand via API).

Apply:

kubectl -n dezky-auth create configmap authentik-web-assets --from-file=web-assets/ --dry-run=client -o yaml | kubectl apply -f -
kubectl -n dezky-auth get deploy authentik-server -o json | python3 server-rebrand.py | kubectl apply -f -

CAVEAT: the server patch + brand PATCH revert on a helm upgrade of Authentik — re-run them (or bake a custom image) for durability.