Skip to contentSkip to navigation

Rate Limiting

Own Auth rate-limits sensitive authentication operations automatically. Postgres and Cloudflare D1 store counters beside the auth data, with no separate rate-limit service to configure.

Overview

Own Auth applies built-in rate limits to sensitive authentication entry points. Core limits do not need middleware or separate configuration.

For the account and network limits around the built-in counters, read Rate limiting authentication endpoints.

Built-in limits

OperationIdentifierDefault limitWindow
Sign upNormalised email510 minutes
Password sign inNormalised email1010 minutes
Change passwordUser ID510 minutes
Magic-link requestNormalised email510 minutes
Email-verification requestNormalised email510 minutes
Password-reset requestNormalised email515 minutes
SMS-code requestNormalised phone number515 minutes
SMS-code verificationNormalised phone number1015 minutes
Trusted external-provider sign inProvider account ID2010 minutes
OAuth startIP address, when available2010 minutes
OAuth callbackIP address, when available3010 minutes
Google One Tap prepareIP address, when available2010 minutes
Google One Tap verifyIP address, when available3010 minutes
SAML startIP address and connection, when available2010 minutes
SAML callbackIP address and connection, when available3010 minutes
SCIM requestSCIM connection1,2001 minute
Failed SCIM authenticationIP address, when available301 minute
Authorization-server startIP address, when available6010 minutes
Authorization-server interaction completionUser ID3010 minutes
Authorization-server token, revocation, and client introspection endpointsIP address, otherwise client ID12010 minutes
Protected-resource introspectionProtected-resource identity6,0001 minute
Failed protected-resource authenticationIP address, when available301 minute
API-key creationUser or organisation owner201 hour
Organisation inviteOrganisation ID101 hour

These limits reduce password guessing, credential stuffing, repeated email and SMS sends, excessive invitations, and excessive key creation.

SMS codes allow five wrong guesses by default. MFA challenges also allow five failed attempts by default. These per-credential attempt limits are enforced separately from the shared rate-limit store through sms.maxAttempts and mfa.maxAttempts.

What happens when a limit is exceeded

Own Auth throws AuthError with:

  • code: rate_limited
  • statusCode: 429
  • safeMessage: Too many attempts. Try again later.
ts
import { isAuthError } from "own-auth";

try {
  await auth.signInEmailPassword({ email, password });
} catch (error) {
  if (isAuthError(error) && error.code === "rate_limited") {
    return res.status(error.statusCode).json({
      error: error.safeMessage,
    });
  }

  throw error;
}

AuthError does not currently include a retryAfterMs value. Do not read or document that field unless the public error contract adds it.

Default durable store

With the default Postgres setup, Own Auth stores counters in own_auth_rate_limits in the same database as the auth data. The Cloudflare D1 adapter uses the same table in D1.

The counters survive server restarts and are shared by every application instance connected to that database. No additional rate-limit configuration is needed for the default setup.

ts
const auth = createOwnAuth({
  tokenPepper: process.env.OWN_AUTH_TOKEN_PEPPER,
});

Configuration

Most built-in core operation limits and windows are not configurable. Protected-resource operators can size remote introspection for their traffic with authorizationServer.resourceIntrospectionRequestsPerMinute and authorizationServer.failedIntrospectionAttemptsPerMinute. SCIM operators can configure scim.requestLimit, scim.requestWindowMs, scim.failedAuthLimit, and scim.failedAuthWindowMs. Authenticated SCIM traffic shares one limit per connection. Failed SCIM authentication is limited only when the handler receives a trusted IP address through getRequestContext.

Plugins may declare their own namespaced endpoint rate limits, but cannot replace or weaken core limits.

Next step

Set up Audit logs to track auth events, or review the full Security model.