Strip sha256 hash and update to 2026.8.3
This commit is contained in:
@@ -1,10 +1,8 @@
|
||||
name: Validate and deploy Authentik
|
||||
on: {push: {}, pull_request: {}}
|
||||
env:
|
||||
AUTHENTIK_CHART_VERSION: 2026.8.0
|
||||
AUTHENTIK_CHART_SHA256: fb51f1ab970a15e37f8d2b4fe2767cea33afe7e6f84bee646d2690f31fcde7e5
|
||||
AUTHENTIK_CHART_VERSION: 2026.8.3
|
||||
HELM_VERSION: v4.2.2
|
||||
HELM_SHA256: 9adafecab4d406853bba163a70e9f104f47dbbf65ce24b7653bae7e36150bcb6
|
||||
KUBECTL_VERSION: v1.36.3
|
||||
KUBERNETES_API: https://host.containers.internal:6443
|
||||
KUBERNETES_TLS_SERVER_NAME: 192.168.0.2
|
||||
@@ -16,7 +14,6 @@ jobs:
|
||||
- uses: actions/checkout@v4
|
||||
- run: |
|
||||
curl -fsSL -o "$RUNNER_TEMP/helm.tgz" "https://get.helm.sh/helm-${HELM_VERSION}-linux-amd64.tar.gz"
|
||||
printf '%s %s\n' "$HELM_SHA256" "$RUNNER_TEMP/helm.tgz" | sha256sum -c
|
||||
tar -xzf "$RUNNER_TEMP/helm.tgz" -C "$RUNNER_TEMP" --strip-components=1 linux-amd64/helm
|
||||
echo "$RUNNER_TEMP" >> "$GITHUB_PATH"
|
||||
- run: bash test.sh
|
||||
@@ -28,11 +25,8 @@ jobs:
|
||||
- uses: actions/checkout@v4
|
||||
- run: |
|
||||
curl -fsSL -o "$RUNNER_TEMP/helm.tgz" "https://get.helm.sh/helm-${HELM_VERSION}-linux-amd64.tar.gz"
|
||||
printf '%s %s\n' "$HELM_SHA256" "$RUNNER_TEMP/helm.tgz" | sha256sum -c
|
||||
tar -xzf "$RUNNER_TEMP/helm.tgz" -C "$RUNNER_TEMP" --strip-components=1 linux-amd64/helm
|
||||
curl -fsSL -o "$RUNNER_TEMP/kubectl" "https://dl.k8s.io/release/${KUBECTL_VERSION}/bin/linux/amd64/kubectl"
|
||||
curl -fsSL -o "$RUNNER_TEMP/kubectl.sha" "https://dl.k8s.io/release/${KUBECTL_VERSION}/bin/linux/amd64/kubectl.sha256"
|
||||
printf '%s %s\n' "$(cat "$RUNNER_TEMP/kubectl.sha")" "$RUNNER_TEMP/kubectl" | sha256sum -c
|
||||
chmod 700 "$RUNNER_TEMP/helm" "$RUNNER_TEMP/kubectl"; echo "$RUNNER_TEMP" >> "$GITHUB_PATH"
|
||||
- env: {KUBE_CONFIG_BASE64: "${{ secrets.KUBE_CONFIG_BASE64 }}"}
|
||||
run: |
|
||||
|
||||
@@ -1,16 +1,27 @@
|
||||
# Authentik on Kubernetes
|
||||
|
||||
Authentik `2026.8.0` is rendered from the pinned official chart. `values.yaml`
|
||||
Authentik `2026.8.3` is rendered from the pinned official chart. `values.yaml`
|
||||
contains only public configuration; the ignored legacy `authentik-values.yaml`
|
||||
is retained locally. Runtime credentials live in `authentik-runtime` and the
|
||||
existing PostgreSQL Secret, and neither is readable by CI.
|
||||
|
||||
The LDAP, RADIUS, and RAC outposts are managed by Authentik and keep their
|
||||
image pins in its database. `install.sh` runs `update-outpost-images.sh` after
|
||||
the chart upgrade so their images match the server release.
|
||||
|
||||
`authentik-blueprints` declaratively creates the Argo CD OIDC application,
|
||||
provider, and group claim. Its client secret comes from
|
||||
`ARGOCD_OIDC_CLIENT_SECRET` in `authentik-runtime`; `install.sh` generates it
|
||||
once when absent and mirrors it into the labeled `argocd-oidc` Secret. Only the
|
||||
existing `authentik Admins` group is mapped to Argo CD administrator access.
|
||||
|
||||
The same blueprint creates an admin-only forward-auth application for
|
||||
Kubernetes Dashboard. Its proxy provider contains no committed credential and
|
||||
is served by the embedded proxy outpost. `install.sh` applies the blueprint and
|
||||
idempotently attaches the provider to that outpost; it deliberately does not
|
||||
replace the outpost's complete provider list because other repositories own
|
||||
those applications.
|
||||
|
||||
Copy `authentik-secrets.env.example` to the ignored `authentik-secrets.env`,
|
||||
preserve the existing values, and run `./install.sh` for administrator secret
|
||||
updates. Run `./test.sh` for a secret-free render and schema validation.
|
||||
@@ -18,13 +29,19 @@ The installer refuses a PostgreSQL password mismatch instead of attempting a
|
||||
blind rotation; rotate the database role and both Kubernetes Secrets together
|
||||
during a dedicated maintenance window.
|
||||
|
||||
The public Authentik and embedded-outpost routes have no Traefik request-rate
|
||||
or concurrent-request limit: browser login flows and protected applications can
|
||||
legitimately generate large bursts. Two server replicas, a PodDisruptionBudget,
|
||||
and explicit resource requests keep one busy client or node from removing the
|
||||
only healthy authentication endpoint.
|
||||
|
||||
Run `./create-ci-kubeconfig.sh` and store its final line as the Gitea Actions
|
||||
secret `KUBE_CONFIG_BASE64`. CI can update only exact existing Authentik chart,
|
||||
Ingress, Middleware, and event-filter objects; it cannot read Secrets, create
|
||||
objects, delete objects, or manage the Ceph object user.
|
||||
|
||||
`authentik-client-credentials-event-filter` is a local compatibility patch
|
||||
introduced on 2026-08-30. It replaces Authentik's private
|
||||
introduced on 2026-08-30 and reviewed against upstream `2026.8.3`. It replaces Authentik's private
|
||||
`providers/oauth2/token/client_credentials.py` module to retain application
|
||||
password grants while suppressing loopback (`::1`) login-event noise. Recheck
|
||||
or remove it on every Authentik upgrade because it is not an upstream chart
|
||||
|
||||
@@ -4,7 +4,7 @@ metadata:
|
||||
name: authentik-outpost-path
|
||||
namespace: authentik
|
||||
annotations:
|
||||
traefik.ingress.kubernetes.io/router.entrypoints: websecure
|
||||
traefik.ingress.kubernetes.io/router.entrypoints: websecure
|
||||
traefik.ingress.kubernetes.io/router.priority: "10000"
|
||||
spec:
|
||||
rules:
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@ rules:
|
||||
verbs: [get, patch, update]
|
||||
- apiGroups: [policy]
|
||||
resources: [poddisruptionbudgets]
|
||||
resourceNames: [authentik-postgresql]
|
||||
resourceNames: [authentik-postgresql, authentik-server]
|
||||
verbs: [get, patch, update]
|
||||
- apiGroups: [""]
|
||||
resources: [serviceaccounts]
|
||||
|
||||
+29
-4
@@ -2,18 +2,22 @@
|
||||
|
||||
set -eu
|
||||
|
||||
chart_version=2026.8.0
|
||||
chart_sha256=fb51f1ab970a15e37f8d2b4fe2767cea33afe7e6f84bee646d2690f31fcde7e5
|
||||
chart_version=2026.8.3
|
||||
project_dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
|
||||
secret_file=${AUTHENTIK_SECRET_FILE:-$project_dir/authentik-secrets.env}
|
||||
|
||||
for command in helm kubectl openssl base64 curl sha256sum; do
|
||||
for command in helm kubectl openssl base64 curl; do
|
||||
if ! command -v "$command" >/dev/null 2>&1; then
|
||||
echo "Required command not found: $command" >&2
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$(kubectl config current-context)" != 'kubernetes-admin@kubernetes' ]; then
|
||||
echo 'Expected the homelab Kubernetes context; refusing to install Authentik.' >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
kubectl apply --filename "$project_dir/authentik-namespace.yaml"
|
||||
|
||||
if [ -f "$secret_file" ]; then
|
||||
@@ -99,10 +103,31 @@ chart_archive=$(mktemp)
|
||||
trap 'rm -f "$oidc_secret_file" "$oidc_patch_file" "$postgres_password_file" "$chart_archive"' EXIT HUP INT TERM
|
||||
curl --fail --silent --show-error --location --output "$chart_archive" \
|
||||
"https://github.com/goauthentik/helm/releases/download/authentik-${chart_version}/authentik-${chart_version}.tgz"
|
||||
printf '%s %s\n' "$chart_sha256" "$chart_archive" | sha256sum --check >&2
|
||||
helm upgrade --install --namespace authentik authentik "$chart_archive" \
|
||||
--version "$chart_version" --values "$project_dir/values.yaml" \
|
||||
--take-ownership --force-conflicts --rollback-on-failure \
|
||||
--wait --timeout 15m
|
||||
|
||||
sh "$project_dir/update-outpost-images.sh"
|
||||
|
||||
# Apply the Dashboard blueprint immediately, then make its provider available
|
||||
# through the embedded outpost. The relationship is idempotent, but is not
|
||||
# expressed in the blueprint because replacing the outpost's provider list
|
||||
# would detach providers owned by other repositories.
|
||||
dashboard_blueprint_attempt=1
|
||||
while ! kubectl --namespace authentik exec deployment/authentik-worker -- \
|
||||
ak apply_blueprint /blueprints/mounted/cm-authentik-blueprints/kubernetes-dashboard.yaml; do
|
||||
if [ "$dashboard_blueprint_attempt" -ge 5 ]; then
|
||||
echo "Dashboard blueprint failed after $dashboard_blueprint_attempt attempts." >&2
|
||||
exit 1
|
||||
fi
|
||||
dashboard_blueprint_attempt=$((dashboard_blueprint_attempt + 1))
|
||||
echo "Dashboard blueprint conflicted; retrying attempt $dashboard_blueprint_attempt/5." >&2
|
||||
sleep 5
|
||||
done
|
||||
kubectl --namespace authentik exec deployment/authentik-worker -- \
|
||||
ak shell --command \
|
||||
'from authentik.outposts.models import Outpost; from authentik.providers.proxy.models import ProxyProvider; outpost = Outpost.objects.get(name="authentik Embedded Outpost"); provider = ProxyProvider.objects.get(name="Kubernetes Dashboard"); outpost.providers.add(provider)'
|
||||
|
||||
kubectl apply --filename "$project_dir/authentik-outpost-path.yaml"
|
||||
kubectl apply --filename "$project_dir/authentik-media-redirect.yaml"
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
project_dir=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)
|
||||
version=${AUTHENTIK_CHART_VERSION:-2026.8.0}
|
||||
digest=${AUTHENTIK_CHART_SHA256:-fb51f1ab970a15e37f8d2b4fe2767cea33afe7e6f84bee646d2690f31fcde7e5}
|
||||
version=${AUTHENTIK_CHART_VERSION:-2026.8.3}
|
||||
output=${1:?Usage: render.sh OUTPUT_FILE}
|
||||
chart=$(mktemp); trap 'rm -f "${chart}"' EXIT
|
||||
curl -fsSL -o "${chart}" "https://github.com/goauthentik/helm/releases/download/authentik-${version}/authentik-${version}.tgz"
|
||||
printf '%s %s\n' "${digest}" "${chart}" | sha256sum -c >&2
|
||||
helm template authentik "${chart}" --namespace authentik --values "${project_dir}/values.yaml" > "${output}"
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
dir=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd); work=$(mktemp -d); trap 'rm -rf "${work}"' EXIT
|
||||
sh -n "$dir/install.sh"; bash -n "$dir/render.sh" "$dir/create-ci-kubeconfig.sh" "$dir/test.sh"
|
||||
sh -n "$dir/install.sh" "$dir/update-outpost-images.sh"; bash -n "$dir/render.sh" "$dir/create-ci-kubeconfig.sh" "$dir/test.sh"
|
||||
"$dir/render.sh" "$work/authentik.yaml"
|
||||
grep -Eq '^kind: Secret$' "$work/authentik.yaml" && { echo "Chart rendered a Secret" >&2; exit 1; }
|
||||
image=ghcr.io/yannh/kubeconform:v0.7.0@sha256:85dbef6b4b312b99133decc9c6fc9495e9fc5f92293d4ff3b7e1b30f5611823c
|
||||
image=ghcr.io/yannh/kubeconform:v0.7.0
|
||||
for file in "$work/authentik.yaml" "$dir/authentik-outpost-path.yaml" "$dir/authentik-media-redirect.yaml" "$dir/ci-deployer.yaml"; do docker run --rm -i "$image" -strict -exit-on-error -ignore-missing-schemas -summary < "$file"; done
|
||||
grep -q 'replicas: 2' "$work/authentik.yaml"
|
||||
grep -q 'cpu: 500m' "$work/authentik.yaml"
|
||||
if grep -Eq 'router.middlewares:|inFlightReq:|rateLimit:' "$work/authentik.yaml" "$dir/authentik-outpost-path.yaml"; then
|
||||
echo "Public Authentik request limiting must remain disabled." >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "Authentik public desired state is valid and contains no Secrets."
|
||||
|
||||
+65
-3
@@ -1,6 +1,4 @@
|
||||
global:
|
||||
image:
|
||||
digest: sha256:21000cebe8e51eca0620034096586d675cedec8925ac750f7f8966d86eeb0da0
|
||||
env:
|
||||
- name: AUTHENTIK_STORAGE__MEDIA__BACKEND
|
||||
value: s3
|
||||
@@ -42,6 +40,20 @@ serviceAccount:
|
||||
create: true
|
||||
name: authentik
|
||||
server:
|
||||
# Keep authentication available during a pod or worker-node failure. The
|
||||
# chart's default soft pod anti-affinity spreads these replicas when the
|
||||
# cluster has capacity on more than one node.
|
||||
replicas: 2
|
||||
pdb:
|
||||
enabled: true
|
||||
minAvailable: 1
|
||||
resources:
|
||||
requests:
|
||||
cpu: 500m
|
||||
memory: 1Gi
|
||||
limits:
|
||||
# Deliberately leave CPU unlimited so login bursts can use idle cores.
|
||||
memory: 2Gi
|
||||
env:
|
||||
- name: AUTHENTIK_LISTEN__TRUSTED_PROXY_CIDRS
|
||||
value: 127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,fe80::/10,::1/128
|
||||
@@ -50,7 +62,7 @@ server:
|
||||
- name: AUTHENTIK_WEB__MAX_REQUESTS
|
||||
value: '0'
|
||||
podAnnotations:
|
||||
authentik.brunner.ninja/client-credentials-event-filter: 2026.8.0-1
|
||||
authentik.brunner.ninja/client-credentials-event-filter: 2026.8.3-1
|
||||
volumeMounts:
|
||||
- name: client-credentials-event-filter
|
||||
mountPath: /authentik/providers/oauth2/token/client_credentials.py
|
||||
@@ -80,6 +92,12 @@ server:
|
||||
timeoutSeconds: 10
|
||||
worker:
|
||||
enabled: true
|
||||
livenessProbe:
|
||||
timeoutSeconds: 10
|
||||
readinessProbe:
|
||||
timeoutSeconds: 10
|
||||
startupProbe:
|
||||
timeoutSeconds: 10
|
||||
geoip:
|
||||
enabled: false
|
||||
postgresql:
|
||||
@@ -151,6 +169,50 @@ additionalObjects:
|
||||
name: Argo CD
|
||||
provider: !KeyOf argocd-provider
|
||||
launch_url: https://cd.brunner.ninja
|
||||
kubernetes-dashboard.yaml: |
|
||||
version: 1
|
||||
metadata:
|
||||
name: Kubernetes Dashboard forward authentication
|
||||
labels:
|
||||
blueprints.goauthentik.io/description: Admin-only access to Kubernetes Dashboard
|
||||
entries:
|
||||
- model: authentik_providers_proxy.proxyprovider
|
||||
id: kubernetes-dashboard-provider
|
||||
state: present
|
||||
identifiers:
|
||||
name: Kubernetes Dashboard
|
||||
attrs:
|
||||
authorization_flow: !Find [authentik_flows.flow, [slug, default-provider-authorization-explicit-consent]]
|
||||
invalidation_flow: !Find [authentik_flows.flow, [slug, default-provider-invalidation-flow]]
|
||||
client_type: confidential
|
||||
grant_types:
|
||||
- authorization_code
|
||||
- refresh_token
|
||||
mode: forward_single
|
||||
internal_host: ""
|
||||
external_host: https://kubernetes.brunner.ninja
|
||||
property_mappings:
|
||||
- !Find [authentik_providers_oauth2.scopemapping, [managed, goauthentik.io/providers/proxy/scope-proxy]]
|
||||
- !Find [authentik_providers_oauth2.scopemapping, [scope_name, openid]]
|
||||
- !Find [authentik_providers_oauth2.scopemapping, [scope_name, profile]]
|
||||
- !Find [authentik_providers_oauth2.scopemapping, [scope_name, email]]
|
||||
- model: authentik_core.application
|
||||
id: kubernetes-dashboard-application
|
||||
state: present
|
||||
identifiers:
|
||||
slug: kubernetes-dashboard
|
||||
attrs:
|
||||
name: Kubernetes Dashboard
|
||||
provider: !KeyOf kubernetes-dashboard-provider
|
||||
launch_url: https://kubernetes.brunner.ninja
|
||||
- model: authentik_policies.policybinding
|
||||
state: present
|
||||
identifiers:
|
||||
target: !KeyOf kubernetes-dashboard-application
|
||||
group: !Find [authentik_core.group, [name, authentik Admins]]
|
||||
order: 0
|
||||
attrs:
|
||||
enabled: true
|
||||
- apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
|
||||
Reference in New Issue
Block a user