Skip to main content
Reading Time: 3 minutes

Okta Workflows is an Okta no-code platform feature for automating identity processes.

The challenge

Have you ever had a scenario where you’ve created a user in Okta Universal Directory (UD), matched or provisioned them into an Active Directory (AD), and later need to get their Immutable ID into their Okta profile? Or maybe you have a user in two ADs and the ‘hasDirectoryUser()’ expression to grab the Immutable ID is giving you a ‘null‘ response?  This post is going show you how I solved a recent use case and hopefully will help you solve yours.

What’s Okta doing?

When a UD user is matched or created in AD, Okta stores an Application User profile with attribute values from AD associated with each user. Depending on your profile source mastering, this information may not be easily mapped as attribute mapping may be set to map over ‘Create Only’ rather than ‘Create and Update’.

Apply mapping on user create only screenshot

Mappings only available on user creation

This desired user data can normally be seen when you test an expression mapping is working, example below:

Screenshot of previewing okta expression mapping

Previewing an expression mapping to MS365

In this scenario, the expression used, hasDirectoryUser()?findDirectoryUser().externalId:null, will only work if the user is part of one AD. If they are added to another AD then the expression will come back ‘null’ value and you are unable to change the expression to check a specified directory application.

findDirectoryUser() – Finds the Active Directory App user object and returns that object or null if the user has more than one or no Active Directory assignments
Reference: Okta Expression Language

So why don’t you create a new mapping to a custom attribute?

This could work (Okta Support Article), however, it may only work on account creation from AD to Okta instead of when the account is updated or matched.

The answer is to grab the information directly from the desired AD application ‘on-demand’. As part of my discovery work, I looked at the Okta API calls that would allow me to GET the information I needed from the application data. In the below example, the ‘Concatenate’ card is used to construct the relative URL needed for the API call. From the JSON response, we can then get multiple values and pass them on (for info on this checkout this How-To: by Max Katz).


If you were looking to implement this workflow for multiple use cases, this is more scalable as it allows the passing of variables therefore not needing to add more flows. Also, Custom API Action (CAPIA) cards generally perform faster than the in-built cards, so this might be a factor to weigh up when implementing.

The Solution

We’ll keep it simple and use the pre-built Okta cards, that way, the workflow can be amended without having to know the unique app ID.

Diagram of the solution:


  1. The flow is triggered by a Delegated Flow requiring the username/email of the end user to be entered by an admin.
  2. The username is read by Okta and the Okta ID and account status are output.
  3. Flow logic then continues if the Okta account is not deactivated and lists the groups the user is a member.
  4. The flow will return an error if the user is not a member of the Office 365 group (the admin who triggered the flow will get an alert) but otherwise continue.
  5. Using the Okta ID, the flow with try to get the External ID from AD 1 and ‘if error’ get the External ID from AD 2. If that errors then the delegated flow admin will be notified.
  6. The Okta ID and External ID are passed to the Office 365 application profile to update.

Below is how the workflow looks in action:

Part 1: Update MS365 ImmutableID

Part 2:  Update MS365 ImmutableID

Important: As this flows trigger is set to Delegated Flow, it will be visible to Super Admins or Delegated Flow Admins, whether it is active or inactive (greyed out) in the Okta Admin dashboard > Workflow > Delegated Flows section. Change the trigger to a helper flow to remove visibility when testing. Image below:

How the delegated flow will look, with title and description taken from the workflow.


Run flow pop-up shown to Okta admins.


As Okta has cached attribute information ready to use, this has unlocked some potential for further use. The trigger for this flow could be changed to when a user is added to a group or utilised as a helper flow for a batch action. You also don’t have to update an application profile, it could be the user’s profile directly.

More resources