Skip to Content
Dirly 2.0 is released 🎉
Authentication

Authentication

Clerk + Convex authentication architecture

Dirly uses Clerk for authentication and integrates it with Convex for secure server-side identity verification.

Clerk Configuration

Auth Config

Convex is configured to accept JWTs from Clerk

convex/auth.config.js

export default { providers: [ { domain: process.env.CLERK_ISSUER_URL, applicationID: "convex", }, ], };

This tells Convex to trust JWT tokens issued by the specified Clerk domain.

Clerk JWT Template Setup

To enable secure authentication between Clerk and Convex, you need to create a custom JWT template in your Clerk dashboard. This template defines how user information is passed to Convex and validates the issuer URL.


Why a JWT Template?

Convex uses Clerk’s session tokens to authenticate users. By creating a custom JWT template, you can:

  • Set the issuer (iss) claim to match your Clerk instance.
  • Add the audience (aud) claim set to "convex".
  • Control token lifetime and other security parameters.

This ensures that Convex can verify the tokens and that your CLERK_ISSUER_URL environment variable matches exactly.


Step 1: Create a New JWT Template

  1. Log in to your Clerk Dashboard .
  2. Select your Dirly project.
  3. Configure In the left sidebar, navigate Sessions to JWT Templates.
  4. Click Create new template.

Step 2: Configure Basic Information

Fill in the form with the following values:

FieldValue
Nameconvex
Token lifetime60 (seconds)
Allowed clock skew5 (seconds)
Issuerhttps://your-clerk-domain.clerk.accounts.dev (replace with your actual domain)
JWKS Endpointhttps://your-clerk-domain.clerk.accounts.dev/.well-known/jwks.json
Custom signing keyDisabled (unless you have a specific reason to use a custom key)

Your Clerk domain is the one shown in your dashboard URL, e.g., https://cool-ocelot-25.clerk.accounts.dev. Make sure to use your domain, not the example.


Step 3: Add Custom Claims

Scroll down to the Customize session token section. You need to add a claim that sets the audience to "convex".

  1. In the Claims editor, enter the following JSON:
{ "aud": "convex" }
  1. Click Save to create the template.
The aud claim is required by Convex to accept the token. Without it, Convex will reject the authentication.

Step 4: Verify the Template

After saving, your template will appear in the list of JWT templates. You can click on it to view the details. The Issuer field should contain your Clerk domain.

You can also test the template by clicking Preview to see what the generated token looks like.

Step 5: Set the Environment Variable

Now that you have your JWT template configured, you need to set the CLERK_ISSUER_URL in your .env.local file.

The issuer URL is exactly the Issuer value you entered in the template:

CLERK_ISSUER_URL=https://your-clerk-domain.clerk.accounts.dev

For example, if your Clerk domain is cool-ocelot-25.clerk.accounts.dev:

CLERK_ISSUER_URL=https://cool-ocelot-25.clerk.accounts.dev
Make sure there is no trailing slash at the end of the URL. It must match exactly the issuer in the JWT template.

Step 6: Restart Your Development Server

After adding the CLERK_ISSUER_URL to your .env.local file, restart your Next.js development server to apply the changes:

npm run dev

Testing the Setup

To confirm everything works:

  1. Sign in to your Dirly application.

  2. Check the browser console for any authentication errors.

  3. In your Convex dashboard, look at the Users table – a new user document should appear when you log in.

  4. If you have admin access, navigate to /admin to ensure the session is recognized.

If you encounter issues, double-check that:

  • The JWT template Issuer matches CLERK_ISSUER_URL exactly.

  • The aud claim is set to "convex".

  • The template is active (you may have multiple templates; the one named "convex" will be used automatically if you’re using Clerk’s Convex integration).

Troubleshooting

ProblemSolution
Convex shows “Unauthorized”Verify that CLERK_ISSUER_URL is set correctly and exactly matches the issuer URL in your JWT template in Clerk.
User not appearing in Convex users tableMake sure you are using the correct JWT template. Clerk may default to its “Default” template. Explicitly specify the desired JWT template in your Convex initialization code (e.g. convexHttp.withJwt({ jwtTemplate: "your-template-name" })).
Token expires too quicklyIncrease the Token lifetime in your JWT template settings in Clerk if the default 60 seconds is too short for your use case (e.g. long-lived sessions, background jobs, or offline usage).

Additional Notes

  • The JWT template you just created will be used automatically by Convex when you use Clerk’s @clerk/nextjs integration, as long as your Convex deployment is configured with the same issuer URL.

  • If you ever change your Clerk domain, you must update both the JWT template and the CLERK_ISSUER_URL environment variable.

For more details, refer to the Clerk JWT Templates documentation  and Convex Clerk Authentication .

Last updated on