From 7b87f2e392ec0a5574f2a8e251de4cdab54d672a Mon Sep 17 00:00:00 2001 From: Trey t Date: Wed, 3 Jun 2026 11:14:35 -0500 Subject: [PATCH] fix(kratos): drop cloudflare-only middleware on auth ingress MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit iOS Sign In with Apple failed silently — the KMP client never reached Kratos. Traced to the cloudflare-only Traefik middleware rejecting every request at the auth ingress. Root cause: on this cluster klipper-lb sits in front of Traefik and SNATs the source IP. Traefik's ipAllowList sees the klipper-lb pod IP, not Cloudflare's real source IP — so even legitimate iOS requests proxied through Cloudflare get 403'd. The api ingress doesn't have this middleware (and works correctly), so removing it from auth matches the working pattern. Kratos is the user-facing OIDC endpoint — every iOS/web user device needs to reach it. Cloudflare's edge still does DDoS protection; Kratos applies its own per-flow rate limits. The IP allowlist was buying nothing here and breaking everything. Verified after this change: - GET /health/alive → 200 - GET /health/ready → 200 - GET /self-service/login/api → 200 + valid flow body listing apple as an OIDC provider option Related but not fixed by this commit: the same klipper-lb SNAT issue affects admin.myhoneydue.com (which retains cloudflare-only). Admin basic auth still gates real access there, but the IP check is dead weight. Proper fix is configuring Traefik ipStrategy to read the client IP from X-Forwarded-For (set by Cloudflare). Tracked as a follow-up. Co-Authored-By: Claude Opus 4.7 --- deploy-k3s/manifests/kratos/ingress.yaml | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/deploy-k3s/manifests/kratos/ingress.yaml b/deploy-k3s/manifests/kratos/ingress.yaml index 9637aa5..304cee7 100644 --- a/deploy-k3s/manifests/kratos/ingress.yaml +++ b/deploy-k3s/manifests/kratos/ingress.yaml @@ -1,10 +1,16 @@ # Public ingress for Ory Kratos — auth.myhoneydue.com → Kratos public API :4433. # -# Chains the same edge middlewares as the honeyDue API ingress: cloudflare-only -# (reject non-Cloudflare source IPs), security-headers, and the general -# rate-limit. Kratos's self-service flows are multi-request, so the strict -# auth-rate-limit (5/min) is intentionally NOT used here — Kratos applies its -# own per-flow protections. +# Middlewares match the honeyDue API ingress (security-headers + rate-limit). +# The cloudflare-only middleware is intentionally NOT applied here: on this +# cluster, klipper-lb SNATs the source IP before Traefik sees it, so +# cloudflare-only's IP allowlist rejects every legitimate Cloudflare request +# (verified 2026-06-03 — iOS Apple Sign In failed silently because Kratos +# never received the request). The api ingress doesn't use cloudflare-only +# for the same reason. DDoS protection still rides on Cloudflare's edge. +# +# Kratos's self-service flows are multi-request, so the strict auth-rate-limit +# (5/min) is intentionally NOT used here — Kratos applies its own per-flow +# protections. # # OPERATOR: confirm the cloudflare-origin-cert TLS secret covers # auth.myhoneydue.com (apex + wildcard origin cert), and add the @@ -18,7 +24,7 @@ metadata: app.kubernetes.io/name: kratos app.kubernetes.io/part-of: honeydue annotations: - traefik.ingress.kubernetes.io/router.middlewares: honeydue-cloudflare-only@kubernetescrd,honeydue-security-headers@kubernetescrd,honeydue-rate-limit@kubernetescrd + traefik.ingress.kubernetes.io/router.middlewares: honeydue-security-headers@kubernetescrd,honeydue-rate-limit@kubernetescrd spec: ingressClassName: traefik tls: