
# Authentication Strategies

`auth.strategies` is a **required, non-empty array** declaring how users authenticate. Each entry is a discriminated union keyed by `type`. At least one strategy is required, and **no two entries may share the same `type`**.

```yaml
auth:
  strategies:
    - type: emailAndPassword
    - type: oauth
      providers: [google, github]
```

| `type`             | Description                                                        |
| ------------------ | ------------------------------------------------------------------ |
| `emailAndPassword` | Traditional credential-based sign-up and sign-in.                  |
| `magicLink`        | Passwordless sign-in via a one-time email link.                    |
| `oauth`            | Social login with external identity providers (Google, GitHub, …). |

:::callout
**Email-OTP is enabled differently.** There is no `type: emailOtp` strategy. Email-OTP turns on automatically when you supply an `auth.emailTemplates.emailOtp` template (see [Email-OTP](#email-otp) below).
:::

## Email & Password

The most common strategy. Credentials are validated server-side and a session is issued on success.

```yaml
auth:
  strategies:
    - type: emailAndPassword
      minPasswordLength: 12
      maxPasswordLength: 128
      requireEmailVerification: true
      autoSignIn: true
```

| Property                   | Description                                                                                |
| -------------------------- | ------------------------------------------------------------------------------------------ |
| `minPasswordLength`        | Minimum password length, 6–128. Defaults to `8`.                                           |
| `maxPasswordLength`        | Maximum password length, 8–256. Defaults to `128`.                                         |
| `requireEmailVerification` | Boolean. When `true`, users must verify their email before sign-in. Defaults to `false`.   |
| `autoSignIn`               | Boolean. When `true`, users are signed in automatically after sign-up. Defaults to `true`. |

When `requireEmailVerification: true`, a verification email is sent on sign-up using the `verification` template (see [Email Templates](#email-templates)).

## Magic Link

Passwordless authentication. The user enters their email, receives a one-time link, and is signed in by clicking it. Requires SMTP to be configured (see [Environment Variables](/en/docs/env-vars)).

```yaml
auth:
  strategies:
    - type: magicLink
      expirationMinutes: 30
```

| Property            | Description                                                    |
| ------------------- | -------------------------------------------------------------- |
| `expirationMinutes` | Link lifetime in minutes (positive integer). Defaults to `15`. |

The link body is rendered from the `magicLink` email template when provided.

## Email-OTP

Email-OTP delivers a numeric one-time code by email instead of a link. **It is not a strategy entry** — it activates when you define the `emailOtp` email template:

```yaml
auth:
  strategies:
    - type: emailAndPassword
  emailTemplates:
    emailOtp:
      subject: Your sign-in code
      text: 'Your verification code is $code. It expires shortly.'
```

The presence of `emailTemplates.emailOtp` mounts the email-OTP plugin. The `$code` variable is substituted with the generated one-time code.

## Social / OAuth Providers

Federated login through external identity providers. Credentials are **never** in the schema — they load from environment variables.

```yaml
auth:
  strategies:
    - type: oauth
      providers: [google, github, microsoft, slack, gitlab]
```

| Property    | Description                                                                |
| ----------- | -------------------------------------------------------------------------- |
| `providers` | Non-empty array of provider identifiers. Credentials loaded from env vars. |

Supported providers:

| Provider    | Use case                       |
| ----------- | ------------------------------ |
| `google`    | Google Workspace integration.  |
| `github`    | Developer authentication.      |
| `microsoft` | Enterprise / Azure AD.         |
| `slack`     | Workspace communication.       |
| `gitlab`    | Developer / CI-CD integration. |

Each enabled provider needs a credential pair in the environment:

```bash
GOOGLE_CLIENT_ID=your-client-id
GOOGLE_CLIENT_SECRET=your-client-secret
GITHUB_CLIENT_ID=your-client-id
GITHUB_CLIENT_SECRET=your-client-secret
```

The general form is `{PROVIDER}_CLIENT_ID` and `{PROVIDER}_CLIENT_SECRET`. Callback URLs are derived from `BASE_URL`. See [Environment Variables](/en/docs/env-vars).

## Registration Control

`auth.allowSignUp` decides whether the public can create their own accounts.

```yaml
auth:
  allowSignUp: false
  strategies:
    - type: emailAndPassword
```

| Value            | Behavior                                                                                                       |
| ---------------- | -------------------------------------------------------------------------------------------------------------- |
| `true` (default) | Anyone can self-register via the enabled strategies.                                                           |
| `false`          | Self-registration is disabled. Only admins create users via `POST /api/auth/admin/create-user` or invitations. |

When self-registration is off, admins onboard users with single-use invitation tokens:

```yaml
auth:
  allowSignUp: false
  strategies:
    - type: emailAndPassword
  invitationTokenExpiry: 7d
```

| Property                | Description                                                                                                                   |
| ----------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| `invitationTokenExpiry` | Lifetime of tokens from `POST /api/auth/admin/invite-user`. Duration string (`72h`, `7d`) or milliseconds. Defaults to `72h`. |

:::callout
Shorter expiries suit high-security customer portals; the `72h` default suits B2B onboarding where invitees may not check email immediately. Invitation tokens are single-use and consumed on first successful accept.
:::

## Email Templates

`auth.emailTemplates` customizes the subject and body of authentication emails. Every template is optional — Better Auth supplies sensible defaults. Defining the `emailOtp` template additionally **enables** the email-OTP flow.

```yaml
auth:
  strategies:
    - type: emailAndPassword
    - type: magicLink
  emailTemplates:
    verification:
      subject: Verify your email for MyApp
      text: 'Hi $name, confirm your email: $url'
    resetPassword:
      subject: Reset your password
      text: 'Reset your password: $url'
      html: '<p>Click <a href="$url">here</a> to reset your password.</p>'
    magicLink:
      subject: Your sign-in link
      text: 'Sign in to MyApp: $url'
```

| Template               | When it is sent                                       |
| ---------------------- | ----------------------------------------------------- |
| `verification`         | Email verification after sign-up.                     |
| `resetPassword`        | Password-reset request.                               |
| `magicLink`            | Magic-link sign-in.                                   |
| `emailOtp`             | Email one-time code (its presence enables email-OTP). |
| `twoFactorBackupCodes` | Two-factor backup codes delivery.                     |
| `welcome`              | Welcome email after verification.                     |
| `accountDeletion`      | Account-deletion confirmation.                        |
| `invitation`           | Admin-issued invitation (passwordless onboarding).    |

Each template accepts a required `subject` and optional `text` and/or `html` bodies. Bodies support `$variable` substitution:

| Variable            | Meaning                                                             |
| ------------------- | ------------------------------------------------------------------- |
| `$url`              | Action link (verify, reset, magic link, invitation accept).         |
| `$name`             | Recipient's name.                                                   |
| `$email`            | Recipient's email address.                                          |
| `$code`             | One-time code (email-OTP).                                          |
| `$organizationName` | Organization name (invitations).                                    |
| `$inviterName`      | Name of the admin who sent the invitation (admin invitations only). |

:::callout
Magic link, email-OTP, password reset, and verification emails all require SMTP. When SMTP is unset the app boots with email disabled and logs a warning — those strategies will not deliver. See [Environment Variables](/en/docs/env-vars).
:::

## Related Pages

- [Authentication Overview](/en/docs/auth-overview) — the `auth` block and how strategies fit in.
- [Sessions](/en/docs/auth-sessions) — what happens after a successful sign-in.
- [Two-Factor](/en/docs/auth-two-factor) — adding TOTP on top of email/password.
- [Environment Variables](/en/docs/env-vars) — `AUTH_SECRET`, `BASE_URL`, and OAuth credentials.
