mrvdot
mrvdot•2y ago

How to setup Custom OIDC Auth (Logto)

Hi there, I'm not sure if I'm completely missing something or if something is misconfigured. I'm attempting to use Logto (OIDC fully compatible) to authenticate with Convex. I have setup the auth.config.js file as:
export default {
providers: [
{
domain: 'https://guq6sg.logto.app/', // have also tried just 'guq6sg.logto.app' but the docs are inconsistent on which it should be
applicationID: 'yt3fw3sx5ea89tp6x27nb', // pulled from logto dashboard
},
],
};
export default {
providers: [
{
domain: 'https://guq6sg.logto.app/', // have also tried just 'guq6sg.logto.app' but the docs are inconsistent on which it should be
applicationID: 'yt3fw3sx5ea89tp6x27nb', // pulled from logto dashboard
},
],
};
(Don't worry, all these environments are purely for testing purposes, I'll swap them out before building anything "real") And have called setAuth (just using the BaseConvexClient as I'm in Angular, not React) with:
this.#client.setAuth(
async ({ forceRefreshToken }) => {
if (forceRefreshToken) {
// Will refresh id token
await this.#logto.getAccessToken();
}
// Have also tried using `accessToken`, unclear which it should be
const token = await this.#logto.getIdToken();
return token;
},
(loggedIn) => {
// This is always false
console.log('[convex] now logged in?', loggedIn);
}
);
this.#client.setAuth(
async ({ forceRefreshToken }) => {
if (forceRefreshToken) {
// Will refresh id token
await this.#logto.getAccessToken();
}
// Have also tried using `accessToken`, unclear which it should be
const token = await this.#logto.getIdToken();
return token;
},
(loggedIn) => {
// This is always false
console.log('[convex] now logged in?', loggedIn);
}
);
And I've confirmed it's getting the token, but never logs in, nor do I see anyway to debug why it's not logging in (URL error, invalid token, ID10T error, something else??). Any suggestions on where I should look? Based on the audit logs in Logto, Convex doesn't seem to ever even try to validate the token (or hit the Logto server at all) Thanks! Really excited to try Convex for a new project, but need auth with Logto to work (their support for multi-tenancy and multi-organization is pretty key for what I'm building)
50 Replies
mrvdot
mrvdotOP•2y ago
If it helps, here's the JWT I get fromgetIdToken: https://jwt.io/#debugger-io?token=eyJhbGciOiJFUzM4NCIsInR5cCI6IkpXVCIsImtpZCI6IlYyX084Sm01X0JEY3NMQXpPYVZOYUVTajlvcjBKZ05mT3ZUQU5CUWRtWGMifQ.eyJzdWIiOiJ5b3NyMDU2d2huaGIiLCJuYW1lIjpudWxsLCJwaWN0dXJlIjpudWxsLCJ1c2VybmFtZSI6bnVsbCwiYXRfaGFzaCI6IjVQeDNHLWlaYzZxaGg0bEdGdDVhWk5pMWVkRGl0dWs0IiwiYXVkIjoieXQzZnczc3g1ZWE4OXRwNngyN25iIiwiZXhwIjoxNzAyNDAzMjEzLCJpYXQiOjE3MDIzOTk2MTMsImlzcyI6Imh0dHBzOi8vZ3VxNnNnLmxvZ3RvLmFwcC9vaWRjIn0.HO3Xt8j92Z0voMWH2BI0rlPgOW4UUwYjg5M_zB5P5XIJcl72tPvE7S74Zf1mwVOI26uTAw0W9-9kGhw17VYDOcll9v6XXzCAhQKbzSsjLzQm2ZT71ruXCbvsbReBiwbZ&publicKey=%7B%0A%20%20%22crv%22%3A%20%22P-384%22%2C%0A%20%20%22kty%22%3A%20%22EC%22%2C%0A%20%20%22x%22%3A%20%22dJAmN0qVDL_Vx4DIwxVmeF1Kx-ZUhyy9YZmvibwMaThVc-j-0mjsv8ulg8ef1zcN%22%2C%0A%20%20%22y%22%3A%20%225oHgP4Iuuul3vmNUjQeemb4WNVuCYJ15tvsUqzfEPFVIOKIxSuZM4BvqWRrvYhqZ%22%0A%7D Which decodes to:
{
"sub": "yosr056whnhb",
"name": null,
"picture": null,
"username": null,
"at_hash": "5Px3G-iZc6qhh4lGFt5aZNi1edDituk4",
"aud": "yt3fw3sx5ea89tp6x27nb",
"exp": 1702403213,
"iat": 1702399613,
"iss": "https://guq6sg.logto.app/oidc"
}
{
"sub": "yosr056whnhb",
"name": null,
"picture": null,
"username": null,
"at_hash": "5Px3G-iZc6qhh4lGFt5aZNi1edDituk4",
"aud": "yt3fw3sx5ea89tp6x27nb",
"exp": 1702403213,
"iat": 1702399613,
"iss": "https://guq6sg.logto.app/oidc"
}
mrvdot
mrvdotOP•2y ago
Interestingly, I updated my logto config to correctly request the access token for this specific resource (i.e. convex) and now it just breaks the server. I see this in my logs:
No description
mrvdot
mrvdotOP•2y ago
And notably, the console.log from my convex query never appears, nor does the isLoggedIn change callback fire Don't see anything in the logs on the convex dashboard about it
ballingt
ballingt•2y ago
@mrvdot what's the name of the backend you're connecting to? It's possible we'll see better error messages than are exposed here.
mrvdot
mrvdotOP•2y ago
@ballingt acoustic-cassowary-66, thanks!
ballingt
ballingt•2y ago
I can look into this more, but initially I see
Unsupported: unexpected or unsupported JWT type `at+jwt`
Unsupported: unexpected or unsupported JWT type `at+jwt`
ballingt
ballingt•2y ago
huh, the first one you linked did not have this
ballingt
ballingt•2y ago
I also see some
Invalid JSON web token: found 1 parts (expected 3)
Invalid JSON web token: found 1 parts (expected 3)
and
No auth provider found matching the given token
No auth provider found matching the given token
but I'll check out the newest errors, makes sense if you've been trying things
mrvdot
mrvdotOP•2y ago
The first error is probably because I was sending the access token, which is just a regular string, rather than the ID token, which is an actual JWT The latter is probably the issue, but it'd be helpful to know exactly what "provider" it was looking for The aud in the JWT matches the applicationID in the auth config
ballingt
ballingt•2y ago
in the last minute I see
No auth provider found matching the given token
No auth provider found matching the given token
and
token_endpoint_auth_signing_alg_values_supported[4]: unknown variant `EdDSA`, expected one of `HS256`, `HS384`, `HS512`, `RS256`, `RS384`, `RS512`, `ES256`, `ES384`, `ES512`, `PS256`, `PS384`, `PS512`, `none` at line 1 column 1247
token_endpoint_auth_signing_alg_values_supported[4]: unknown variant `EdDSA`, expected one of `HS256`, `HS384`, `HS512`, `RS256`, `RS384`, `RS512`, `ES256`, `ES384`, `ES512`, `PS256`, `PS384`, `PS512`, `none` at line 1 column 1247
and
Invalid JSON web token: found 1 parts (expected 3)
Invalid JSON web token: found 1 parts (expected 3)
the middle looks interesting, I wonder if we can support that
mrvdot
mrvdotOP•2y ago
Hmm, the alg says ES384
ballingt
ballingt•2y ago
I see ECDSASHA384 in the bottom section
mrvdot
mrvdotOP•2y ago
I think that's just the function for verifying. The algorithm is still ES384 (you can see it at the top) Yeah, that's just something JWT.io suggests. If you do a "boring" JWT decode, that's not in there: https://www.jstoolset.com/jwt/6a104097b60be175
ballingt
ballingt•2y ago
ah thanks
mrvdot
mrvdotOP•2y ago
Poking around some other OIDC setups, it looks like maybe the at_hash requires an additional accessToken for full validation: https://supabase.com/docs/reference/javascript/auth-signinwithidtoken
mrvdot
mrvdotOP•2y ago
Not sure if that's necessary or just recommended
ballingt
ballingt•2y ago
Our Clerk example uses "convex" as applicationId, but I believe that's because that's what they put in the aud field https://github.com/get-convex/convex-demos/blob/main/users-and-clerk/convex/auth.config.js
No description
mrvdot
mrvdotOP•2y ago
Yeah, that was my understanding as well
ballingt
ballingt•2y ago
No auth provider found matching the given token
No auth provider found matching the given token
is the only error I see for the last 20 min (sorry about these not being exposed!)
mrvdot
mrvdotOP•2y ago
Ok, yeah, that does seem like the mostly likely culprit Any chance you can see/log how exactly it's trying to match the provider? I tried using the iss field and that also caused an error *for the domain in the auth config
ballingt
ballingt•2y ago
taking a look
mrvdot
mrvdotOP•2y ago
Thanks
sangle69
sangle69•13mo ago
Hi guys. I am trying to implement Logto auth too and not sure how to do so. @mrvdot Did you succeed in implementing this ? Please advise 🙂
Pierre
Pierre•2mo ago
Hi everyone, Any news ? 🙂 Does convex support the ES384 algorithm ? @mrvdot did you find a solution ? @Tom , any idea ? It's very important because LogTo is the only stable, simple, and complete solution I have for sveltekit that I can self-host. I don 't want to use Convex Auth, since it's beta and not everything is svelte ready. Also, I don't want to use a Cloud solution. I want to self-host it. I tried with the JWT plugin of Better-Auth, but at the end, I have the same problem as LogTo : {"type":"AuthError","error":"Could not verify token claim","baseVersion":0} Without more informations
ballingt
ballingt•2mo ago
@Pierre can you share you JWT token? @mrvdot and I got this working in December.
Pierre
Pierre•2mo ago
Hi @Tom , Thank you so much for your help ! Here is the JWT token : eyJhbGciOiJFUzM4NCIsInR5cCI6IkpXVCIsImtpZCI6Im1IUTNRaHIxRDVFNUhMWnFoY0kyZTJLYkpCMzQ2NHFObTVaZnVTaGZuVlEifQ.eyJzdWIiOiJ3NzZ4NDhzb3F6NTMiLCJuYW1lIjoiRXl0YW4gUElSTkFZIiwicGljdHVyZSI6bnVsbCwidXBkYXRlZF9hdCI6MTc0MzA3NzkwNjg0OSwidXNlcm5hbWUiOiJwaXJuYXkiLCJjcmVhdGVkX2F0IjoxNzQzMDI4ODMwNzUxLCJhdF9oYXNoIjoiamVYLXJTVEdVLXFkNFFIRFZ2UWdpYmlVRWFkUWFMVnkiLCJhdWQiOiJyZ2Z3YmVjMmtzcW1ueXYwcnN6OW8iLCJleHAiOjE3NDMxMTM3MDAsImlhdCI6MTc0MzExMDEwMCwiaXNzIjoiaHR0cHM6Ly9hdXRoLmNvbnZleC5kZXZleXRhbi5jb20vb2lkYyJ9.sRfgHhZW4-ghcU8DnLytA8kLWajMA_stANxvxw__HT3X8Y4UHxmvcog65Ml9trbEGxXEnyp-OAjaVNC6JQUABeG9NK72_Qs747CDZ_1PRELoXY_QbiRo-UQBHK8ZOC99 Also, here is the auth config : export default{providers:[{domain:"https://auth.convex.deveytan.com/oidc",applicationID:"rgfwbec2ksqmnyv0rsz9o"}]};
ballingt
ballingt•2mo ago
unfortunately I can't help today, but check in tomorrow!
Pierre
Pierre•2mo ago
Oh thank you so much ! Hi @Tom , Do you need a new token. Hi @ballingt , Did you find something ?
erquhart
erquhart•5w ago
@Pierre I don't know if this will be the ticket, but I set up a custom auth integration recently and kept getting no auth provider found until I changed the audience of the jwt to "convex". It seemed like the Convex backend was rejecting based on not having that audience value, but I can't find evidence of this in the backend repo. OH it just has to match the applicationID from auth.config.ts So yeah nvm, this isn't the issue you're having.
erquhart
erquhart•5w ago
GitHub
convex-backend/crates/authentication/src/lib.rs at 9554a34f21a72814...
The open-source reactive database for app developers - get-convex/convex-backend
erquhart
erquhart•5w ago
The issuer, audience, and iat/exp all check out based on that last jwt and auth config you shared, so that leaves key problems. I don't know what algorithms Convex supports, but if you can try it with RS256 that would help rule out algorithm support. Then it's down to jwks mismatch with the jwt.
Pierre
Pierre•5w ago
Hi @erquhart , Thank you ! I tried the RSA key of Logto. Still not working. @ballingt , did you find something ?
erquhart
erquhart•5w ago
Did you check to ensure the jwks works to decode your jwt?
Pierre
Pierre•4w ago
Yes, all was good Hi @erquhart , Is it because of the algorythm issue with convex ?
erquhart
erquhart•4w ago
if RS256 is not working, it's not the algorithm
skyturtle
skyturtle•3w ago
Hey @Pierre, I was just wondering if you were able to sort this out? I've been struggling to get a custom auth integration using Logto to work. Like you, I have a valid JWT and the payload has a valid aud, iss, sub, etc. I've even been able to implement login/logout using a <LogtoProvider> component, but there seems to be issues when the Convex backend tries to validate the JWT. In the console, I keep seeing
{
"type": "AuthError",
"error": "Auth provider discovery of http://localhost:3001/oidc failed",
"baseVersion": 0,
"authUpdateAttempted": true
}
{
"type": "AuthError",
"error": "Auth provider discovery of http://localhost:3001/oidc failed",
"baseVersion": 0,
"authUpdateAttempted": true
}
That domain is obviously on my local machine, but I couldn't get it working with a production version of Logto either.
Pierre
Pierre•3w ago
Unfortunately, not. Having not heard back from @ballingt or @mrvdot . I don't know what's causing the holdup. I've put it on the back burner for now and I am waiting for the Better Auth component to be further developed.
erquhart
erquhart•3w ago
Are you hoping to use Logto with Better Auth?
Pierre
Pierre•7d ago
No, I was hoping to use LogTo, but since I can't get it to work, I'm wondering if I should just switch to BetterAuth. I FINALLY figured out why it wasn't working @skyturtle ! I'm using Logto (version 1.26.0), deployed on my own server. In the console, I had correctly changed the key to use the RSA algo (/console/signing-keys). But... it still wasn't working. Asking the Logto docs' AI, I found out that after changing the key, you have to RESTART the Logto instance (in my case, restart the Docker service). And now it finally works! What a relief! Thanks Convex for this great product! I love Convex! Support for other algorithms like ES384 would be greatly appreciated. I also think adding a page for Logto in your documentation, similar to Clerk or Auth0, would be great for the community (since you can't self-host Clerk or Auth0). Thanks for your help @ballingt and @erquhart !
erquhart
erquhart•7d ago
So glad you got this working!!
skyturtle
skyturtle•6d ago
@Pierre that's awesome you got it working! Unfortunately, I'm still getting an Auth Error with Auth provider discovery ... failed etc. I've been using RSA algo and my Logto instance had already been restarted. If you don't mind sharing, how are you integrating Logto auth? Are you using doing a Custom Auth Integration? Or are you using Convex Auth with Logto as an OAuth provider?
Pierre
Pierre•5d ago
I use the Custom Auth Integration. I also discovered that adding Sentry to the Convex (with the SENTRY_DSN variable) allows you to better understand auth errors. It helped me a lot. I have to say that unfortunatly Convex only support ID token, not access token. In the auth convex params, you should set the domain with https://your-logto-instance.com/oidc (not the admin) with the application ID.
Pierre
Pierre•5d ago
Just asked to support access token : https://github.com/get-convex/convex-backend/issues/75
GitHub
Support at+jwt auth token · Issue #75 · get-convex/convex-backend
It would be great to support JWT with the at+jwt type (OIDC standard). For example : Logto access tokens are at+jwt tokens.
skyturtle
skyturtle•4d ago
Gotcha. I’ll see if I can hook Sentry up to my app and dig around. Any chance you’re using React? I think in some previous messages you mentioned SvelteKit. I was just hoping that maybe I could see an example of how you’re implementing custom auth. Sorry to keep bugging you. It’s just been driving me crazy haha! If not, no worries! And for the auth params, I’ve been setting it to my instance and NOT the admin panel.
Allen
Allen•4d ago
How does your metadata json look? Mind sharing it?
skyturtle
skyturtle•3d ago
Are you asking about the data in the payload of the JWT?
Pierre
Pierre•3d ago
I use Svelte, not React. And don't worry, I also spent several days scratching my head before I understood how things worked 🙂 But it's actually straightforward to integrate Logto with Convex. You should create a route (like /my-token) which returns the ID token from the Logto client. Then, you should use the setAuth of the Convex client, like this :
client.setAuth(
async () => {
const token = await fetch('/my-token').then((res) => res.text());
return id ?? null;
},
() => {}
);
client.setAuth(
async () => {
const token = await fetch('/my-token').then((res) => res.text());
return id ?? null;
},
() => {}
);
skyturtle
skyturtle•3d ago
Ah gotcha. So it looks like you've got an endpoint you can hit with the fetch request. Right now I'm using TanStack Router so I'm not able to do any server API routes, which is why I was trying to do everything in "React land". I know TanStack Start has API routes, but I'm not sure if I feel like messing around with the beta at this point. I may give it a shot if I can't sort it out with a traditional SPA. Anyway, thanks again for the help!

Did you find this page helpful?