OIG – Certification for External System Entitlements

A common ask for Okta Identity Governance (OIG) is to be able to do access certification on external application data. Currently OIG can only run campaigns on objects (group memberships and application assignments) in the Okta Universal Directory (UD).

Importing of external system entitlements is on the product roadmap. But with some understanding of the UD data model, Okta Workflows and the new OIG API (currently in beta), a solution can be built to import external entitlements in Okta, create groups to represent the entitlements and run a campaign against them.

This article shows an example of a solution that has been built for some customers recently. As always, this is not officially supported code, but should be considered an example of how to implement the requirements and use the OIG APIs. It is designed for test data and may not cope with tens of thousands of user-entitlement entries; it has only been tested on a small volume; it stores user-entitlement entries as rows in a Workflows table and a single list of objects in a main flow. YMMV.

To use this mechanism there is some pre-work needed, then the data needs to be imported via one of the import flows, a flow is run to use the data to create the appropriate objects and relationships in Okta, and finally a campaign is built and launched. For the import there are three options to load the data: 1. Google Sheets, 2. Excel Online, 3. Google Drive.

The code and documentation for this solution can be found on our iamse-blog github.

NOTE – there is another approach using a CSV directory documented here: https://iamse.blog/2022/08/18/certifying-access-for-disconnected-application-in-okta/. That approach achieves the same outcome of a cert campaign, but involves deployment of the On-Premise Provisioning (OPP) agent. It does not present the app entitlements as groups so the entitlement visibility is limited.


Okta Identity Governance (OIG) does not currently support importing external apps and their access entitlements into Okta. This integration, implemented in Okta workflows, provides three examples of importing a CSV file into an Okta workflows table, taking that data and creating groups to represent the entitlements and associating them with the app, and then creating and launching a campaign.

The end result is an Access Certification campaign, with users assigned to the external app, and the resources to review being the “groups” which are shown as an app-entitlement label.

The remainder of this document will walk through the configuration of this. The following sections are a summary. More detail is provided in the pdf stored with the .folder file here.


The flows will load a CSV file that contains firstName, lastName, email, managerEmail, appName, groupName (the last field, groupName, is the app entitlement to be used and defined as a group). Throughout this article external entitlements will be referred to as “groups” but they could be any entitlement tied to a user.

The following is required to run the flows to import and use the CSV file:

  1. Create a dummy (bookmark) app to represent the external app
  2. Create the User-Groups CSV file
  3. Import the .folder file (see link above)
  4. Setup the Environment Variables table (this set of flows uses a table for common variables used, like apiTokens).

A sample CSV file is shown below:

With this done, you would perform the following steps.

Running the Flows

As per the figure above there are three stages and five sets of flows:

  1. Step 1 – Import the CSV File into a Workflows Table
    • The M1* flows will import the data from a Google Sheets file
    • The M2* flows will import the data from an Excel Online file
    • The M3* flows will import the data from a file on Google Drive
  2. Step 2 – Use the loaded data to update Okta UD
    • The M4* flows will check the users and app, create groups for the entitlements and add users to them, and assign the groups to the app
  3. Step 3 – Create and Launch an access certification campaign
    • The M5* flows will create a campaign for all of those new groups and launch it

Notes for each are in the following sections. They will refer to specific flows by the flow number (e.g. M41).

Step 1 – Import the CSV File into a Workflows Table

The first step is to import the CSV file and store the contents in a Workflows Table. Samples are provided for Google Sheets (the M1* flows), Excel Online (the M2* flows) and Google Drive (the M3* flows).

All flows follow the same pattern, consume the CSV file records and write them to a Workflows table. The end result will look like the following.

There may be some configuration required, such as confirming the appropriate connector is used and that the filename matches. See the pdf for details.

Step 2 – Use Loaded Data to Update Okta

Now that one of the methods above has been used to load all the user-entitlement data into the Workflows table, we run another flow to check the data and apply any updates.

The M40* flow contains the following steps:

  1. Read all the table rows into a common object that will be used for all the following steps
  2. Check all users are valid Okta users by email address using the M41 flow (if any are not valid, the flow will error out)
  3. Check the app is valid by name, using the M42 flow (if there’s no app by the name in the CSV, the flow will error out) and return the app ID
  4. Strip out a unique group (entitlement) list from the CSV data using the M43 flow
  5. For each unique group (entitlement) create an Okta group (name is <app>-<group>), add the relevant users and assign that group to the app using the M44 flow

