Help debugging custom JWT auth
Hi, I am trying to use custom JWT auth with my convex database. I have an endpoint that generates a valid JWT (see screenshot below) and I have configured the
auth.config.ts
in the convex directory. However, the onChange callback for setAuth
is always returning false.
The convex instance is a local development instance created with npx convex dev --local --once
, so should be able to access the well-known?
convex/auth.config.ts
:
setAuth call:
Any help is appreciated!!
25 Replies
Checking the authentication tab in the instance dashboard it looks like the provider details from
auth.config.ts
are missing, but I am unsure why?
If the
npx convex dev --local --once
didn't show an error with any file, it should work
@Leon (Synth)Yeah, the dev command is running no problem

Checking the websocket messages it is returning an
{"type":"AuthError","error":"Could not decode token","baseVersion":0,"authUpdateAttempted":true}
, which looks to be this line:
https://github.com/get-convex/convex-backend/blob/63efd5913af60fa93dc4e8147d47ccd29c72edb9/crates/authentication/src/lib.rs#L246
Exactly why it failed to decode the token, it doesn't seem to make obvious?That line doesn't look like the same line, do you see an error about AuthHeader?
This is all of the messages I see in the websocket for both connection attempts:

Interesting point though, that that error doesn't seem to exist on main anywhere with the
AuthError
type, as far as I can see
Is the provider not showing in the dashboard an unrelated bug or could this be causing it?ah yeah, that's strange
Is this dev?
This is dev
I have a self hosted instance but it obviously wouldn't be able to reach the local jwks
Can you try with a cloud deployment
Betting this is a local hosting bug
Before attempting with a cloud deployment, just checked it with a local running verison of the self-hosted images and I get the exact same error.
docker.compose.yml
:
auth.config.ts
updated to point at host:
Will give it a go with a cloud deployment now, just need to get the jwks up somewhere@erquhart can confirm, I even get the error when using convex cloud


Here is how I am generating the token, if it helps:
But I'd assume if jwt.io says it is a valid token then there is nothing wrong there
bump
So it looks like I have managed to get past the
Could not decode token
error by adding the key id header to the JWT. Now, I have seen it successfully authenticated a few times, but it seems to be extremely inconsistent. Most of the time I am now getting this error: Could not validate token
Which is further down in the auth method, so, progress!: https://github.com/get-convex/convex-backend/blob/63efd5913af60fa93dc4e8147d47ccd29c72edb9/crates/authentication/src/lib.rs#L304
Ok, so... just adding a 1 second timeout before returning the token from
setAuth
seems to have fixed the inconsistencies... 😅
Could this be that the tolerance on the iat
claim is too strict?Opened an issue for investigation: https://github.com/get-convex/convex-backend/issues/139
GitHub
Too tight tolerance on customJwt
iat
claim and kid
header seems...Hi, I spent the most part of yesterday evening and this morning troubleshooting as to why my custom JWT was failing to authenticate with convex. You can find my troubleshooting process in this #sup...
Glad you figured all this out - the iat thing is interesting, thanks for opening an issue on it. Waiting a full second is rough, maybe a shorter one will be a working solution until this is actually resolved?
I ended up doing the diff between the current time and the issued at time so it isn't always a full second but it seems like it needs to be at least a second since the
iat
for it to work consistentlyI haven't really seen this with other jwts, any chance your jwt generation is off a bit? Agree that maybe some tolerance in iat validation would help, but again, haven't seen this in other implementations before.
I mean, maybe? This is how I am generating the JWT with jose:
My system time doesn't seem to be out of sync

I don't know what would cause the generation to be off?
Is your key generation running in Convex? Same function or different?
Key generation is running outside of convex in a normal http endpoint (specifically a sveltekit route)