Edge rate limiting: custom Caddy build + rate_limit block #48

Stängd
öppnade 2026-07-09 23:03:58 +00:00 av supernaut · 2 kommentarer
Ägare

Custom Caddy build (xcaddy + caddy-ratelimit), distributed like the on-host kanidm-provision image; add a rate_limit block on the www host covering /api/signup and /api/invites. Record a new ADR (amends ADR 0005).

Epic: gitborg/gitborg-docs#7

Custom Caddy build (xcaddy + caddy-ratelimit), distributed like the on-host kanidm-provision image; add a `rate_limit` block on the `www` host covering /api/signup and /api/invites. Record a new ADR (amends ADR 0005). Epic: gitborg/gitborg-docs#7
Upphovsperson
Ägare

Design/plan drafted (in bitborg-internal plans/2026-07-21-edge-rate-limiting-design.md). Summary:

Getting rate_limit in: mholt/caddy-ratelimit isn't in the official image, so build a custom Caddy. Recommend an on-host build (mirror the kanidm-provision pattern: staged Containerfile + podman_image state: build, native amd64, rebuild only on version bump) using Caddy's official caddy:2.11.4-builder-alpine (ships xcaddy) → copy the binary onto caddy:2.11.4-alpine. Pin the custom tag in the caddy role vars so the monitoring VM stays on stock upstream. CI+registry (ADR 0019 style) is deferred to Phase 3 — infra has no CI pipeline yet. Renovate tracks both the base Caddy version and the (pre-1.0) module ref; the existing #63 running-image verify guards a green apply.

Policy (numbers = maintainer's call): per-surface zones keyed by {remote_host} (real IP via #81/#129, ipv6_prefix 56) — sign-up + Cap captcha (~10/min, the original scope), auth/login (~20/min), API (~120/min), general www (~300/min); git-over-HTTPS + /v2 registry NOT limited (protects clones/CI/runner egress — same reason as the fail2ban /v2 exclusion #179). Note the invite flow is retired (ADR 0029) — no invite zone needed.

Layering: nftables → fail2ban (reactive 401 ban, #127) → Caddy rate_limit (proactive 429) → app-layer limiter (already in bitborg-web src/lib/rate-limit.ts, complementary). Do NOT feed 429s into fail2ban in Phase 1 (false-positive risk for shared-NAT/CI); revisit as a separate loose jail later.

Rollout: build+pin with no zones (prove drop-in) → add sign-up/captcha zone generously → observe via Loki 429s + a Grafana panel (module exposes Prometheus metrics) → tune → extend. Record a new ADR amending 0005.

Design/plan drafted (in bitborg-internal `plans/2026-07-21-edge-rate-limiting-design.md`). Summary: **Getting `rate_limit` in:** `mholt/caddy-ratelimit` isn't in the official image, so build a custom Caddy. Recommend an **on-host build** (mirror the kanidm-provision pattern: staged Containerfile + `podman_image state: build`, native amd64, rebuild only on version bump) using Caddy's official `caddy:2.11.4-builder-alpine` (ships xcaddy) → copy the binary onto `caddy:2.11.4-alpine`. Pin the custom tag in the **caddy role vars** so the monitoring VM stays on stock upstream. CI+registry (ADR 0019 style) is deferred to Phase 3 — infra has no CI pipeline yet. Renovate tracks both the base Caddy version and the (pre-1.0) module ref; the existing #63 running-image verify guards a green apply. **Policy (numbers = maintainer's call):** per-surface zones keyed by `{remote_host}` (real IP via #81/#129, `ipv6_prefix 56`) — sign-up + Cap captcha (~10/min, the original scope), auth/login (~20/min), API (~120/min), general www (~300/min); **git-over-HTTPS + `/v2` registry NOT limited** (protects clones/CI/runner egress — same reason as the fail2ban `/v2` exclusion #179). Note the invite flow is retired (ADR 0029) — no invite zone needed. **Layering:** nftables → fail2ban (reactive 401 ban, #127) → Caddy rate_limit (proactive 429) → app-layer limiter (already in bitborg-web `src/lib/rate-limit.ts`, complementary). **Do NOT feed 429s into fail2ban in Phase 1** (false-positive risk for shared-NAT/CI); revisit as a separate loose jail later. **Rollout:** build+pin with no zones (prove drop-in) → add sign-up/captcha zone generously → observe via Loki 429s + a Grafana panel (module exposes Prometheus metrics) → tune → extend. Record a new ADR amending 0005.
Upphovsperson
Ägare

Phase 1 shipped + live (PR #186, ADR 0032): custom caddy-ratelimit build + the sign-up/captcha rate_limit zone, keyed by real client IP (#81/#129). Phase 2 — auth/API/general zones + git/registry exemptions — is future tuning under epic bitborg-docs#7. Closing the Phase-1 scope of this issue.

Phase 1 shipped + live (PR #186, ADR 0032): custom caddy-ratelimit build + the sign-up/captcha rate_limit zone, keyed by real client IP (#81/#129). Phase 2 — auth/API/general zones + git/registry exemptions — is future tuning under epic bitborg-docs#7. Closing the Phase-1 scope of this issue.
Logga in för att delta i denna konversation.
Ingen milstolpe
Inga tilldelade
1 deltagare
Notiser
Förfallodatum
Förfallodatumet är ogiltigt eller utanför gränserna. Använd formatet "åååå-mm-dd".

Inget förfallodatum satt.

Beroenden

Inga beroenden satta

Referens
bitborg/bitborg-infra#48
Ingen beskrivning angiven.