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
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).
101 lines
5.3 KiB
Markdown
101 lines
5.3 KiB
Markdown
# 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
|
|
```bash
|
|
# 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
|
|
```bash
|
|
# 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.yaml` — `dezky-portal` OIDC app/provider
|
|
(`https://app.dezky.eu/api/auth/callback`).
|
|
- `operator-application.yaml` — `dezky-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`:
|
|
```bash
|
|
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.
|
|
|
|
## Full visual rebrand (logo / favicon / background / footer) — APPLIED
|
|
|
|
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.
|