A key aspect of identity governance is being able to see “who has access to what”. Within Okta you have visibility to user-to-group and user-to-application mappings (i.e. the associations that Okta is managing). These are often called coarse-grained entitlements. But what about the fine-grained entitlements that are normally defined and managed within an application, such as licenses, roles or profiles? In many cases Okta has visibility to these entitlements and we can use Okta Workflows to report on them.
This article looks at how we can use Okta Workflows to report on fine-grained entitlements stored in user profiles and other objects in the Universal Directory. It includes examples of AD groups, Office365 user profile attributes and Salesforce user profile attributes.
Article contents:
Introduction
Before looking at some implementations, let’s look at what data we have to work with and how to access it.
Fine-Grained Entitlements Held in Universal Directory
Within Universal Directory (UD) we may hold different types of fine-grained entitlements; there may be application group assignments, other group-like assignments, and attributes held on an application assignment.
What is stored in UD will depend on the application and the integration with Okta. For the first two, many integrations will pull in application groups or other group-like objects, where the assignment of users is managed within the application not within Okta. Common examples are Microsoft Active Directory and Microsoft Azure AD – we import groups from these directories into Okta and can use them for policy in the same way as Okta groups, but we don’t manage the user-to-group mapping.

The other source of entitlements is in the application profiles and application assignments. Many application user profiles will contain attributes that may be considered entitlement. For example the Salesforce user profile includes profile, roles, permission sets and licenses as attributes. The Office365 user profile contains roles and licenses. It is common to assign these by group.
Thus the fine-grained entitlement information is in the Universal Directory, but it’s hard to get a single view or report. This is where Okta Workflows comes in.
Approach Using Okta Workflows
The approach is quite simple; pull the data from UD, massage as required, and store it in a workflows table.
This table could simply be exported as a CSV file or you could build more comprehensive report delivery mechanism. For example I have flows built that will (on a schedule) export a table to CSV, store them on a shared Google drive, set access permissions, and send an email to an administrator with a link to the report CSV.
At its simplest, the workflows only need an Okta connector to retrieve the data, some internal logic (in cards and subflows) for data massaging and a table to store the report data. It is straightforward, but there would need to be a set of flows for each different application as the application user profiles and required attributes would be unique.
The remaining sections of this article will look at three examples; reporting on AD groups and reporting on Office365 and Salesforce fine-grained entitlements.
Reporting on AD Groups with Workflows
Importing Active objects will include all AD users, groups and group memberships. As the groups are connected to policy in Active Directory, they can provide some fine-grained entitlement information (although naming standards will dictate how useful the information can be).
The Data and the Result
This is the simplest case of those shown here as we can extract a list of groups associated with an AD “application” (i.e. a directory integration), find all the users in each group and list them out into a table.
This will result in a list similar to the following.

This could be exported and worked on in a spreadsheet product like Microsoft Excel.
Looking at the Workflows Behind It
To extract the groups and produce the list in the table above involves three flows – a main flow and two subflows (now called Helper flows).

The first flow is the main flow. It could be scheduled to run periodically, but in this case it is set to run on demand. The flow logic is:

The four cards will:
- Set the application ID of the AD “application” (directory integration) in a variable. This could be more dynamic pulling from a list of AD applications but works for the sake of the example.
- Set the API URL to query the groups API for all groups where
type eq "APP_GROUP" and source.id eq the appid
from the first card - This API URL is used with a Custom API Action card for the Okta connection. There is no ootb Okta Connector action for this type of query
- For each group found in that AD instance, a helper flow is called to get the group profile and users.
The flow logic for this first helper flow is:

The helper flow is passed one group object. For that group it will:
- Extract the id of the group
- Use that id in an Okta List Group Members card to return a list of users in the group
- For each user in the list, a helper flow is called to write the user and group information to the table
The flow logic for the second helper flow is:

The helper flow is passed both the group object and the user object. It will extract group profile attributes from the group object and the login from the user object, then write them to the table.
This concludes the flows for the AD group report.
Reporting on Office365 User Profile Attributes
As mentioned above, the Office365 user profile contains some attributes, like roles and licenses that may be considered fine-grained entitlements.
The Data and the Result
This report involves finding all users associated with an Office365 application, reading the relevant application user profile attributes and writing them to a table.
The result will look similar to the following.

Note that it only includes license information as my test system doesn’t have roles setup.
Looking at the Workflows Behind it
There are two flows involved:

There’s a main flow to get all users in the application and a helper flow to process each user.
The main flow is shown below:

There are five cards:
- The first card will empty the report table
- The second card sets a variable with the ID of the Office365 application
- The third card sets a variable with the API URL to get a list of users for the application (
/api/v1/apps/appId/users
) - The fourth card will run a custom API Action with that API URL to return the list of users (a list of objects)
- The last card calls a helper flow to process each user
The helper flow is shown below:

It is passed a single user object. The first card will extract the username, licenses and displayname from the user object. Note that this is processing the application user profile NOT the Okta user profile. The second card will convert the list of licenses into a comma-separated string. The last card writes the record to the report table.
This flow could easily be modified to extract additional attributes and write them to the table.
Reporting on Salesforce User Profile Attribtes
Like with Office365, the Salesforce application user profile contains attributes that could be considered fine-grained entitlements.
The Data and the Result
This report involves finding all users associated with a Salesforce application, reading the relevant application user profile attributes and writing them to a table.
The result will look similar to the following.

Assuming the system was setup with real data, you could get role, groups (salesforce and public), profile and licenses for each user.
Looking at the Workflows Behind it
There are two flows involved:

These are basically the same as the Office365 flows above. The first will find all users in the Salesforce application. The second will extract the relevant attributes out, where they are a list (salesforceGroups, publicGroups and featureLicenses) convert them to a string, and write the values to a table. The main part of the second flow (the helper flow) is shown below.

That concludes the exploration of the flows.
Conclusion
This article has shown that Okta does have some fine-grained entitlement information stored in the Universal Directory, either in the form of application-specific groups or application user profile attributes. It is a reasonably straightforward exercise to use Okta Workflows to extract and massage this data and store it in Workflows tables for export.
The examples above, for Active Directory groups, Office365 and Salesforce user profile attributes could be used as templates for other applications and help answer the governance question of “who has access to what”.
Sample Code
The workflows example described above can be downloaded from https://github.com/iamse-blog/workflows-templates/tree/main/dae-iga05-FineGrainedPermissionReporting
2 thoughts on “Fine-Grained Entitlement Reporting with Workflows”