[PR #6321] feat: add keyGenerator option for rate limit #23492

Open
opened 2026-04-15 21:45:45 -05:00 by GiteaMirror · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/better-auth/better-auth/pull/6321
Author: @k8adev
Created: 11/26/2025
Status: 🔄 Open

Base: nextHead: feat/custom-rate-limit-keys


📝 Commits (3)

  • f45683c feat(rate-limit): add keyGenerator option for custom rate limit identifiers
  • 70fe95a docs(rate-limit): add keyGenerator documentation
  • f151c19 fix(rate-limit): fallback to IP when keyGenerator returns empty or throws

📊 Changes

4 files changed (+160 additions, -19 deletions)

View changed files

📝 docs/content/docs/concepts/rate-limit.mdx (+35 -15)
📝 packages/better-auth/src/api/rate-limiter/index.ts (+25 -4)
📝 packages/better-auth/src/api/rate-limiter/rate-limiter.test.ts (+88 -0)
📝 packages/core/src/types/init-options.ts (+12 -0)

📄 Description

Currently, the rate limiter generates keys based on the client's IP address configurable via ipAddressHeaders.

This works well for most cases, but there are scenarios where IP-based rate limiting is not ideal:

  • NAT/CGNAT: Multiple users behind the same NAT gateway share the same public IP, causing false positives
  • Corporate networks: Thousands of users may share the same corporate IP
  • VPN users: Multiple users share the same VPN exit node IP

I encountered this issue on Vercel, where IPv6 clients connect via NAT64 gateways with shared IPs since the platform doesn't support IPv6 directly. This causes multiple unrelated users to be rate-limited together.

Solution

Add an optional keyGenerator function to the rate limit configuration:

  export const auth = betterAuth({
    rateLimit: {
      keyGenerator: (request) => {
        return request.headers.get("x-fingerprint"); // or any other custom header
      },
    },
  });

The request path is automatically appended to the returned value.

Changes

  • Added keyGenerator option to BetterAuthRateLimitOptions type
  • Implemented keyGenerator logic in rate limiter
  • Added test for custom key generator
  • Added documentation

Backwards Compatibility

This is a non-breaking change. If keyGenerator is not provided, the current behavior is preserved.


Summary by cubic

Adds an optional rateLimit.keyGenerator to build custom rate limit keys from the request (e.g., a header) instead of the client IP. This avoids shared-IP throttling and falls back to IP if the generator is missing, empty, or errors; the request path is always appended.

  • New Features
    • Added rateLimit.keyGenerator to BetterAuthRateLimitOptions.
    • Implemented key generation logic in the rate limiter with path suffixing.
    • Added tests and documentation for custom key generation.

Written for commit f151c19345. Summary will update automatically on new commits.


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/better-auth/better-auth/pull/6321 **Author:** [@k8adev](https://github.com/k8adev) **Created:** 11/26/2025 **Status:** 🔄 Open **Base:** `next` ← **Head:** `feat/custom-rate-limit-keys` --- ### 📝 Commits (3) - [`f45683c`](https://github.com/better-auth/better-auth/commit/f45683c912bcf7782c53f77b93f72401b3593350) feat(rate-limit): add keyGenerator option for custom rate limit identifiers - [`70fe95a`](https://github.com/better-auth/better-auth/commit/70fe95a5067955e0f63eca01122a4b39899cc26d) docs(rate-limit): add keyGenerator documentation - [`f151c19`](https://github.com/better-auth/better-auth/commit/f151c19345f83d0101e9dcc0fba61aba095d114d) fix(rate-limit): fallback to IP when keyGenerator returns empty or throws ### 📊 Changes **4 files changed** (+160 additions, -19 deletions) <details> <summary>View changed files</summary> 📝 `docs/content/docs/concepts/rate-limit.mdx` (+35 -15) 📝 `packages/better-auth/src/api/rate-limiter/index.ts` (+25 -4) 📝 `packages/better-auth/src/api/rate-limiter/rate-limiter.test.ts` (+88 -0) 📝 `packages/core/src/types/init-options.ts` (+12 -0) </details> ### 📄 Description Currently, the rate limiter generates keys based on the client's IP address configurable via `ipAddressHeaders`. This works well for most cases, but there are scenarios where IP-based rate limiting is not ideal: - NAT/CGNAT: Multiple users behind the same NAT gateway share the same public IP, causing false positives - Corporate networks: Thousands of users may share the same corporate IP - VPN users: Multiple users share the same VPN exit node IP I encountered this issue on Vercel, where IPv6 clients connect via NAT64 gateways with shared IPs since the platform doesn't support IPv6 directly. This causes multiple unrelated users to be rate-limited together. ## Solution Add an optional `keyGenerator` function to the rate limit configuration: ```ts export const auth = betterAuth({ rateLimit: { keyGenerator: (request) => { return request.headers.get("x-fingerprint"); // or any other custom header }, }, }); ``` The request path is automatically appended to the returned value. ## Changes - Added keyGenerator option to BetterAuthRateLimitOptions type - Implemented keyGenerator logic in rate limiter - Added test for custom key generator - Added documentation ## Backwards Compatibility This is a non-breaking change. If `keyGenerator` is not provided, the current behavior is preserved. <!-- This is an auto-generated description by cubic. --> --- ## Summary by cubic Adds an optional rateLimit.keyGenerator to build custom rate limit keys from the request (e.g., a header) instead of the client IP. This avoids shared-IP throttling and falls back to IP if the generator is missing, empty, or errors; the request path is always appended. - **New Features** - Added rateLimit.keyGenerator to BetterAuthRateLimitOptions. - Implemented key generation logic in the rate limiter with path suffixing. - Added tests and documentation for custom key generation. <sup>Written for commit f151c19345f83d0101e9dcc0fba61aba095d114d. Summary will update automatically on new commits.</sup> <!-- End of auto-generated description by cubic. --> --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
GiteaMirror added the pull-request label 2026-04-15 21:45:45 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#23492