You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 1cb95de
Browse filesBrowse the repository at this point in the historyBrowse files
Explain auth rate limits behind a proxy and in end-to-end tests
Deployed Cloudflare apps now apply Better Auth's default rate limits per
client IP. A server that calls auth for many users shares one IP, and
tests that sign in often hit the sign-in limit. Show a secret-header rule
that skips the limits only for a trusted caller, and say that a proxy
using it must limit the requests it forwards.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: docs/guide/auth.md
+32Lines changed: 32 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -131,6 +131,38 @@ Local development needs no secret setup. To preview a production build locally,
131
131
132
132
Deployed apps on Cloudflare limit auth requests per client IP with Better Auth's defaults, for example 3 sign-in attempts per 10 seconds. Each Worker instance keeps its own count. Change or turn off the limits with `rateLimit` in `auth.ts`. To share one count across instances, set `rateLimit: { storage: 'database' }`, then run `void db generate` for a direct Cloudflare deploy.
133
133
134
+
### Proxies and end-to-end tests
135
+
136
+
All requests from one IP share one count. Two common setups reach the limits:
137
+
138
+
- A server calls your auth endpoints for your users, such as a backend-for-frontend, a rewrite from Vercel or nginx, or another Worker's `fetch`. All of those users share that server's IP.
139
+
- End-to-end tests sign up or sign in many times against a deployed app.
140
+
141
+
Don't read the client IP from `x-forwarded-for` instead: any client can send that header. Give the trusted caller a secret header, and skip the limits only for requests that carry it:
`'/**'` matches every auth endpoint. Returning `false` skips the limit, and returning `rule` keeps the default limit for everyone else. Declare `AUTH_TRUSTED_KEY: string().optional()` in `env.ts` and set it with `void secret put AUTH_TRUSTED_KEY` (see [Environment variables](./env-vars.md#production-server-values)).
160
+
161
+
Your app no longer limits requests that carry the key, so:
162
+
163
+
- A proxy that sends it must limit every auth request it forwards for each of its users, including sign-up, password reset and verification emails.
164
+
- A test runner should send it only to your app. Never put the key in code that runs in your users' browsers.
165
+
134
166
## Customization
135
167
136
168
For advanced configuration, create `auth.ts` at the project root and export `defineAuth(...)`:
0 commit comments