AUTH4D-335 Per-IP rate limits group IPv6 clients by /64

No endpoint or response shape changes. Every per-IP rate limit (email and SMS code sends, code and password attempts, guest creation, device and account-link polling, the Stitch webhook budget) now keys IPv6 clients by their /64 prefix instead of the full address:

  • IPv4 addresses are used as is.
  • IPv6 addresses have their low 64 bits zeroed and are written in canonical form (2001:db8:1:2:aaaa::1 and 2001:0db8:0001:0002::7 both count as 2001:db8:1:2::/64).
  • IPv4-mapped IPv6 (::ffff:203.0.113.7) counts as the IPv4 address.
  • An edge address that is not a valid IPv4 or IPv6 address is treated like a missing one: the endpoints that need an IP budget fail closed with 503 temporarily_unavailable.

The address comes only from CF-Connecting-IP in staging and production, as before. Nothing in the API uses the client address for anything other than rate limits.

Deploy note: existing IPv6 budgets are keyed by the full address, so the first deploy starts every IPv6 client with a fresh budget once. IPv4 budgets are unaffected.

Source: docs/api-spec/auth4d-335.md