App.profile is blank when the application type is API

When using the client_credentials flow, app.profile is empty when trying to make a custom claim. So, when requesting a token and trying to include any value from it there is nothing. My issue is that in order to not statically map Okta appIds to groups in our application code we’d like to include them in the claim like we are able to do with use tokens. App attributes are also not very well documented anywhere.

Even trying an expression like getFilteredGroups({"the app id"}, "", 5) does not return the groups for this type of app.

This is another thread I found on the issue:

Is there a way to get group information in the token? It seems like a bug that the app profile is totally blank here.

Hello @axdev,

By default app.profile will return {} as there are no attributes by default.

For an example of adding attributes to the applications profile to be retrieved by a claims expression see here.

But if you are using a client credentials grant type there will be no user context associated with the flow, so there is user to query for group membership.

You can still access the app.profile object in a claim for a client credentials application, but really all you can do is use the values as are. You can’t return a list of group ids and then check for membership in those groups since there is no user to check against.

Thank You,

1 Like

Ok, thanks. But what is the purpose of assigning an app to a group if that info can never be accessed? It somewhat defeats the purpose of trying to secure application access using groups by keeping this info only in Okta. Now we have to manage this attribute outside of Okta, thus making it less secure.

Additionally, it isn’t clear why an attribute prefixed with app would require any user to be attached at all. We can clearly access variables attached to the app only in the example you shared, so it still doesn’t make sense why a a function like getFilteredGroups can’t get group info based on the list it has been passed.

In the case of getFilteredGroups the purpose is to pass it a list of groups to search and only return groups which a user (principal of the current flow) is a member of.

So if userA is a member of 500 groups, and appA only has any rules set up for 20 groups. Then those 20 groups would be passed to the function and only the groups userA is a member of (if any) would be returned.
The function allows an application to limit groups that are returned to only what it is interested in.

1 Like

Maybe it’s a documentation issue, but “pass it a list of groups to search and only return groups” does not work in the case of getting a token for client_credentials flow. Regardless of if you pass it a static list of groups or a manual allowlist like in the link below. The function itself doesn’t work based on the group ids parameter, which is confusing in the way it is documented. (the link you shared earlier makes it seem like you can use the static list of ids with getFilteredGroups in the client_credentials flow. This does not seem to work.)

You can’t use getFilteredGroups when there is not a user in scope, because that function will still try to compare the lists of groups assigned to the user in context against the provided list. You can still dump the list of groups from the app.profile attribute you created to store the list into a claim though, but there is no direct way to have a claim match against the list of groups assigned to the app itself.