railiance-apps/manifests/informed-decision-http-redirect.yaml

63 lines
2.5 KiB
YAML
Raw Normal View History

feat(informed-decision): HTTP -> HTTPS redirect for decisions.coulomb.social The main Ingress is websecure-only per the forgejo pattern, so port 80 was unrouted for this host and plain http:// returned Traefik's default 404. Adds a redirectScheme Middleware plus a web-entrypoint Ingress, following the reuse-surface pattern. Pins router.priority: "1" on the redirect. cert-manager solves HTTP-01 by creating a solver Ingress on this same host and entrypoint, so a catch-all "/" redirect competes with it directly. Traefik would normally settle that by rule length, but reuse-surface's 2026-07-07 report is exactly a case of a specific rule losing to a catch-all when precedence was left implicit -- and here the symptom would not be a visible 404 but a silently failed renewal ~60 days out, surfacing as an expired certificate on the origin backing an OIDC redirect URI. Verified by probe twice: with a solver-shaped Ingress present the challenge path returns 200 (solver wins) while "/" still redirects; with it absent the redirect correctly catches both. Probe was throwaway and is not committed; the runbook carries the table to recreate it. GET returns 301 and HEAD 308. That split is Traefik's own behaviour on this cluster, not a defect here -- reuse.coulomb.social does the same. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EJbh7o7UWF4tQ5jxygnNGu Assistant: claude-code Assistant-Model: opus Assistant-Process: 2072522@bnt-lap001 Assistant-Session: 46173adf-7302-4ede-99d6-963b61359928
2026-09-10 16:57:28 +02:00
# HTTP -> HTTPS redirect for decisions.coulomb.social.
#
# manifests/informed-decision-ingress.yaml is websecure-only (forgejo pattern),
# which leaves port 80 unrouted for this host: plain http:// returned Traefik's
# default 404 rather than redirecting. This adds the redirect, following the
# reuse-surface pattern (reuse/reuse-surface-http-redirect + a redirectScheme
# Middleware).
#
# ROUTER PRIORITY IS LOAD-BEARING. cert-manager solves HTTP-01 by creating a
# temporary solver Ingress on this same host and this same `web` entrypoint,
# serving /.well-known/acme-challenge/<token>. A catch-all `/` redirect on the
# same entrypoint competes with it. Traefik would normally resolve that by rule
# length -- the solver's Path rule is far longer than PathPrefix(`/`) -- but
# reuse-surface reported on 2026-07-07 that relying on implicit precedence is
# exactly how a specific rule ends up swallowed by a catch-all, and there the
# symptom was a 404 someone noticed. Here the symptom would be a silently failed
# renewal roughly 60 days out, i.e. an expired certificate on the origin backing
# an OIDC redirect URI.
#
# So priority is pinned explicitly and low. Traefik gives the highest-priority
# matching router the request; any cert-manager solver (which uses the default
# computed priority, an order of magnitude larger) outbids this one. Verified by
# probe on 2026-09-10 -- see docs/informed-decision-origin.md.
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: informed-decision-redirect-https
namespace: informed-decision
labels:
app.kubernetes.io/name: informed-decision
app.kubernetes.io/component: redirect
spec:
redirectScheme:
scheme: https
permanent: true
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: informed-decision-http-redirect
namespace: informed-decision
labels:
app.kubernetes.io/name: informed-decision
app.kubernetes.io/component: redirect
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: web
traefik.ingress.kubernetes.io/router.middlewares: informed-decision-informed-decision-redirect-https@kubernetescrd
# Deliberately low: ACME solver routers must win on this entrypoint.
traefik.ingress.kubernetes.io/router.priority: "1"
spec:
ingressClassName: traefik
rules:
- host: decisions.coulomb.social
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: informed-decision
port:
number: 80