Redirect URL for multi-tenancy app

Another issue, but I'll start a separate thread for that, because they are unrelated. Context: I’m building a multi-tenancy, white-label app. It's an education platform, B2B2C model. I have a platform, where creators (mentors, teachers) can prepare a course. One teacher can have multiple courses. Students can have access to just part of them, but across many organisations (tenants). There is also a student portal, where students can login, if they are invited to (like edu.example1.com, med.example2.dev). I'm using NextJS. The issue is: 1. If we have one tenant under edu.example1.com 2. Second under med.example2.dev (!) What should be the KINDE_SITE_URL then? I cannot set it for one URL only, because I'll have edu.example1.com, med.example2.dev etc. And is there an easy way to setup redirect URL to the given tenant after login? So if I started from med.example2.dev, I should land on med.example2.dev after auth process.
12 Replies
Abdelrahman Zaki - Kinde
Hi @Adam Tkaczyk, thanks for the context. Just to clarify, could you let us know where the app is currently deployed?
Adam Tkaczyk
Adam TkaczykOP5mo ago
What exactly do you need to know? It's my dev env, single instance of app, GCP Cloud Run
top kek
top kek5mo ago
after the callback you can do whatever you want, you’re free to redirect the user to another subdomain! look at what im doing in my codebase in the /auth/callback handler:
await client.handleRedirectToApp(manager, new URL(request.url));

const companySlug = await client.getClaimValue(manager, 'external_org_id', 'access_token');
if (typeof companySlug !== 'string') {
console.error('Access token missing external_org_id claim');
throw badRequestError('You are not signing in to any company.');
}

const redirectUrl = await manager.getSessionItem('redirect_url');
if (typeof redirectUrl === 'string') {
await manager.removeSessionItem('redirect_url');
if (redirectUrl.startsWith(`/${companySlug}`)) {
return redirect(redirectUrl, { headers: await getHeaders() });
}
}

const postLoginUrl = urlFrom(request, companySlug);
return redirect(postLoginUrl.toString(), { headers: await getHeaders() });
await client.handleRedirectToApp(manager, new URL(request.url));

const companySlug = await client.getClaimValue(manager, 'external_org_id', 'access_token');
if (typeof companySlug !== 'string') {
console.error('Access token missing external_org_id claim');
throw badRequestError('You are not signing in to any company.');
}

const redirectUrl = await manager.getSessionItem('redirect_url');
if (typeof redirectUrl === 'string') {
await manager.removeSessionItem('redirect_url');
if (redirectUrl.startsWith(`/${companySlug}`)) {
return redirect(redirectUrl, { headers: await getHeaders() });
}
}

const postLoginUrl = urlFrom(request, companySlug);
return redirect(postLoginUrl.toString(), { headers: await getHeaders() });
Abdelrahman Zaki - Kinde
Hi @Adam Tkaczyk, just checking in, did the suggestion above help with your setup? Let us know if you have any questions or if you'd like help adapting it to your use case.
Adam Tkaczyk
Adam TkaczykOP5mo ago
Hi, already implemented the auth I needed on my own 😅
Koosha-Kinde
Koosha-Kinde5mo ago
Got it, glad to hear you’ve got it working. Feel free to reach out anytime if you run into anything else.
Stephen
Stephen3mo ago
Sorry, for re-raising this older topic, but I'm starting to figure out how I'm going to do the same. What I understand is that Kinde upon authenticating will (if you're using code flow - i.e. one of their Back SDKs like Nuxt or Next.js) create a Kinde auth cookie with lax against the domain where the cookie was issued. If I did the authentication against my core platform domain (e.g. mysaas.com) then the cookie would be issued against mysaas.com, but redirecting afterwards to example1.com or example2.dev would make the auth cookie unavailable? I would need to authenticate against my white labeled domains, but this also means I'd need to maintain via Kinde's APIs a set of allowed redirect URLs? I guess I'm struggling to see how this would work. Or is it the case for white labelling we need to use the Scale plan with custom organisation authentication?
Koosha-Kinde
Koosha-Kinde3mo ago
Hi there, You are welcome to get back to us. For your query, you're correct that Kinde issues authentication cookies scoped to the domain where the authentication flow is initiated. If you authenticate on your core platform domain (e.g., mysaas.com), the auth cookie is set for mysaas.com. Redirecting the user to a different domain (like example1.com or example2.dev) means that the cookie will not be accessible on those white-labeled domains due to browser cookie isolation. For white-labeled authentication—where each customer has their own domain—you should authenticate directly on the respective white-labeled domain. This requires configuring each domain as a custom domain in Kinde and ensuring that all callback/redirect URLs are registered in Kinde’s application settings. Each domain you authenticate against must be explicitly added as an allowed redirect URI in Kinde. If you want per-organization custom domains (e.g., org1.yoursaas.com, org2.customerdomain.com), this is supported via Kinde’s advanced organization features, available on the Scale plan. This lets each organization have its own custom authentication domain and configuration.
Stephen
Stephen3mo ago
Thanks Patrick. Looking at the Custom Domains settings, it looks like only one custom domain per environment is supported? I've already set up a custom domain, and I don't see an option to create another. At this stage, for my customers, all of the authorisation settings would be the same. I don't necessarily need locked down per-organisation settings (although it's likely some of my enterprise customers will want this at some stage). They just want the 'illusion' that my app is hosted on my domain, and I don't think they'd care that I authenticate via a single Kinde domain for all requests. Could another solution be to use Kinde's API to dynamically add / remove return URLs based on custom domains? Or is that not going to work / supported? I use my Kinde development environment to authentically locally (localhost) as well as via my cloud hosted development environment. So I'm guessing that should work, unless there's some limit on the maximum number of callback URLs. you can have per application. I'm asking both to conserve initial cost, and to try and keep things as simple as possible.
Koosha-Kinde
Koosha-Kinde3mo ago
Hi there, I will look into your query more deeply and get back to you soon. Hi there, I am sorry for not responding sooner. Kinde supports only one custom domain per environment. If you need to serve multiple brands or domains, you cannot assign more than one custom domain directly to a single Kinde environment at this time. The custom domain you configure will be the one used for all authentication endpoints for that environment. For your scenario—where you want to give customers the impression they’re staying on your domain, but don’t need per-organization isolation—a single custom domain is the supported approach. All users would authenticate via that domain, regardless of which organization they belong to. Regarding callback URLs: you can register multiple callback (redirect) URLs per application, and you can manage these via the Kinde Management API. This means you can dynamically add or remove callback URLs as needed (for example, to support both localhost and cloud environments, or preview deployments). There is a hard limit of 1,000 callback URLs per application. So, your proposal to use the Kinde API to manage callback URLs for different customer-facing domains is technically possible, but it does not give each customer a unique authentication domain—they would still be redirected through your single configured custom domain. The callback URL is where the user is sent after authentication; it can be any URL you control and have registered, but the authentication flow itself will always use your configured Kinde (or custom) domain.
Stephen
Stephen3mo ago
Perfect, thanks Patrick!
Koosha-Kinde
Koosha-Kinde3mo ago
You are welcome. Please feel free to ask any questions and reach out if you need assistance.

Did you find this page helpful?