---
title: Concepts
description: The five building blocks of convex-auth for engineers new to Convex.
sidebar:
  order: 2
---

If you have never built auth in Convex, start here. `convex-auth` is not an external service. It is a set of Convex components, actions, and React hooks that keep users, sessions, and identities in your Convex database.

## The five building blocks

**[Component](/convex-auth/quickstart)**

The `convexAuth` component stores tables for users, identities, sessions, and refresh tokens.

**[Config](/convex-auth/configuration)**

The `convexAuth({...})` helper in `convex/auth.ts` enables providers and exposes actions.

**[Actions](/convex-auth/react)**

Convex actions handle sign-up, sign-in, password reset, OAuth callbacks, and 2FA.

**[HTTP routes](/convex-auth/oauth)**

`auth.addHttpRoutes(http)` mounts email verification, password reset, and OAuth callback routes.

**[React client](/convex-auth/react)**

`ConvexAuthClientProvider` and `useAuthActions` call the actions from your UI.

## Auth state lives in Convex

`convex-auth` stores everything in your Convex database:

| Auth concept   | Convex table          | Notes                                     |
| -------------- | --------------------- | ----------------------------------------- |
| `user`         | `users`               | One row per person.                       |
| `account`      | `auth_identities`     | Email, OAuth, TOTP, and backup-code data. |
| `session`      | `auth_sessions`       | JWT + refresh token sessions.             |
| `refreshToken` | `auth_refresh_tokens` | Long-lived refresh tokens.                |

Because the data is Convex data, you can query it with `ctx.db` and write `rules`/`authz` against the same tables as the rest of your app. There is no external API to sync.

## Sessions are JWTs, not opaque tokens

When a user signs in, `convex-auth` mints an RS256 JWT. The token contains the user and session id. Convex verifies the token with the `JWKS` env var on every request. The access token is short-lived; a refresh token in `auth_refresh_tokens` rotates it without another login.

- Set `JWT_PRIVATE_KEY` and `JWKS` once.
- Send the access token in the `Authorization` header (React client handles this).
- Convex re-hydrates `ctx.auth` for every query/mutation/action from that token.

## Non-deterministic work happens in actions

Convex queries and mutations must be deterministic. Anything that touches a third party, a network, or `crypto.subtle` lives in a Convex action:

- Password hashing (Argon2id / bcrypt) runs in an action.
- OAuth code exchange and `crypto.randomUUID()` run in an action.
- Email sending is delegated to your `sendEmail` callback, which you can call from an action.

This is the same split Convex Auth 2.0 uses: auth data in the DB, auth work in actions.

## What is wired where

- convex/
  - auth.config.ts
    - registers `convex-auth` as the auth provider
  - convex.config.ts
    - mounts the `convexAuth` component
  - auth.ts
    - calls `convexAuth({...})` and re-exports actions
  - http.ts
    - calls `auth.addHttpRoutes(http)`
- src/
  - main.tsx
    - wraps with `ConvexAuthClientProvider`

## Next steps

1. **Install**

    Set up the packages and keys in [`Installation`](/convex-auth/installation).

2. **Configure**

    Walk through the end-to-end wiring in [`Quickstart`](/convex-auth/quickstart).

3. **Reference**

    Look up every option in [`Configuration`](/convex-auth/configuration).
