bawsky
bawsky•5mo ago

Roles missing in access token (JWT)

Hello. I'm trying to request access tokens with projects' roles without success - is this a bug or am I missing something? Authorization request (line breaks for readability):
# note the scopes:
# openid email profile urn:zitadel:iam:org:project:id:{projectid}:aud urn:iam:org:project:roles urn:zitadel:iam:org:projects:roles

http://localhost:8080/oauth/v2/authorize
?client_id=317093501659578371
&response_type=code
&redirect_uri=http%3A%2F%2Flocalhost%3A5000%2Fapp%2Fsign-in%2Fzitadel
&response_mode=query
&scope=openid%20email%20profile%20urn%3Azitadel%3Aiam%3Aorg%3Aproject%3Aid%3A317093501441409027%3Aaud%20urn%3Aiam%3Aorg%3Aproject%3Aroles%20urn%3Azitadel%3Aiam%3Aorg%3Aprojects%3Aroles
&code_challenge=ocYCWfMwcSjWZok91g7EAZsKLdqPI7Nn_qoUWIdHHM4
&code_challenge_method=S256
# note the scopes:
# openid email profile urn:zitadel:iam:org:project:id:{projectid}:aud urn:iam:org:project:roles urn:zitadel:iam:org:projects:roles

http://localhost:8080/oauth/v2/authorize
?client_id=317093501659578371
&response_type=code
&redirect_uri=http%3A%2F%2Flocalhost%3A5000%2Fapp%2Fsign-in%2Fzitadel
&response_mode=query
&scope=openid%20email%20profile%20urn%3Azitadel%3Aiam%3Aorg%3Aproject%3Aid%3A317093501441409027%3Aaud%20urn%3Aiam%3Aorg%3Aproject%3Aroles%20urn%3Azitadel%3Aiam%3Aorg%3Aprojects%3Aroles
&code_challenge=ocYCWfMwcSjWZok91g7EAZsKLdqPI7Nn_qoUWIdHHM4
&code_challenge_method=S256
Token request body (line breaks for readability):
grant_type=authorization_code
&client_id=317093501659578371
&redirect_uri=http%3A%2F%2Flocalhost%3A5000%2Fapp%2Fsign-in%2Fzitadel
&code_verifier=ThisIsntRandomButItNeedsToBe43CharactersLong
&code=ONEHefIhLq9n6KgnHO6gdD9JX8np2jaB3IsJyWOzL3Zjnw
grant_type=authorization_code
&client_id=317093501659578371
&redirect_uri=http%3A%2F%2Flocalhost%3A5000%2Fapp%2Fsign-in%2Fzitadel
&code_verifier=ThisIsntRandomButItNeedsToBe43CharactersLong
&code=ONEHefIhLq9n6KgnHO6gdD9JX8np2jaB3IsJyWOzL3Zjnw
Retrieved access token
{
"iss": "http://localhost:8080",
"sub": "317094026115284995",
"aud": [
"317093501659578371",
"317093501441409027"
],
"exp": 1745542441,
"iat": 1745499241,
"nbf": 1745499241,
"client_id": "317093501659578371",
"jti": "V2_317094820197695491-at_317094820197761027"
}
{
"iss": "http://localhost:8080",
"sub": "317094026115284995",
"aud": [
"317093501659578371",
"317093501441409027"
],
"exp": 1745542441,
"iat": 1745499241,
"nbf": 1745499241,
"client_id": "317093501659578371",
"jti": "V2_317094820197695491-at_317094820197761027"
}
obs.: the role claims are also not present in the id token, but they ARE present in the userinfo response
7 Replies
bawsky
bawskyOP•5mo ago
Here are my setup steps: 1. Setup the main org/project/app: 1. Create a new 'example_org' organization 2. Inside the 'example_org' organization, create a new 'example_project' project - in the project 'General' settings, enable "Assert Roles on Authentication" 3. Inside the 'example_project' project, create a new 'example_role' 4. Inside the 'example_project' project, create a new 'example_app' (note: I'm using a 'User Agent' app, with PKCE enabled) - in the app 'Token Settings' settings, set "Auth Token Type" to "JWT" 2. Setup another org with a user: 1. Create a new 'example_org2' organization 2. Inside the 'example_org2' organization, create a new 'example_user' user 3. Grant the user access to the project: 1. Inside the 'example_project' project, grant 'example_role' to the 'example_org2' organization 2. Inside the 'example_org2' organization, grant 'example_role' authorization to the 'example_user' user userinfo response:
{
"email": "user@example.com",
"email_verified": true,
"family_name": "example",
"given_name": "user",
"locale": null,
"name": "user example",
"preferred_username": "user@example.com",
"sub": "317094026115284995",
"updated_at": 1745498768,
"urn:zitadel:iam:org:project:317093501441409027:roles": {
"example_role": {
"317093501844062211": "exampleorg2.localhost"
}
},
"urn:zitadel:iam:org:project:roles": {
"example_role": {
"317093501844062211": "exampleorg2.localhost"
}
}
}
{
"email": "user@example.com",
"email_verified": true,
"family_name": "example",
"given_name": "user",
"locale": null,
"name": "user example",
"preferred_username": "user@example.com",
"sub": "317094026115284995",
"updated_at": 1745498768,
"urn:zitadel:iam:org:project:317093501441409027:roles": {
"example_role": {
"317093501844062211": "exampleorg2.localhost"
}
},
"urn:zitadel:iam:org:project:roles": {
"example_role": {
"317093501844062211": "exampleorg2.localhost"
}
}
}
NOTE: selecting "Add user roles to the access token" in the application's "Token Settings" work, but then the roles are retrieved independently of what scopes I pass (i.e. urn:iam:org:project:roles and urn:zitadel:iam:org:projects:roles scopes seem to be ignored) Also probably relevant: I'm running Zitadel locally with docker-compose v2.71.7
Rajat
Rajat•5mo ago
hi @bawsky do you have Add user roles to the access token enabled within the User Agent app?
Rajat
Rajat•5mo ago
No description
bawsky
bawskyOP•5mo ago
Hello @Rajat! I've actually tried both ways: - when it's selected, the user roles are ALWAYS added to the access token, regardless of urn:iam:org:project:roles and urn:zitadel:iam:org:projects:roles scopes - when it is not selected, the user roles are NEVER added to the access token, regardless of urn:iam:org:project:roles and urn:zitadel:iam:org:projects:roles scopes
Rajat
Rajat•5mo ago
hi @bawsky apologies for the trouble :)) as a fallback/workaround, since roles are present in the /userinfo response but not in the token, retrieve them via an API call to /oauth/v2/userinfo after authentication , while I check with my team if its a bug or a feature. If that helps. Thanks
bawsky
bawskyOP•5mo ago
No trouble at all! We're just starting the work on integrating Zitadel into our already-consolidated product - so this issue doesn't really affect us yet (we are integrating Zitadel for authentication but we still control roles and authorization inside our application - I'm just evaluating the possibility of also migrating that part to Zitadel at some point in future). Thanks a lot for the response @Rajat 😄 Looking forward to understand this - please keep me updated here (and let me know if I should open a GitHub to track it if it's a bug).
Rajat
Rajat•5mo ago
hi @bawsky sure, pls go ahead and open a bug 🙂 tag this thread and someone from the team will take a look and we'll prioritise it

Did you find this page helpful?