---
title: Security
description: "Security controls in convex-auth: 2FA, CAPTCHA, breach checks, rate limits, sessions, and keys."
sidebar:
  order: 14
---

`convex-auth` gives you several security controls out of the box. Most are configured in `convex/auth.ts`; the rest are environment and deployment practices.

## Passwords

### Breach detection

`emailAndPassword.checkBreach` checks new passwords against Have I Been Pwned and rejects known-breached ones.

```ts convex/auth.ts
export const auth = convexAuth({
  component: components.convexAuth,
  emailAndPassword: {
    enabled: true,
    checkBreach: true,
    minPasswordLength: 8,
    maxPasswordLength: 128,
  },
});
```

### Password reset

By default `revokeSessionsOnPasswordReset` is `true`. When a user resets their password, all active sessions are invalidated immediately.

## Rate limiting

Configure sign-in attempt rate limits per email:

```ts convex/auth.ts
export const auth = convexAuth({
  component: components.convexAuth,
  emailAndPassword: {
    enabled: true,
    rateLimit: {
      windowMs: 15 * 60 * 1000,
      maxAttempts: 5,
    },
  },
});
```

## CAPTCHA

Protect the sign-up and password-reset endpoints with a CAPTCHA provider:

```ts convex/auth.ts
export const auth = convexAuth({
  component: components.convexAuth,
  captcha: {
    provider: "cloudflare-turnstile",
    secretKey: process.env.TURNSTILE_SECRET_KEY!,
  },
});
```

Supported providers: `cloudflare-turnstile`, `google-recaptcha`, `hcaptcha`, and `captchafox`. The default `endpoints` are `/api/auth/sign-up/email`, `/api/auth/sign-up`, and `/api/auth/request-password-reset`.

## Two-factor authentication

TOTP is native. When 2FA is enabled, `signIn` returns a `twoFactorChallengeToken`. The client must verify the TOTP code or a backup code before a session token is issued.

```tsx
const { data } = await client.signIn.email({ email, password });
// data.twoFactorChallengeToken is set if 2FA is enabled
await client.twoFactor.verifyTotp({ code, trustDevice: true });
```

Set `trustDevice` to skip 2FA on the current device for the configured trust window.

## JWT and JWKS

Sessions are RS256 JWTs.

- `JWT_PRIVATE_KEY` — the private JWK used to sign tokens. Never commit it.
- `JWKS` — the public JWKS used to verify tokens on every Convex request.
- Use `convex env set` for both local and production.
- Rotate keys by generating a new pair, updating `JWKS`, and then updating `JWT_PRIVATE_KEY`.

## Trusted origins

All email links, OAuth callbacks, and verification redirects require an allowed origin. Configure the origins in the provider config:

```ts convex/auth.ts
export const auth = convexAuth({
  component: components.convexAuth,
  emailAndPassword: {
    trustedOrigins: ["https://yourdomain.com", "https://app.yourdomain.com"],
  },
  oauth: {
    trustedOrigins: ["https://yourdomain.com", "https://app.yourdomain.com"],
  },
});
```

## Session and refresh tokens

- Access tokens are short-lived (default 7 days).
- Refresh tokens are long-lived (default 30 days).
- Revoke sessions from the client with the session-list hooks.
- Password reset revokes all sessions by default.
- Revocation is enforced on every validation path — a revoked session's token is rejected by session resolution, token verification, the bearer HTTP endpoints, OAuth account linking, and MCP authorization immediately, not just at expiry.
- Session listings never expose raw tokens; `listSessions` returns `isCurrent` instead.
- Revoking a passkey revokes every session and refresh token it created, including sessions minted after a two-factor challenge.

## Security checklist

1. **Use strong signing keys**

    Generate RS256 keys with `jose` and keep them in Convex env, not in the repo.

2. **Enable breach checks**

    Set `checkBreach: true` for email/password.

3. **Add CAPTCHA**

    Protect sign-up and password reset in production.

4. **Rate-limit sign-in**

    Configure `rateLimit` for email/password and any custom actions.

5. **Pin trusted origins**

    Set `trustedOrigins` for email, OAuth, and magic links.

6. **Use 2FA for admin accounts**

    Require TOTP for accounts with elevated privileges.

7. **Rotate keys on suspicion**

    Regenerate `JWT_PRIVATE_KEY` and `JWKS` if a key leaks.
