fix(kratos): drop cloudflare-only middleware on auth ingress
Backend CI / Test (push) Has been cancelled
Backend CI / Contract Tests (push) Has been cancelled
Backend CI / Lint (push) Has been cancelled
Backend CI / Secret Scanning (push) Has been cancelled
Backend CI / Build (push) Has been cancelled

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 <noreply@anthropic.com>
This commit is contained in:
Trey t
2026-06-03 11:14:35 -05:00
parent 6de90acef7
commit 7b87f2e392
+12 -6
View File
@@ -1,10 +1,16 @@
# Public ingress for Ory Kratos — auth.myhoneydue.com → Kratos public API :4433. # Public ingress for Ory Kratos — auth.myhoneydue.com → Kratos public API :4433.
# #
# Chains the same edge middlewares as the honeyDue API ingress: cloudflare-only # Middlewares match the honeyDue API ingress (security-headers + rate-limit).
# (reject non-Cloudflare source IPs), security-headers, and the general # The cloudflare-only middleware is intentionally NOT applied here: on this
# rate-limit. Kratos's self-service flows are multi-request, so the strict # cluster, klipper-lb SNATs the source IP before Traefik sees it, so
# auth-rate-limit (5/min) is intentionally NOT used here — Kratos applies its # cloudflare-only's IP allowlist rejects every legitimate Cloudflare request
# own per-flow protections. # (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 # OPERATOR: confirm the cloudflare-origin-cert TLS secret covers
# auth.myhoneydue.com (apex + wildcard origin cert), and add the # auth.myhoneydue.com (apex + wildcard origin cert), and add the
@@ -18,7 +24,7 @@ metadata:
app.kubernetes.io/name: kratos app.kubernetes.io/name: kratos
app.kubernetes.io/part-of: honeydue app.kubernetes.io/part-of: honeydue
annotations: 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: spec:
ingressClassName: traefik ingressClassName: traefik
tls: tls: