
# Authentication Overview

Sovrium ships authentication as a first-class platform capability powered by [Better Auth](https://better-auth.com). A single `auth` block in your app config enables sign-up, sign-in, sessions, role-based access control, and admin user management — no auth code to write.

The `auth` block answers one question: **does this app have users?** When it is present, authentication is on; when it is omitted, every `/api/auth/*` route returns `404` and the app is fully public.

```yaml
auth:
  strategies:
    - type: emailAndPassword
  defaultRole: member
```

That four-line config gives you working email/password sign-up and sign-in, server-managed sessions, the three built-in roles, and the admin user-management endpoints.

## Enabling Authentication

Authentication is enabled by the **presence** of the `auth` object. There is no `auth.enabled: true` flag.

| State          | Result                                                                                        |
| -------------- | --------------------------------------------------------------------------------------------- |
| `auth` omitted | App is public. All `/api/auth/*` routes return `404`. No identity, no sessions.               |
| `auth` present | Auth is on. Sign-up/sign-in routes mount, sessions are issued, RBAC and admin features apply. |

At minimum the `auth` block requires a non-empty `strategies` array (at least one strategy, no duplicate types). Everything else is optional and layered on top.

:::callout
**Admin features are always on.** When `auth` is configured, user management, role assignment, and impersonation endpoints are mounted automatically — there is no separate toggle. The first user to register becomes an admin (`firstUserAdmin`).
:::

## The `auth` Config Block

The `auth` object accepts the following top-level properties. Each links to its dedicated page.

| Property                | Description                                                                                                                                                         |
| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `strategies`            | **Required.** Array of authentication strategies (email/password, magic link, OAuth). At least one; no duplicate types. See [Strategies](/en/docs/auth-strategies). |
| `allowSignUp`           | Boolean. Controls self-registration. `true` (default) lets anyone sign up; `false` restricts user creation to admins. See [Strategies](/en/docs/auth-strategies).   |
| `roles`                 | Array of custom role definitions layered on top of the built-in roles. See [Roles & RBAC](/en/docs/auth-roles-rbac).                                                |
| `defaultRole`           | Role assigned to new users on registration. Defaults to `member`. See [Roles & RBAC](/en/docs/auth-roles-rbac).                                                     |
| `groups`                | User groups for many-to-many membership and group-scoped permissions. See [Groups](/en/docs/auth-groups).                                                           |
| `twoFactor`             | TOTP-based two-factor authentication. Requires the `emailAndPassword` strategy. See [Two-Factor](/en/docs/auth-two-factor).                                         |
| `emailTemplates`        | Custom subject/body for authentication emails (verification, reset, magic link, OTP, invitation, …). See [Strategies](/en/docs/auth-strategies).                    |
| `invitationTokenExpiry` | Lifetime of single-use admin invitation tokens. Duration string (`72h`, `7d`) or milliseconds. Defaults to `72h`.                                                   |
| `scopeTables`           | Tables referenced by the multi-tenant `user_access` junction. Drives `$currentUser.assignments` scoping. See [Sessions](/en/docs/auth-sessions).                    |
| `landingPath`           | Engine-resolver mount path for per-role post-login landing. See [Post-Login Landing](/en/docs/auth-post-login).                                                     |
| `noAccessPath`          | Fallback path when no role's `defaultLanding` matches the session. Defaults to `/403`. See [Post-Login Landing](/en/docs/auth-post-login).                          |

Infrastructure secrets (signing keys, callback URLs, OAuth credentials) live in environment variables — **not** in this schema. See [Environment Variables](/en/docs/env-vars).

## Default Roles

Every Sovrium app with auth configured has three built-in roles available without any configuration. They cannot be redefined.

| Role     | Level | Access                                                                |
| -------- | ----- | --------------------------------------------------------------------- |
| `admin`  | 80    | Full access — manage users, roles, settings; all table permissions.   |
| `member` | 40    | Standard access to application resources (the default new-user role). |
| `viewer` | 10    | Read-only access.                                                     |

The numeric **level** establishes a hierarchy (higher = more privileged) used by permission resolution. Custom roles slot into this hierarchy with their own `level`. See [Roles & RBAC](/en/docs/auth-roles-rbac) for definitions, hierarchy, and admin roles.

## Required Environment Variables

Two environment variables are required for production auth:

| Variable      | Purpose                                                                                        |
| ------------- | ---------------------------------------------------------------------------------------------- |
| `AUTH_SECRET` | Secret key for signing tokens and encrypting sessions. Use a strong random string (32+ chars). |
| `BASE_URL`    | Base URL of the app (e.g. `https://myapp.com`). Used for auth callback URLs and email links.   |

```bash
AUTH_SECRET=your-strong-random-secret-32-chars-min
BASE_URL=https://myapp.com
```

:::callout
**Never commit `AUTH_SECRET`.** Treat it like a database password. Rotating it invalidates all active sessions. See [Environment Variables](/en/docs/env-vars) for the full list, including OAuth `{PROVIDER}_CLIENT_ID` / `{PROVIDER}_CLIENT_SECRET` pairs.
:::

## Complete Example

```yaml
auth:
  # Two ways in: credentials + Google social login
  strategies:
    - type: emailAndPassword
      minPasswordLength: 12
      requireEmailVerification: true
    - type: oauth
      providers: [google, github]

  # Self-registration on, new users start as viewers
  allowSignUp: true
  defaultRole: viewer

  # One extra role beyond the built-ins
  roles:
    - name: editor
      description: Can edit content
      level: 30

  # Group membership for field-level permissions
  groups:
    - name: marketing
    - name: finance

  # TOTP 2FA (requires emailAndPassword above)
  twoFactor:
    issuer: MyApp
    backupCodes: true
```

## Where to Go Next

- [Strategies](/en/docs/auth-strategies) — email/password, magic link, email-OTP, social/OAuth, registration control, and email templates.
- [Roles & RBAC](/en/docs/auth-roles-rbac) — role definitions, hierarchy, and admin roles.
- [Groups](/en/docs/auth-groups) — many-to-many membership and group-based permissions.
- [Sessions](/en/docs/auth-sessions) — session config, revocation, and active-scope sessions.
- [Two-Factor](/en/docs/auth-two-factor) — TOTP setup and recovery codes.
- [OAuth Server](/en/docs/auth-oauth-server) — Sovrium as an OAuth/OIDC authorization server.
- [Post-Login Landing](/en/docs/auth-post-login) — per-role landing and `$currentUser.assignments` interpolation.
- [Table Permissions](/en/docs/table-permissions) — how roles and groups gate per-table and per-field access.
