From 8db16d748302c85c32a693d861f0730da50b7b02 Mon Sep 17 00:00:00 2001 From: "fuzeone-bot[bot]" Date: Wed, 15 Jul 2026 11:07:37 +0300 Subject: [PATCH 1/2] =?UTF-8?q?fix(authn):=20route=20Authentik=20native=20?= =?UTF-8?q?paths=20under=20app=20host=20=E2=80=94=20restore=20OIDC=20(prod?= =?UTF-8?q?=20outage)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #247's reverse-proxy stripped /api/auth/idp and relied on X-Forwarded-Prefix, but Authentik IGNORES it — so discovery advertised app.fuzefront.com/application/o/authorize/ (no prefix), an unrouted path → the browser authorize redirect 404'd → prod login broke. Fix: route Authentik's native root paths (/application,/if,/source,/flows,/ws,/-, /outpost.goauthentik.io,/static/dist,/static/authentik) straight to authentik-server under app.fuzefront.com (no strip); issuer -> https://app.fuzefront.com/application/o/fuzefront/. Boundary intact: browser stays on app.fuzefront.com, never sees the IdP host. Chart-only — deploys via Argo, no image build. helm template renders clean. Co-Authored-By: Claude claude-opus-4-8 Claude-Session-Id: cf830721-b1ef-4fe0-a024-035ad280dcf7 --- .../helm/fuzefront/templates/authentik.yaml | 19 ------------------ deploy/helm/fuzefront/templates/ingress.yaml | 20 ++++++++----------- deploy/helm/fuzefront/values-prod.yaml | 13 +++++++----- 3 files changed, 16 insertions(+), 36 deletions(-) diff --git a/deploy/helm/fuzefront/templates/authentik.yaml b/deploy/helm/fuzefront/templates/authentik.yaml index 30dafacf..50a969ae 100644 --- a/deploy/helm/fuzefront/templates/authentik.yaml +++ b/deploy/helm/fuzefront/templates/authentik.yaml @@ -284,24 +284,5 @@ spec: headers: customRequestHeaders: X-Forwarded-Proto: "https" -{{- if eq .Values.ingress.className "traefik" }} ---- -# Strip the `/api/auth/idp` prefix before forwarding to authentik-server, so -# Authentik receives its native paths (e.g. /application/o/fuzefront/). Traefik's -# stripPrefix also sets `X-Forwarded-Prefix: /api/auth/idp`, which Authentik uses -# to build absolute discovery/authorize URLs back under the app host + prefix — -# keeping the issuer `https://app.fuzefront.com/api/auth/idp/...` consistent. -apiVersion: traefik.io/v1alpha1 -kind: Middleware -metadata: - name: authentik-idp-stripprefix - labels: - {{- include "fuzefront.labels" . | nindent 4 }} -spec: - stripPrefix: - prefixes: - - /api/auth/idp - forceSlash: false -{{- end }} {{- end }} {{- end }} diff --git a/deploy/helm/fuzefront/templates/ingress.yaml b/deploy/helm/fuzefront/templates/ingress.yaml index 1c823e46..fec6ae23 100644 --- a/deploy/helm/fuzefront/templates/ingress.yaml +++ b/deploy/helm/fuzefront/templates/ingress.yaml @@ -186,9 +186,8 @@ metadata: app.kubernetes.io/component: authentik-idp annotations: {{- if eq .Values.ingress.className "traefik" }} - traefik.ingress.kubernetes.io/router.middlewares: {{ .Release.Namespace }}-authentik-idp-stripprefix@kubernetescrd,{{ .Release.Namespace }}-authentik-forwarded-proto@kubernetescrd + traefik.ingress.kubernetes.io/router.middlewares: {{ .Release.Namespace }}-authentik-forwarded-proto@kubernetescrd {{- else if eq .Values.ingress.className "nginx" }} - nginx.ingress.kubernetes.io/rewrite-target: /$2 nginx.ingress.kubernetes.io/proxy-buffer-size: "16k" {{- end }} {{- with .Values.ingress.annotations }} @@ -206,16 +205,13 @@ spec: - host: {{ .Values.ingress.host | quote }} http: paths: - {{- if eq .Values.ingress.className "nginx" }} - - path: /api/auth/idp(/|$)(.*) - pathType: ImplementationSpecific - backend: - service: - name: authentik-server - port: - number: 9000 - {{- else }} - - path: /api/auth/idp + # Route Authentik's OWN native root paths under the app host (NO prefix, + # NO strip). Authentik ignores X-Forwarded-Prefix, so it builds absolute + # OIDC discovery/authorize URLs at these root paths using the forwarded + # Host (app.fuzefront.com) — which must therefore be routable here. + # These prefixes don't overlap the app's /api, /apps, /socket.io, / routes. + {{- range $p := list "/application" "/if" "/source" "/flows" "/ws" "/-" "/outpost.goauthentik.io" "/static/dist" "/static/authentik" }} + - path: {{ $p }} pathType: Prefix backend: service: diff --git a/deploy/helm/fuzefront/values-prod.yaml b/deploy/helm/fuzefront/values-prod.yaml index be367c4e..a3c21ef3 100644 --- a/deploy/helm/fuzefront/values-prod.yaml +++ b/deploy/helm/fuzefront/values-prod.yaml @@ -256,11 +256,14 @@ authentik: bootstrapEmail: admin@fuzefront.com oidc: enabled: true - # App-hosted, reverse-proxied issuer. The /api/auth/idp prefix is stripped by - # the Traefik middleware before reaching authentik-server; X-Forwarded-Prefix - # keeps Authentik's discovery URLs under this path. The FuzeFront OAuth - # callback (redirectUri) is already app-hosted and unchanged. - issuerUrl: "https://app.fuzefront.com/api/auth/idp/application/o/fuzefront/" + # App-hosted, reverse-proxied issuer at Authentik's NATIVE root path. Authentik + # ignores X-Forwarded-Prefix, so it advertises discovery/authorize URLs at + # /application/o/... (using the forwarded Host app.fuzefront.com); the app + # Ingress routes those native Authentik paths (/application,/if,/source,...) + # straight to authentik-server (no prefix, no strip), so the browser stays on + # app.fuzefront.com and never sees the IdP host. Callback (redirectUri) is the + # FuzeFront security-service route, unchanged. + issuerUrl: "https://app.fuzefront.com/application/o/fuzefront/" redirectUri: "https://app.fuzefront.com/api/auth/oidc/callback" # No split-DNS in prod: real public DNS + a real Let's Encrypt cert mean the # backend reaches Authentik over the internet without a hostAlias or a custom From 0a2eeca9f086a196894f7524ed64c9c247fc890b Mon Sep 17 00:00:00 2001 From: "fuzeone-bot[bot]" Date: Wed, 15 Jul 2026 13:09:23 +0300 Subject: [PATCH 2/2] =?UTF-8?q?ci(release):=20add=20workflow=5Fdispatch=20?= =?UTF-8?q?=E2=80=94=20enable=20manual=20image=20builds?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Auto-merged PRs push to master under GITHUB_TOKEN, which GitHub does not let trigger push-workflows — so release.yml never ran after #247/#253/#256 and the security-service/frontend images never built. workflow_dispatch gives a reliable manual build+GitOps-bump path (durable fix: switch auto-merge to a PAT — needs a RELEASE_PAT secret, tracked separately). Co-Authored-By: Claude claude-opus-4-8 Claude-Session-Id: cf830721-b1ef-4fe0-a024-035ad280dcf7 --- .github/workflows/release.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2f80993a..9e84e7f1 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -4,6 +4,16 @@ name: Release (images + GitOps bump) # GHCR tagged with the commit SHA, then bump the tags in values-prod.yaml and # commit. Argo CD sees the git change and rolls out the new images. on: + # Manual trigger: auto-merged PRs push to master under GITHUB_TOKEN, and GitHub + # does NOT start push-triggered workflows for GITHUB_TOKEN pushes — so this + # workflow otherwise never runs after an auto-merge and images never build. + # Dispatch this after a deploy-window merge to build + bump the image tags. + workflow_dispatch: + inputs: + reason: + description: 'Why this manual build (e.g. deploy security-service after an auto-merged PR)' + required: false + default: 'manual release' push: branches: [master] paths: