Install and Configure Convex Auth

In this section, we will install Convex Auth, run the initializer to set up the necessary files and keys for authentication, and look at what the initializer set up for us.

In the previous section, we distinguished between authentication (proving who you are) and authorization (proving what you are allowed to do). I also noted that software developers often use “auth” as a catch-all term that covers both. Another term you will hear a lot is OAuth (with a capital “O”). This is a specific authentication method that lets users sign in with an existing account from a third-party provider like GitHub, Google, or Facebook.

When we say “OAuth,” we are talking about the protocol that governs how our app talks to those providers to authenticate users. In this chapter, we will use GitHub OAuth as our authentication method, and Convex Auth will handle the details of the OAuth flow for us.

Install the Packages

Convex Auth is published as @convex-dev/auth. It uses Auth.js internally for OAuth providers, so we also need @auth/core:

pnpm add @convex-dev/auth @auth/core@0.37.0

Run the Initializer

Convex Auth comes with a CLI initializer that generates the files we need and sets up the JWT signing keys. Run it now:

npx @convex-dev/auth

When it asks for SITE_URL, enter http://localhost:5173 (Vite’s default URL for the local development server). We are currently setting up auth for the development environment. When you deploy to production later, you will need to set SITE_URL to your production URL (e.g., the GitHub Pages URL for this app). We will cover the production setup later.

Following this prompt, the initializer will:

  • Configure private and public key (set JWT_PRIVATE_KEY and JWKS on your deployment server)
  • Configure auth config file (creates convex/auth.config.ts)
  • Initialize auth file (creates convex/auth.ts)
  • Configure http file (creates convex/http.ts)

The initializer may also modify the convex/tsconfig.json to adjust the TypeScript configuration to work best with the auth library. You can review the changes in your version control system if you are curious, but there is no need to understand the details of that. It is just some standard TypeScript config tweaks.

Configure private and public key

Convex Auth uses JWTs (JSON Web Tokens) for session management. We will not go through how JWTs work in detail here, but the short version is that they are “signed tokens” that prove a user’s identity.

Think of a JWT as a tamper-proof ID card. When a user signs in, the server creates a JWT that includes the user’s ID and other relevant information. The server includes a signature with this information and hands it to the client as a token. The signature is a cryptographic proof that the token was issued by the server and has not been altered.

Whenever the client (browser) makes a request to the server, it includes this token along with the request. The server can then verify the JWT to confirm that it is valid and was issued by the server itself, allowing it to trust the information contained in the token without needing to look it up in a database on every request.

The signature uses the RSA (Rivest-Shamir-Adleman) algorithm. This algorithm uses a pair of keys: a private key for signing the JWTs and a public key for verifying them. The JWT_PRIVATE_KEY and JWKS (JSON Web Key Set) environment variables that the initializer sets up are part of this RSA system.

Configure auth config file

Convex needs a small config file that provides some basic information used to sign and verify JWTs, and to generate the correct URLs for the OAuth flow. The initializer creates convex/auth.config.ts with the following content:

export default {
  providers: [
    {
      domain: process.env.CONVEX_SITE_URL,
      applicationID: "convex",
    },
  ],
};
  • The CONVEX_SITE_URL is set automatically on every Convex deployment — you do not configure it yourself.
  • The applicationID: "convex" is a constant Convex Auth expects.

Once the initializer creates this file, you will not need to change it again.

Initialize auth file

The initializer creates convex/auth.ts with the following content:

import { convexAuth } from "@convex-dev/auth/server";

export const { auth, signIn, signOut, store, isAuthenticated } = convexAuth({
  providers: [],
});

This file tells Convex Auth which authentication method to use (inside the providers array). Currently, it is empty because we have not set up any providers yet. It is up to us to fill in the provider configuration, and we can choose multiple providers if we want (e.g., GitHub, Google, email/password). In this chapter, we will set up GitHub OAuth, so let’s add that provider now:

  import { convexAuth } from "@convex-dev/auth/server";
+ import GitHub from "@auth/core/providers/github";

  export const { auth, signIn, signOut, store, isAuthenticated } = convexAuth({
-   providers: [],
+   providers: [GitHub],
  });

We will configure the GitHub provider in the next section, but for now, let’s look at what convexAuth(...) returns:

  • signIn, signOut, and isAuthenticated are Convex mutations and queries that the frontend hooks call internally. We do not need to invoke them directly, but they must be exported so that Convex deploys them.
  • store is used by the library for its own session bookkeeping.
  • auth is the object we will attach HTTP routes to in convex/http.ts (it handles the OAuth callback).

Configure http file

Convex Auth uses HTTP actions internally. HTTP actions let you build an HTTP API right in Convex. We will not explore HTTP actions in this chapter, but the short version is that they are Convex functions triggered by HTTP requests. Convex Auth uses them to handle the OAuth flow. At a high level, the flow looks like this:

  Browser
     │
     │ 1. User clicks "Sign in with GitHub"
     ▼
  Convex Auth
  (on your Convex deployment)
     │
     │ 2. Redirects the browser to GitHub
     ▼
  GitHub
     │
     │ 3. User authorizes the app
     ▼
  Convex callback
  (/api/auth/callback/github)
     │
     │ 4. Convex Auth completes sign-in,
     │    creates the session, and
     │    redirects back to your app
     ▼
  Browser
  (user is now signed in)

When GitHub redirects the user back after they’ve authorized the app, that redirect hits an HTTP endpoint on your Convex deployment, and the auth library needs to handle it.

The initializer creates convex/http.ts with the following content:

import { httpRouter } from "convex/server";
import { auth } from "./auth";

const http = httpRouter();

auth.addHttpRoutes(http);

export default http;

If you are curious, auth.addHttpRoutes(http) adds a group of paths under /api/auth/*, including the OAuth callback at /api/auth/callback/github that we will register with GitHub in the next section. For now, you do not need to understand the details.

Checkpoint: Commit your progress.

git add .
git commit -m "tracker-01: Install and configure Convex Auth"
git push