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
- Log in to your Clerk Dashboard .
- Select your Dirly project.
- Configure In the left sidebar, navigate Sessions to JWT Templates.
- Click Create new template.
Step 2: Configure Basic Information
Fill in the form with the following values:
| Field | Value |
|---|---|
| Name | convex |
| Token lifetime | 60 (seconds) |
| Allowed clock skew | 5 (seconds) |
| Issuer | https://your-clerk-domain.clerk.accounts.dev (replace with your actual domain) |
| JWKS Endpoint | https://your-clerk-domain.clerk.accounts.dev/.well-known/jwks.json |
| Custom signing key | Disabled (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".
- In the Claims editor, enter the following JSON:
{
"aud": "convex"
}- Click Save to create the template.
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.devFor example, if your Clerk domain is cool-ocelot-25.clerk.accounts.dev:
CLERK_ISSUER_URL=https://cool-ocelot-25.clerk.accounts.devStep 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 devTesting the Setup
To confirm everything works:
-
Sign in to your Dirly application.
-
Check the browser console for any authentication errors.
-
In your Convex dashboard, look at the Users table – a new user document should appear when you log in.
-
If you have admin access, navigate to
/adminto ensure the session is recognized.
If you encounter issues, double-check that:
-
The JWT template Issuer matches
CLERK_ISSUER_URLexactly. -
The
audclaim 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
| Problem | Solution |
|---|---|
| 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 table | Make 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 quickly | Increase 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/nextjsintegration, 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_URLenvironment variable.
For more details, refer to the Clerk JWT Templates documentation and Convex Clerk Authentication .