When you run this flow you will see in Okta there are new groups created, that they have the users assigned as per the CSV, and the group is assigned to the app.

With these Okta objects and relationships we can now create and launch a campaign.

Step 3 – Create and Launch a Campaign

The last step (set of flows) is to use the new data to create and launch a campaign, where the resources are the entitlements (i.e. groups called <app>-<group>). 

The M50* flow contains the following steps

  1. Setup some common variables for the two sub flows
  2. Create the campaign using the M51 flow
  3. Launch the new campaign using the M52 flow

You don’t need to change any campaign parameters. It will set the date as the next day (D+1), run for 30 days, use the user.profile.managerId field for reviewer and it uses a single Okta user (Id stored in the Environment Variables table) for the fallback reviewer. If you want to alter any of these settings, you will need to go into the M51 flow and modify there. 

Run the M50 flow and you should see a new campaign with the resources being all the groups for the app as per the CSV. The following figure shows the new campaign in the Okta Admin Console.

Expanding the campaign shows that the resources are the groups that were in the CSV file.

The detail of the campaign shows that the resource is the combination of app and entitlement (i.e. <appname>-<groupname>). This was one of the design criteria – we needed to show the manager what the external application entitlement was.

From here it is standard access certification execution. There is no removal of access on a revoke. You could build additional flows that would respond to the review-revoke event and go update the CSV in whichever location (Excel Online, Google Sheet, Google Drive) but that has not been done here.

Exploring Using OIG APIs in Workflows

The logic in the M1*-M4* flows are fairly standard – they import external files, process Workflows tables, and integrate with Okta via the Okta connection to manage the process.

The last set of flows are using the OIG APIs to create and launch a campaign and it’s worth having a look at it as we don’t have many examples yet (and we don’t have an OIG connector).

The following sections look at the main M5* flows and how they’ve been structured. As there is no OIG connector, we have to use the HTTP API functions to call the OIG APIs.

M50 – Main Flow to Create and Launch a Campaign

The main flow will setup some variables used in the sub flows (application name/id, domain name, authorization token) then call sub flows to 1) create the campaign and 2) launch the campaign.

This is a basic flow to make the process more readable – all the steps of M51 & M52 could have been included in M50.

M51 – Create Campaign

This flow will used various cards and subflows to build up the body of the request then run the request to create the campaign. The steps are shown in the following figures.


The first step is to construct the API endpoint URL.

Defining the API URL

Build the API Call Body

Then we define the contents of the API Call body, which is a complex object.

The scheduleSettings define when the campaign will run. In this case we are setting it to launch tomorrow (today + 1 day) and run once for 30 days.

Defining the scheduleSettings block for the body

The resourceSettings object defines the resources to be reviewed. In this case we’re pulling out the unique list of groups and defining the object list in a subflow.

Defining the resourceSettings block for the body

The principalScopeSettings is set to USERS. The reviewerSettings define how the reviewer is defined, in this case it’s an expression (OEL) using the user.profile.managerId attribute (with a stored ID for an admin as the fallback reviewer).

Defining the principalScopeSettings and reviewerSettings blocks for the body

The last block is the remediationSettings and in this case we’re setting NO_ACTION for all three.

Defining the remediationSettings block for the body

Then we construct the HTTP body object with all of the attributes and objects constructed above.

Construct the API call body from earlier steps

The following figure shows the HTTP body object built by these steps.

Sample body object

Make API Call and Retrieve the Launch URL

Finally we use the URL and body from above to make a POST to create the campaign. We get the launchCampaignURL to return for use in the next section.

Call API to build campaign and retrieve Launch URL

M52 – Launch Campaign

The final step is to launch the campaign. This is trivial as we have the launch URL from the create step above.

And that’s it, and example of how to use workflows to create and launch a campaign.


This article has shown how Okta Workflows can be used to import user entitlement data from an external app into Okta and run a campaign on it. It shows importing a CSV file (via three different mechanisms), creating groups to represent the entitlements and then running a campaign on them

It also explores how Workflows can setup and make the relevant OIG Campaign API calls to create and launch a campaign.

One thought on “OIG – Certification for External System Entitlements

Leave a Reply