K
Kinde2mo ago
EJ.

M2M API Scopes Not Updating After Edit. Must Recreate Application

I've encountered an issue with updating M2M application scopes in the Kinde dashboard. When I edit an existing Management API application to add new scopes (for example, I had read:user_properties at start and later I want to add update:user_properties) and save the changes, the API calls still fail with: {"errors": {"code": "SCOPE_MISSING", "message": "Scope is missing: update:user_properties"}} Workaround found: The only way I could get the new scopes to work was to: 1. Delete the existing M2M application 2. Create a new M2M application 3. Configure all required scopes during initial setup 4. Update environment variables with new client credentials It appears that scope changes to existing M2M applications are not properly propagated.
9 Replies
Abdelrahman Zaki - Kinde
Hi @EJ., when you update the scopes on an existing M2M application, you’ll need to generate a new access token for the updated scopes to take effect. The old token won’t include the new scopes, which could be why you're seeing that error. Just to check, did you generate a new access token after adding update:user_properties? Let me know, and happy to help further!
EJ.
EJ.OP2mo ago
You are referring to the m2m access token? Is there a specific way to generate a fresh access token? Maybe it's cached but not on my end so it's not fresh?
Abdelrahman Zaki - Kinde
Yes, I meant the M2M access token. Just to clarify, how are you currently generating or using the access token? For testing purposes, you can generate a fresh token directly in the Kinde Admin: - Open your M2M application in the Kinde dashboard - Go to the Quick start - Click Get token - Select Use test token That will give you a new token with the latest scopes applied. Let me know if you're seeing the same issue with a test token, and we can dig deeper!
EJ.
EJ.OP2mo ago
We are using a Next.js application with the M2M client credentials flow exactly as documented. Our Next.js API route makes a POST request to the token endpoint: In our Next.js API route handler const response = await fetch(${this.baseUrl}/oauth2/token, { method: "POST", headers: { "Content-Type": "application/x-www-form-urlencoded", }, body: new URLSearchParams({ grant_type: "client_credentials", client_id: this.clientId, client_secret: this.clientSecret, audience: ${this.baseUrl}/api, scope: "read:users read:user_properties update:user_properties read:billing_agreements read:billing_entitlements create:meter_usage", }), }); I've updated the M2M application in the Kinde dashboard to include 6 scopes (from the previous 4): - read:users - read:user_properties - update:user_properties - read:billing_agreements - read:billing_entitlements - create:meter_usage However, when I decode the JWT token returned by Kinde, it only contains 4 scopes: 📋 Token scopes received: create:meter_usage read:billing_agreements read:billing_entitlements read:users (this is my log) The read:user_properties and update:user_properties scopes are missing from the token, even though: 1. They are configured in the M2M application settings 2. We're explicitly requesting them in the scope parameter 3. We've restarted the Next.js development server multiple times 4. We're forcing new token generation (not using cached tokens) This results in a 403 error when trying to use the update endpoint: {"errors": {"code": "SCOPE_MISSING", "message": "Scope is missing: update:user_properties"}} Next.js 15.3.3 running on localhost:3000 running in Kinde EU region. For context, this is for a user profile dashboard with more bells and whistles than the self serve portal.
Abdelrahman Zaki - Kinde
Thanks for the detailed info! Just to confirm the scopes are being applied correctly, could you try generating a token via the Quick start tab in your M2M app in the Kinde dashboard and check if the scopes are included in the access token?
EJ.
EJ.OP2mo ago
Yes scopes are indeed included in the test access token
Abdelrahman Zaki - Kinde
Thanks for confirming that the test token includes the correct scopes. I just tried to reproduce the issue using the same flow via the /oauth2/token endpoint and the token returned included all configured scopes as expected. Could you try making the same token request using a tool like Postman or cURL (outside of your Next.js app) to see if the full set of scopes is returned? Also, if you're still seeing the issue, could you share the exact steps to reproduce it? We’d love to dig deeper and get this sorted. Let me know how you go!
EJ.
EJ.OP2mo ago
I solved it. The issue was that in the management api service I created, the scopes were pre-limited const tokenUrl = ${this.baseUrl}/oauth2/token; const response = await fetch(tokenUrl, { method: "POST", headers: { "Content-Type": "application/x-www-form-urlencoded", }, body: new URLSearchParams({ grant_type: "client_credentials", client_id: this.clientId, client_secret: this.clientSecret, audience: ${this.baseUrl}/api, scope: "[x] [y] [z]", }), }); so even if I added scopes in Kinde dashboard, I couldn't use them Thanks for your help!
Abdelrahman Zaki - Kinde
Ah, that makes perfect sense, thanks for sharing what you found! Really glad you got it sorted. Let us know if anything else comes up or if we can help with anything further.

Did you find this page helpful?