Refresh claims approach
Hi, I'm trying to figure out how to refresh claims / user details with Kinde. There are few scenarios I'm trying to solve this for:
- As part of registration activities a user might be allocated to an organisation & role via the M2M API. Their original access token doesn't have these claims and they end up with forbidden access. I understand the why as the Nuxt server is using the cached values.
- Users might have their roles changes within an admin section using the M2M API.
If I log the user out and in again, it works fine. If I refresh the claims using
refreshUserClaims()
in the management API (either via the JavaScript SDK or .NET SDKs) then nothing happens and the user still gets forbidden access issues from my application (I do get a success response from Kinde when calling the refresh API).
With Kinde, how are you supposed to handle this? Ideally without logging out and in again.31 Replies
Just came here to ask the exact same question, cause I'm having the same use-case as described above and want the user changes reflected immediately in my app instead of them only being reflected after logging out and back in again
Hey @Stephen and @Woet,
Thanks for reaching out on refreshing claims. The logic to refresh claims is different per SDK.
Are you able to let me know what SDKs you want to know how to refresh claims, and I can get back to you with some advice?
Hey @Oli - Kinde , thanks for the response! I'm currently using the Next.js app router SDK
Hey @Oli - Kinde.
- I'm using Nuxt (Vue) to perform auth / registration using your SDK. In the case of the API call to refreshing claims I'm using your TypeScript SDK as that's your current guidance.
- I'm also using the .NET SDK to try and force a claims refresh. My .NET APIs are the one's doing the M2M 'heavy lifting', I'm only using TypeScript SDK to do the claims refresh as that is the Nuxt server which 'owns' the Kinde cookie / JWT. (I do also force a claims refresh for actions which change claims values in the .NET API but I understand why it does nothing, my .NET API only validates the JWT with Kinde)
I guess one question I would have for your team is why an API call to Kinde's servers via
refreshUserClaims()
is needed at all, at least in terms of understanding what is actually happening. I would have thought just forcing a refresh of the users auth token would in turn refresh the claims. It's been a minute since I looked at your Nuxt SDK source code, but IIRC there was another method to refresh claims (that didn't require a M2M app) but because it was using your sessionManager
the session manager already saw that there was a 'valid' auth token and so doesn't call your servers to refresh, at least to my understanding.
P.S. working on Christmas day Oli? That's dedication đHey @Woet,
We have some major changes to our NextJS SDK that will fix a whole range of refresh claims issues - so stay tuned for this.
I'm using Nuxt (Vue) to perform auth / registration using your SDK. In the case of the API call to refreshing claims I'm using your TypeScript SDK as that's your current guidance. I'm also using the .NET SDK to try and force a claims refresh. My .NET APIs are the one's doing the M2M 'heavy lifting', I'm only using TypeScript SDK to do the claims refresh as that is the Nuxt server which 'owns' the Kinde cookie / JWT. (I do also force a claims refresh for actions which change claims values in the .NET API but I understand why it does nothing, my .NET API only validates the JWT with Kinde)It sounds like you are using the TypeScript SDK to refresh claims and it's not working as expected. So I would suggest raising an
GitHub issue
on the TypeScript SDK GitHub repo around your use-case of refreshing claims - it's easier for my expert TypeScript teammate to address TypeScript queries raised on GitHub when he has time to look into themGitHub
GitHub - kinde-oss/kinde-typescript-sdk: Kinde SDK for TypeScript
Kinde SDK for TypeScript. Contribute to kinde-oss/kinde-typescript-sdk development by creating an account on GitHub.
I guess one question I would have for your team is why an API call to Kinde's servers via refreshUserClaims() is needed at all, at least in terms of understanding what is actually happening. I would have thought just forcing a refresh of the users auth token would in turn refresh the claims. It's been a minute since I looked at your Nuxt SDK source code, but IIRC there was another method to refresh claims (that didn't require a M2M app) but because it was using your sessionManager the session manager already saw that there was a 'valid' auth token and so doesn't call your servers to refresh, at least to my understanding.By default, Kinde caches tokens for performance. The cache becomes invalid when user information is updated via UI or API, including: - Profile information updates - Organization membership changes - Role changes - Permission updates - Property changes - User-level feature flag updates Why refreshUserClaims() is needed: There are specific scenarios where individual user tokens don't automatically update, including: - Feature flag changes at organisation/environment level that users inherit - Permissions added to a role that the user has For these cases, the refreshUserClaims endpoint explicitly invalidates the cache for that specific user. This ensures the next token refresh will pull fresh claims from Kinde rather than using cached data. Token Refresh Behaviour You raise an interesting point about the session manager and token validation. While I can't speak to the specific Nuxt SDK implementation, I can explain that just refreshing an auth token alone may not force new claims if the cache is still valid. The refreshUserClaims endpoint specifically invalidates that cache to ensure fresh data on the next token refresh. Let me know if you have any further questions.
P.S. working on Christmas day Oli? That's dedication đWe keep our eyes on Kinde businesses and systems, whilst you enjoy your holiday period đ
Thanks @Oli - Kinde I've added to https://github.com/kinde-oss/kinde-typescript-sdk/issues/63 as I suspect this 'behaviour' might be the root cause of the issue and it may be intentional, not a bug.
If it's intentional I'm presuming it's because different organisations can have different authentication policies, particularly for your upgraded Organisations.
GitHub
Bug: unable to reload users information when reassigning organizati...
Prerequisites I have searched the repositoryâs issues and Kinde community to ensure my issue isnât a duplicate I have checked the latest version of the library to replicate my issue I have read the...
Hey @TotalScrub,
Thanks so much for raising this
GitHub issue
. My TS teammate will look at this when he is back online in the new year.
We are in the process of building out our js-utils package. Once its it at a state we are comfortable with, we will get all our JS-based SDKs to depend on the js utils
package.
I am confident our js utils
package solves your token refresh issues, e.g. when reassigning orgs.
Please don't hesitate to raise anymore GitHub issue
- they are the best way for my teammates to investigate and communicate on our progress on issues that come up.GitHub
GitHub - kinde-oss/js-utils
Contribute to kinde-oss/js-utils development by creating an account on GitHub.
Thanks @Oli - Kinde, any rough timeframe for when you think you might have the
js utils
package in place? Right now it's just annoying, because I don't have any customers as I build out my MVP. But it would be a significant issue for me were I live, to the point where I'd need to heavily change my onboarding workflow to work around it.Hey @TotalScrub,
I cannot provide any timelines at the moment. But when my teammate is back online on Jan 6 his #1 priority will be getting the new
JS Utils
package live.NP @Oli - Kinde I understand. If I could get some rough ballpark at some point in Jan once your teammate has a better sense of the effort involved that would be appreciated as it would allow me to plan accordingly. E.g. if I can just wait for it to be released, if I need to do a workaround, or if I just go with early customers and advise them of the issue / workaround.
Not expecting / asking it to be delivered in Jan, just some 'no promises' indication of when it might drop
Hi @TotalScrub,
Totally understand info around when you can expect the new
JS Utils
package.
I am on break from New Years until Jan 13, and I will speak to my teammate then and post here when we think the new JS Utils
package will be released.@Woet if you follow the GitHub thread https://github.com/kinde-oss/kinde-typescript-sdk/issues/63 it might solve your issue for you. With guidance from Coel (Kinde) I was able to redirect the user to log in (with no prompt so they don't see the Kinde UI) with the organisation and get the expected claims.
cc @Oli - Kinde
GitHub
Bug: unable to reload users information when reassigning organizati...
Prerequisites I have searched the repositoryâs issues and Kinde community to ensure my issue isnât a duplicate I have checked the latest version of the library to replicate my issue I have read the...
@Stephen thanks for sharing! I think our needs to refresh claims are similar, so I'll take a look if this thread can help me. My exact use-case is that if an ADMIN changes the role of a user, that the change in permissions is reflected immediately for that user after changing the role. So what I think would need to happen, is that the change in roles done by the ADMIN user, needs to trigger a refresh of the claims for another user.
Same for when deleting users
Ahh, my use case might be slightly different @Woet.
The problem was that upon Kinde user creation the user didn't belong to any Kinde organisations (and roles are assigned to users in an org, not to the user itself). After initial registration I would then assign the user to the appropriate organisation. I would call
The problem was that upon Kinde user creation the user didn't belong to any Kinde organisations (and roles are assigned to users in an org, not to the user itself). After initial registration I would then assign the user to the appropriate organisation. I would call
refreshUserClaims()
using Kinde's Management API but it did nothing.
Based on the GitHub thread I later learned it was because the user was still signed into no organisations and I needed to sign the user into the organisation they had been added to (which could be done 'silently'). This fixed my issue.
But I still also need to start working on your use-case at some point as well.
According to Kinde's document this should just happen - https://docs.kinde.com/authenticate/manage-authentication/sync-with-kinde/.
However, most systems will cache a valid JWT so it isn't clear to me how a web server (or browser) would know that the JWT is no longer valid unless it's using something like Token Introspection (https://www.oauth.com/oauth2-servers/token-introspection-endpoint/) or as suggested by Kinde using short expiry tokens.
@Oli - Kinde I know you're on leave, but it would be good if we could get some guidance on this when you get back, happy to jump on a call as well. It's likely it's just documentation but I would say for many developers (including myself) it would be good to get some more crystal clear guidance on how this works to save on confusion.Kinde docs
Keep your product in sync with Kinde
Our developer tools provide everything you need to get started with Kinde.
OAuth 2.0 Simplified
Token Introspection Endpoint - OAuth 2.0 Simplified
When an OAuth 2.0 client makes a request to the resource server, the resource server needs some way to verify the access token. The OAuth 2.0 core spec
I know this an older thread, but I was wondering - how are we supposed to do the token refresh in SvelteKit 2? @Oli - Kinde Thanks đ
Hi Paul E,
If you are using our SDK. Token refresh in SvelteKit 2 is handled automatically by the SDK. Just make sure youâve included the
Let me know if this is what you had in mind, and if there's anything else I can assist with.
If you are using our SDK. Token refresh in SvelteKit 2 is handled automatically by the SDK. Just make sure youâve included the
offline
scope in your config (KINDE_SCOPE=profile email offline openid
).
You can retrieve the access token like this:
No need to manually refreshâKinde handles it behind the scenes.Let me know if this is what you had in mind, and if there's anything else I can assist with.
Hi Roshan,
thank you for your message!
When I change a user role, claim or custom property of the ID token on the server side, then I want to silently refresh the client token, without the user having to logout / login again.
There are two casses:
a) process is synchronously (client calls server, server changes property) I
b) process is async (server changes property without user/client interaction)
I wrote the following helper, but it doesn't really work reliable (? maybe it does, but not sure) to refresh the token on the client ('prompt' set to 'none').
Do you plan to offer an official helper in the SvelteKit SDK to do something like this, or am I missing something? đ
see message.txt attachment
My code snippet solves a) process is synchronously, but what about b) - do I have to wait for a token refresh cycle here?
Thanks for your support!
Hi Paul E,
Thanks for your question. Youâre correct that thereâs no way to âpushâ new claims into an already issued token â a new token has to be issued for the changes to appear.
Hereâs how we recommend handling each scenario:
(a) Synchronous (client calls server, server changes claims/roles)
1. After changing the userâs roles/claims on the server, call the Management API
Let me know if you have any other questions or if thereâs anything else I can assist you with.
refreshUserClaims
endpoint for that user.
2. On the client, call kindeAuthClient.getToken(request as SessionManager)
. If the user has a valid session, the SDK will refresh the token silently and return updated claims.
(b) Asynchronous (server changes without client interaction)
- Best UX: Send the client a notification (via SSE/WebSockets/in-app signal) that claims have changed, then call getToken(...)
to trigger a refresh.
- Simpler approach: Lower the ID token lifetime so regular SDK refreshes pick up changes sooner.
- Critical paths: For sensitive actions, have the backend verify the userâs permissions directly via the Management API to ensure the latest state.
A few notes on your current helper:
- prompt=none
only works if the Kinde session cookie is present and valid; otherwise, the user will be prompted to log in.
- Calling refreshUserClaims
doesnât update the current token â it simply invalidates the cached claims so the next token issuance reflects the changes.
- Where possible, try getToken(...)
first, as the SDKâs built-in refresh will handle most cases without needing to redirect.
At the moment, there isnât an âofficialâ SvelteKit helper that combines claim invalidation and silent refresh into one call. The supported path is what youâre doing now â SDK-managed refresh via getToken(...)
or silent re-auth via prompt=none
if needed.Let me know if you have any other questions or if thereâs anything else I can assist you with.
Hi Roshan! Thank you for your response!
How do I know that getToken has given me a new token, such that I donât need to do a token refresh using the redirect with prompt=none?
When is the Kinde session cookie not present or invalid?
Does getToken refresh both the ID and access tokens?
I think it would be great to have official helper methods to make this easier for someone jumping into Auth with Kinde đđť
The current user feedback is that having to login too often because the token lifetime ran out is very annoying for them. (I am using passwordless login)
Thatâs why I am actually considering to increase the token lifetime from the Kinde defaults.
An official helper for this kind of workflow would definitely streamline things â Iâll pass that suggestion on to the team.
Thanks for the feedback, Paul.
Thanks for the feedback, Paul.
Hello Roshan, when trying to call getToken on the client (not server) I receive following error:
Am I misunderstanding something?
Here is my code :
Thank you again.
Paul,
The error is happening because getToken in the SvelteKit SDK is designed for server-side usage only â it depends on SessionManager and server-side environment variables, which arenât available in the browser. If you need to access the token on the client, youâll need to: Call
The error is happening because getToken in the SvelteKit SDK is designed for server-side usage only â it depends on SessionManager and server-side environment variables, which arenât available in the browser. If you need to access the token on the client, youâll need to: Call
getToken
in a server context (+page.server.js
, +layout.server.js
, or server actions) and pass the token to your client code, or
The SvelteKit SDK is primarily intended for backend/session handling, which is why it tries to import server-only modules when run in the browser.Thanks Roshan,
previously you wrote:
â2. On the client, call
kindeAuthClient.getToken(request as SessionManager)
. If the user has a valid session, the SDK will refresh the token silently and return updated claims.â
So we mixed up something there?
I donât need the token on the client. I just wanted to try your recommendation.Sorry Paul,
That was a mistake on my part. The wording should have been clearer.
What I meant was:
â2. Call kindeAuthClient.getToken(request as SessionManager)
.â
This is intended for a server-side context, not the client.No worries!
So calling getToken on the server refreshes the token and updates the claims of the user if he has a valid session?
Hi Paul,
Apologies for the delay â I was testing this out and also checked in with our senior engineers.
What youâve done with your helper around
getToken
wonât instantly give you a new token with updated claims. Apologies for the misunderstanding on my end.What youâve done with your helper around
/api/auth/login?prompt=none
is currently the most reliable way to force a refresh and get the latest claims.
If you need real-time updates in sensitive flows (e.g. checking permissions during a payments process), you could also call the Permissions API at that moment. This ensures youâre working with the most up-to-date state, even before the normal refresh cycle kicks in.
Iâve also passed along your request for a dedicated helper to our internal team â itâs definitely on our radar.Thank you for your clarification, Roshan! đ
Happy to help, Paul! Donât hesitate to reach out if you need anything else.