Okta Identity Governance (OIG) provides an access certification component for reviewing users and their access. When reviewing access, a reviewer (such as a users manager) can approve or revoke the access (or reassign). With the revoke action, the access certification campaign can be configured to automatically remove access or do nothing (i.e. leave the access as is).
But what if you want to have some custom processing around a revoke action (or an approve for that matter)? This is where you can leverage Okta Workflows. This article will explain the mechanism to trigger a workflow from a campaign and how to access the data passed in the event. It won’t go into detail on how to build workflows – there are many articles around on here (https://iamse.blog) and other sites (like https://maxkatz.net/).
First, some terminology to set the baseline:
- Campaign – this is a dataset of accesses to review over a period of time, such as group membership or application assignment.
- Review – this is a single item in a campaign, such as a user group membership or user app assignment
- Reviewer – the person reviewing the access, such as the users manager or application owner
- Event – here were are referring to an event in the Okta System Log
- Flow – an individual workflow in a Workflows folder
- Connector – a Workflows connector
The mechanism to trigger a workflow from an Access Certification campaign is fairly straightforward:
- Any action (decision) on a review (approve, revoke, reassign) or campaign event affecting reviews (e.g. end campaign) will write an event into the Okta System Log,
- A flow is configured to be triggered when that event is written to the system log (using a new event in the Okta Connector), and there are two ways this can be done, and
- The flow is passed the event details (in an object), which it unpacks and uses to perform some custom action such as logging a ticket in a ticketing system or sending an email.
The following sections look at the event, how to trigger a flow off it and how to process the event details.
Campaign Events in the Okta System Log
I will use an example to show the data flowing through the system. I created a simple group membership campaign, launched it then had one of the managers perform their reviews.
These three reviews will trigger multiple events in the Okta system log. There are two event types related to the review:
certification.campaign.item.decide– the decision, such as the approval or revoke, and
certification.campaign.item.remediate– the remediation taken as a result of the decision
You can trigger a workflow via an Event Hook for either event. If you want to use the Okta Connector to trigger, you can only do it on the decide event.
There are also events for campaign launch, update and close (e.g.
All events in the Okta System Log have the same overall structure, its only at the DebugData level that campaign-specific attributes are used. We will focus on the
certification.campaign,item.* specific attributes.
The certification.campaign.item.decide Event
Let’s look at the
We can see the three events corresponding to the reviews by the manager, two approves and one revoke.
Expanding the REVOKE event, at a high level we see Actor (reviewer), Client, Event, Request and Target (review item) as you would for any System Log event.
The Client and Request sections are of no value for campaign review events, so we will ignore them.
Drilling in further we can see the Actor attributes tell us about the reviewer.
The Event section contains a wealth of information about the review.
Of note is the DisplayMessage, Result and all of the data in the System.DebugContext.DebugData section. This includes the decision and notes, the principal (user who’s access is being reviewed), the resource (including type and name) and template (i.e. campaign). This rich set of information is very useful for running actions in response to a review.
The Target section provides some information but is rehashing the DebugData information above.
You will get the most value out of the Event data, and perhaps the AlternateId (Okta username) of the reviewer in the Actor section.
The certification.campaign.item.remediate Event
The remediate events have the same overall structure. The Client and Request sections provide no value for these campaign events. The Actor section details the reviewer and the Target section consolidates information about the review item that is detailed in the Event section.
The Event section information, specifically the System.DebugContext.DebugData, is the same as in the decide event. The decide event has four more attributes (RequestId, RequestUri, TargetEventHookIds, and Url) which may be useful for using in workflows.
One benefit of the remediate event over the decide event is the Event Info summary (top level of event view in System Log) and the Event.Outcome.Result value. If there is an issue remediating access (requiring manual remediation), the remediate event will show a result as SKIPPED, whereas the corresponding decide event will show SUCCESS. If you wanted to build flows specifically for manual remediation, then knowing the remediate event result may be of value. But as mentioned earlier, you can only get this event type via an Event Hook and API Endpoint, not via the Okta Connector.
Key Campaign Review Item Event Attributes
The following table lists the key attributes in the Actor and DebugData sections that are relevant to campaign review events. (Note that the attribute naming below is as per the Event, not the object you will work with in workflows).
|Attribute||Description and Use|
|.AlternateId||Okta username for the reviewer. Note that this field is not exposed in the DebugData, so if you want this attribute in your workflow, you can use this one (or get the ID and do a lookup into Okta).|
|.ID||Okta Id for the reviewer.|
|.DisplayName||Okta full name for the reviewer.|
|.Type||This will always be “User” for these events (but could be different for other System Log events)|
|Event.DisplayMessage||Display message like “Access certification review decision: REVOKE”|
|Event.EventType||certification.camapign.item.decide or .remediate|
|Event.Outcome.Result||The result of the event – it should always be “SUCCESS” for a decide event. For a remediate event it may also show “SKIPPED” if the access couldn’t be remediated. This field may be useful for error checking on workflows.|
|.CampaignId||Object Id for the campaign (can be used in Campaign API calls to get more info about the campaign)|
|.CampaignItemDecision||Review decision – according to the API docs, the values are: “APPROVE”, “REVOKE” or “UNREVIEWED”. However I have seen “DELEGATE” in one event.|
|.CampaignItemDecisionNotes||If the review has added a note when approving, revoking or reassigning|
|.CampaignItemId||Object Id for the review item (can be used in Review API calls to get more information about the review item)|
|.CampaignItemPrincipalId||Okta Id for the user who’s access is being reviewed|
|.CampaignItemPrincipalName||Okta full name for the users who’s access is being reviewed|
|.CampaignItemRemediation||Remediation action taken in response to revoking access. Will be “DENY” or “NO_ACTION” depending on the remediation settings of the campaign.|
|.CampaignItemRemediationStatus||The status of the remediation. According to the API docs, the values are: “ERROR”, “MANUAL”, “NONE”, “OPEN”, or “SUCCESS”|
|.CampaignItemResourceId||Okta Id for the resource (Group or Application) that the user is assigned to|
|.CampaignItemResourceName||Name of the resource (Group or Application) that the user is assigned to|
|.CampaignItemResourceStatus||Status of resource in Okta. Groups should always be ACTIVE, but applications may show as “ACTIVE” or deactivated (not sure of enumeration).|
|.CampaignItemResourceType||“APPLICATION” or “GROUP”|
|.CampaignItemReviewerId||Okta Id for the reviewer. This is the same as Actor.ID|
|.CampaignItemReviewerName||Okta full name for the reviewer. This is the same as Actor.DisplayName|
|.CampaignItemTemplateId||This is a legacy item that is not of any use|
|.CampaignItemTemplateName||Name for the campaign|
To get a better understanding of the OIG data objects, like Campaign and Review, have a look at the API docs: https://developer.okta.com/docs/api/iga/.
Now that we know the events and data sent to the system log, let’s look at how we can get the event data into a workflow.
Triggering a Flow From This Event
There are two main mechanisms to call a workflow and pass the event data:
- Setup an Event Hook and have a workflow triggered by an API Endpoint, or
- Setup a workflow that uses the Okta Connector with the new Event
We will explore both. There are other less effective (and less performant) ways, but we won’t discuss them.
Trigger Workflow with Event Hook
Event Hooks in Okta allow callouts to external URLs based on specific events occurring in Okta. This includes the
To use this mechanism you will need a workflow triggered by an API Endpoint and an Event Hook configured to call that API Endpoint. Let’s start with a simple flow that has that trigger and a single Object:Get Multiple card to expand the data.events part of the event object.
We can see the API Endpoint settings by clicking the icon at the bottom of the card.
We won’t go into details on this. See https://help.okta.com/wf/en-us/Content/Topics/Workflows/function-reference/HTTP/http_accept.htm for more details. The Invoke URL is used in the Event Hook.
This Event Hook is looking for the
For the remediate event you select a different event in the hook.
With this Event Hook active, any review decision event will trigger the flow. For example:
It has pulled the data.events portion (list of objects) out of the body object. The contents of this look like below.
Note that the data and structure is the same as the event in the System Log. Well, almost. The
data.events is actually a list of objects (you don’t see this in the System Log view) as are some of the objects within (like
target). You need to be aware of this when processing event details (see below).
Note – there is a new Event Hook Filter feature rolling out that means you can have specific hooks (and thus specific workflows) for different events of the same type. More information can be found at https://iamse.blog/2022/07/12/event-hook-filtering-and-okta-workflows/.
Trigger Workflow with an Access Certification Decision Card on the Okta Connector
The Okta Connector card in Workflows has been extended to include an Access Certification Decision event (https://help.okta.com/wf/en-us/Content/Topics/Workflows/connector-reference/okta/events/accesscertificationdecisionsubmitted.htm). This will trigger a workflow when a decision event arrives in the System Log. This can only be used for the decide event, there isn’t an equivalent for the remediate event.
As with the Event Hook method, the workflow is presented with the Event details for processing.
Expanding the Event Details object shows the same content as above.
Note that approach this has returned a single object (i.e. the Event Details object), whereas the API Endpoint approach returns the entire event and you need to strip out the event details (data.events) AND select the first item in the array (
data.events.0 in a Object:Get Multiple card).
The Connector event also returns the Actor, Debug Context and Debug Data objects in their own right, so you could directly access them rather than unpacking the entire Event Details.
Obviously these objects/fields are much easier to work with instead of unpacking higher level objects in the event details. The next section looks at how we can unpack the data.
Processing Event Details in the Flow
The data that you need out of the review decision event will depend on what processing you want to do in the workflow. You will definitely need some of the attributes in the
debugContext.debugData object. You may also need some of the
How much unpacking/data processing depends on the mechanism used to trigger the workflow:
- If you have used the Event Hook / API Endpoint mechanism, you will need to use an Object:Get Multiple to unpack the whole event object down to the attributes you need
- If you have used the Okta Connector event, you only need to unpack the Debug Data object (and use any of the Actor attributes directly).
The following sections show examples.
Extracting Event Details from Event Hook / API Endpoint Mechanism
If using this approach you have a bit more work to unpack the campaign review details. The following example shows extracting some debugData attributes.
It uses three Object:Get Multiple cards to 1) extract the
data.events.0 (first array element) object, 2) extract the
debugContext.debugData object, and 3) extract specific fields. You could combine this into one Object:Get Multiple card, but each attribute would need to be fully specified (e.g.
data.events.0.debugContext.debugData,campaignItemDecision) which could be painful (and prone to typing mistakes as the fields aren’t wide enough to see the full string).
When a campaign review is performed you seen an output similar to the following.
You would then use these attributes in the rest of the workflow.
Extracting Event Details from Connector Event
This approach is much simpler than above as the Connector Card event already breaks out the Actor object and the Debug Context and Debug Data objects. In this case a single Object:Get Multiple card will extract the details. In this example, the
Actor.Display Name field is also used in this flow but is off to the right (not shown).
This results in a similar outcome to the previous example.
Again, you would use the event details attributes to drive the flow. The above example shows doing a lookup for the user (principal) in Okta then deciding whether to proceed with the flow (only if the Decision is APPROVE or REVOKE).
Understanding the mechanisms to call an Okta Workflow in response to an Access Certification Campaign, and the data passed to the workflow, is critical to being able to build workflows to implement some custom remediation processing. This article has looked at the data objects written to the Okta System Log and passed to workflows, the two mechanisms to trigger a workflow from that System Log event, and how to unpack and use the data.