Author: iamdavid

  • OIG Access Requests – Where Do I Assign Teams?

    A common concern from a new Okta Identity Governance (OIG) Access Requests deployment is “I can’t see the Application or Group list when building a Request Type”. The most common cause is the assignment of Teams.

    Teams are the access control mechanism built into OIG Access Requests. They control who can create and own Request Types (flows), who can see and use configuration lists (like app lists), and who can be used as approvers and other participants within flows.

    An earlier article, OIG Access Requests – Understanding User Grouping, looked at Teams and how they can be used in flows. This article looks at the three common areas that are missed when creating and using teams in Access Requests: Team membership, Teams assigned to the Okta connection, and Teams assigned to the configuration lists.

    Ensure Your Team Has the Right Members

    A common issue with a new Access Request instance is that the default team (“IT”) does not have the current administrator assigned. When first accessing Access Requests as an administrator, you should go to Teams and check the IT team has you assigned. For any new Team, you should check that the relevant administrators are assigned. If you don’t have administrators assigned they will not see any Request Types they create (they can create, but the new Request Type does not show up in the UI for them).

    In the above example the new Team, Plant Managers, has a new admin, Monty Burns, assigned.

    Ensure the Team is Assigned to the Okta Connection

    For a Request Type to be able to make calls into Okta (e.g. Add User to Group) the Team must be assigned to the Okta connection in OIG Access Requests.

    To check/update Team assignment, go into Settings and edit the Okta Connection.

    Make sure all relevant Teams, including any new ones, are assigned.

    If you add a new Team, you need to make sure they are assigned here.

    Ensure the Team is Assigned to Any Configuration Lists

    Finally, if you want to be able to access any of the Configuration items (like the standard Applications or Groups lists, or the sublists or custom lists you build), the relevant Team must be assigned to the list.

    To check/update Team assignment, select the vertical dots icon beside the relevant list.

    Then select Edit list.

    Then select the check box to add to the list.

    You should now have visibility into the relevant lists when creating or editing the Request Type.

  • Enable Provisioning with OAuth for Salesforce.com

    A while back Okta changed the provisioning credentials for salesforce.com from the old username and password+token approach to using OAuth. Whilst the new approach was added to the Okta help documentation (https://help.okta.com/oie/en-us/Content/Topics/Provisioning/Salesforce/sfdc-configure-provisioning-REST.htm), the need for the documents to cover both the old and new can lead to some confusion. A customer hit a snag and I ran through the setup procedure in my own tenant.

    The following article covers the notes and screen shots from setting up provisioning to salesforce.com with OAuth. The comments should be used in concert with the product docs (not instead of).

    The relevant steps are in https://help.okta.com/en-us/Content/Topics/Provisioning/Salesforce/sfdc-configure-provisioning-REST.htm (and link to other pages). The steps referenced below are as per this documentation. First two steps are “Prerequisites” in https://help.okta.com/en-us/Content/Topics/Provisioning/Salesforce/sfdc-enable-provisioning.htm.

    Prerequisite Steps

    Step 1 – Create admin account in SFDC (normal system admin will work if you’re setting up a test or demonstration environment)

    Step 2 – Create custom user profile (SFDC – ADMINISTRATION > Users > Profiles) to setup a set of permissions for the account connecting to SFDC can perform. Note that if you are using the system admin account you will not need a custom user profile.

    Setup Connected App and Get OAuth Credentials

    Step 3 – Create connected app for the Okta connection.

    Step 4 – You might need to wait as directed (you won’t get a prompt) before,

    Step 5 – Go get the API Key and Secret

    We will come back to Step 6 at the end. For now, go to the steps under Configure OAuth and REST integration.

    Configure OAuth and REST Integration

    Step 1 – Go to the SFDC app provisioning page in Okta.

    Step 2 – Enable provisioning and Copy both Key and Secret values from the SFDC page into the relevant fields in the Okta SFDC app provisioning page.

    Step 3 – Click the Authenticate button (in my system it was Re-authenticate as I’d already had values).

    Step 4 – When prompted re-authenticate to SFDC as the admin account (there may be a MFA challenge with a PIN sent to the email address for the app).

    Step 5 – Approve the OAuth scopes

    Step 6 – You should see a success message and can Save the settings

    Check Refresh Token Policy

    This is the last step skipped above. Go back into SFDC and find the new connected app. I found the App Manager view easiest. Click the Manage function.

    Check the Refresh Token Policy.

    That should be it. You should be able to provision to SFDC from Okta.

    This concludes the article.

  • OIG Access Requests – Understanding User Grouping

    Understanding user grouping mechanisms in the Okta Identity Governance (OIG) Access Requests mechanism is important to building and running access request flows. It can be confusing and this article aims to address the confusion.

    Note that OIG Access Requests is the old atSpoke product. The term “Okta” in this article refers to the Okta Identity Cloud. The term “Access Requests” in this article refers to the tenant/instance providing the access requests and workflows functionality (this was atSpoke). Also a recent change in Access Requests was to replace the term “workflows” with “request types”. This article uses the term workflows.

    This article is looking at the groupings applied to objects within Access Requests, not the the admin access into Access Requests from Okta.

    Summary (TL/DR)

    There are four grouping mechanisms in OIG Access Requests:

    • Teams – these are within Access Requests and represent groups of users. They are defined in Access Requests and do not currently link to Okta groups. They can be used to define who can run a flow (requesters) and who can participate in steps in the flows (participants).
    • Okta Groups – these are groups that have been pushed from Okta into Access Requests. The mapping of users to these groups is done in Okta. They can be used to define who can run a flow (requesters).
    • Okta Resource Lists – Access Requests has lists that can be used for picking items in flows (e.g. list of apps or groups a user needs to be added to). There are two lists automatically pulled from Okta – a list of all Okta groups (“Groups”) and a list of all applications (“Applications”). The list items are the group (or application) names. These are controlled by the integration between Okta and Access Requests and cannot be changed by the administrators.
    • SubLists – The sublists of groups (or apps) are built from the existing Groups (or Applications) configuration items (“Okta resource lists”). An administrator controls the membership of the list. You have no visibility into the members of the groups, just the group names.

    The following table shows these groupings and which functions they apply to.

    Function All (AR) Users* (AR) Team Okta Group Resource Lists / Sublists Configuration Items**
    Workflow owner (“Team”)   YES    
    Workflow audience (who can run) YES YES YES  
    Task assigned-to (participant)   YES YES  
    Selection list in Questions       YES YES
    Actions – Assign Okta user to specific list item (group/app)       YES

    * – There is an “Everyone” category for the Audience (“Everyone in <instance>”). This is all users in Access Requests

    ** – Configuration items are also lists, but not group/app lists. They are static lists of items (strings) used for selection in flows and cannot be tied back to Okta objects. You cannot create a configuration item list of group names, for example, and have the flow use them to update groups in Okta.

    It should be possible to only use the (Access Request) teams for flow ownership and have everything else in a workflow based on objects in Okta. This would significantly simplify administration of users and groups.

    The groupings and functions are covered in detail in the remainder of the article.

    Defining/Configuring the Different User Grouping

    This section of the article looks at the different user group mechanisms and how they are defined and/or configured. The next section will look at how they are used.

    Teams

    Teams are local groups defined within Access Requests. They have no external connection (e.g. no link to Okta objects). They can have different icons and colours to differentiate them.

    Teams in Access Requests

    Teams are created/managed in the Access Requests UI, under the Teams menu item. Members are local users defined in Access Requests, but as there’s no way to locally create users, the user pool is the list of users sync’d from Okta (i.e. those in the group(s) or user(s) assigned to the Access Requests app in Okta).

    Any teams used for flows that will perform actions in Okta must be assigned to the Okta connection (in the Settings > Integrations page). This will be discussed in more detail below.

    Okta Groups

    Okta groups (with membership) can be pushed from Okta to Access Requests. They are defined as Push Groups in the Access Requests app in Okta.

    Okta Groups Pushed to Access Requests

    When the synchronisation runs, the push groups will appear in the Access Requests Okta Groups list in the configuration setting.

    Push Group in Access Requests

    These groups do not need to be assigned to the Okta connection in Access Requests.

    Okta Resource Lists

    Okta Resource lists consists of the Groups list, the Applications list and any sublists defined. They are defined in the Settings > Configuration section of the Access Requests admin UI.

    The Groups list contains an item for each group (group name) in Okta.

    A sublist can be created here, selecting items from either the Applications or Groups lists.

    Once you assign groups (or apps) to a sublist from a source list (Groups or Applications) the source list cannot be changed (i.e. before removing groups/apps in Okta you need to check to see if they are being used in sublists).

    Other Lists (Configuration Items)

    You can also create local lists of strings (like the Buildings in the following screenshot) to use as pulldown selection lists in flows. They aren’t user groupings in the context of this article, but are treated like other lists mentioned earlier.

    Now that we’ve looked at the different user groupings, let’s look at how they are used.

    Use of the Different User Groupings

    The user groupings can be used in the scope of a workflow (who owns and who runs it), selection lists and task participants.

    Scope of a Workflow

    When defining a workflow in Access Requests, you need to define two scopes, the Team it is assigned to and the Audience.

    Defining the Team and Audience for a Workflow

    The Team is the team of users that the workflow instance will be assigned to, i.e. who owns the flow. This comes from atSpoke’s more general ticketing mission. There can only be one team assigned and it must be an Access Request team – it cannot be an Okta group.

    The Audience is who the workflow is available to, i.e. who can see and run the flow. There are three options:

    1. Everyone in your Access Requests instance (i.e. everyone assigned to the app in Okta and sync’d to Access Requests)
    2. Members of the “Team” that owns the flow
    3. One of the Okta Groups you have pushed from Okta (see above).

    This is shown below.

    Audience Selection for a Workflow

    Note that there is a toggle under Audience to make the workflow visible to everyone, rather than limited to the selected group.

    Participants (Assigned To) in Steps in a Workflow

    All of the steps (Questions, Tasks and Actions) will need to be assigned to someone. Questions are normally assigned to the requester. Actions are normally assigned to the service performing the action, such as Okta for Okta actions.

    Tasks may need to be assigned to someone else, like a request assignee, requester’s manager of a specific user. From a group perspective a task might be assigned to any member of a Team or an Okta Group.

    Assigning Users to a Task

    Thus you have the option of managing participant lists (groups) in Access Requests (Teams) or Okta (Okta Groups).

    Selection Lists in Steps in a Workflow

    Some workflows will prompt users from a selection list. For example, selecting an application or group to get access to, or selecting a site they need access to. These lists are based on the Okta resource lists or Configuration items (lists) defined in the Settings.

    Using Configuration Items (Lists) in a Step

    In the example above, the user will be prompted to select a “Site” from a dropdown list. This list is populated from the Configuration item “Buildings”. But any Configuration item could be presented as a list, including the list of all Okta apps, groups or sublists you have defined in Access Requests (see above).

    Selecting item

    Some of the Actions available also present Configuration items for configuring the action (i.e. used in workflow configuration by an admin, not something presented to an end user at workflow execution). For example, you may need to specify an application or group to provision to a user, as shown below.

    Using Configuration Items

    This concludes the different functions where user groups are used.

    Conclusion

    This article has looked at the different user groupings (Access Requests Teams, Okta Groups and lists from Okta) and the different Access Requests workflows functions. The following table shows these groupings and which functions they apply to.

    Function All (AR) Users* (AR) Team Okta Group Resource Lists / Sublists Configuration Items
    Workflow owner (“Team”)   YES    
    Workflow audience (who can run) YES YES YES  
    Task assigned-to (participant)   YES YES  
    Selection list in Questions       YES YES
    Actions – Assign Okta user to specific list item (group/app)       YES

    • – There is an “Everyone” category for the Audience (“Everyone in <instance>”). This is all users in Access Requests

    It should be possible to only use the (Access Request) teams for flow ownership and have everything else tied to a workflow based on objects in Okta. Thus users and applications could be managed in groups in Okta and workflows would not need to be changed to accomodate user/app changes. This would significantly simplify administration of users and groups.

  • OIG Access Requests – Using the New Timer Feature

    This article explores the new Timer feature in Okta Identity Governance (OIG) Access Requests. It provides an overview of the new function and how it could be used for a long-term (days or weeks) access request and a short-term (hours) privileged access request.

    This article assumes a familiarity with the OIG Access Requests workflows. For more articles see Okta Identity Governance.

    At the time of publishing this article, the Timer feature is only available in preview environments, but will be in production with OIG General Availability (Aug timeframe).

    Overview of the new Timer feature

    This new feature allows an Access Request workflow to be paused for a period of time, or until a certain date.

    When accessing the workflow builder view, you will see a new button at the bottom, labeled “Timer

    New Timer function in Access Requests

    Clicking this will add a new Timer step to a workflow. It will pause the execution of a flow and then continue the flow after the timer ends.

    Timer step in workflow

    It can “End after duration“, i.e. pause for a set period of time (N days/hours/minutes). Or it can “End on date“, i.e. pause until a specific date (based on a previously selected date field). The former is great for fixed, short term breaks in a flow. The latter is better when you want the requester to specify a date from some activity. We will provide some examples later in this article.

    In addition to being able to add a timer to a workflow, some of the inbuilt actions have a timer function added with an “Add a time limit” option.

    Selecting this allows setting the same Timer settings (“End after duration” or “End on date”) as the Timer function above, and will add a Timer step to the flow.

    It will also automatically add the reversal action. If the action was “[Okta] Assign individual app“, then a new “[Okta] Remove individual from app” action is added. Both steps have the appropriate Logic added so they will only run based on previous steps.

    In the example above, the user will be assigned to an app, a timer will then run (when the assignment step is completed) and wait for a day, then when the timer ends, the access is automatically removed.

    This makes building automated time-bound access workflows very simple. Let’s look at two examples, a longer-term app assignment and a short-term privileged access assignment.

    Example 1 – A Date-Select Long-Term Assignment

    In this example, we want to allow users to request an access up to a specific date and have the access automatically revoked after that date. For this example, we have a carpark access app in Okta that users need to request.

    Most of the workflow is a fairly standard access request with approval flow. But an additional question is asked “Need Until“, which is a Date question.

    Need Until step using a Date Question

    With the Assign to App action, I have selected the Add a time limit and set it to the date selected by the requester.

    Access Request Workflow with Timer and Revoke steps

    When this flow runs, the requester will need to select the date they need access until.

    User initiates access request

    When the workflow is approved and the app is assigned in Okta, the timer will kick in.

    Timer running in workflow

    Once the Timer ends (at midnight 30 June) the app access will be automatically revoked.

    A variation on this would be to let someone else, like the reviewer, to set the end date.

    Manager Setting the End Date for Access

    Letting the user select and end date, and then having access automatically cleaned up, is a very effective way of managing access. As shown above, you could let the requester or another user (e.g. manager/reviewer, another team, application owner) set the end date.

    Note that you could also set a start date (timer between approval and Okta action) or both start and end date (two timers, one before the Okta provision action, and one before the de-provision action).

    Example 2 – A Fixed-Time Short-Term Assignment

    This example is for a fixed-time access set in the workflow itself. This approach lends itself to short term access that you want cleaned up automatically, such as privileged access. In this example we will use a request to access a set of Windows DBA accounts (that would be tied to the Okta Advanced Server Access AD-Joined feature, so the user can select which accounts they want to access a Windows server as).

    On the Assign step ([Okta] Add user to group) the Add a time limit option was selected and a 2 hour time was set.

    Add a time limit to Group Assignment

    This added two additional steps – the Timer to wait 2 hours, and a Revoke step to take the user back out of the DBA access group (using the [Okta] Remove user from a group action).

    Timer and Revoke steps in Workflow

    When the access is requested, and after the approval (Review) and group assignment (Assign) steps run, the Timer for two hours is triggered.

    Timer for 2 Hours

    Hovering over the message in the Tasks view shows the actual time of expiry.

    This group membership is automatically removed after two hours.

    Timer done and access revoked

    The actions are reflected in the Okta system log.

    System Log entries for workflow actions

    This is a basic example of implementing automated short-term access, such as for privileged access.

    Conclusion

    The new Timer feature in Okta Identity Governance Access Requests opens up new use cases, such as time-based automatic revocation of access granted.

    This article has described the new feature and shown two examples of this automatic revocation. The first is for a date-bound automatic revocation, where the requester (or another person) selects an end-date for an access and Access Requests will automatically remove the access on that date. The second shows a time-bound revocation where access is automatically revoked after a fixed time interval, which would be very useful in privileged access requests.

  • Historical Reporting of OIG Access Requests

    A common request asked is how to look at past access request events. Currently you can see the results of the requests in the Okta System Log and also in the Okta Identity Governance (OIG) Access Requests admin console. This article will explore these.

    This is still an early release product, so expect to see more logging and reporting in this area as the product develops.

    Overview

    Okta Identity Governance (OIG) Access Requests is an external system performing changes to data objects in Okta Identity Cloud (Okta) via APIs. This is the same as if ServiceNow or a custom program were making changes to Okta via APIs.

    OIG Access Requests Updates Okta via APIs

    Thus from a logging perspective, you will see the activity in the OIG Access Request component itself and in the Okta System log. These are discussed in the following sections.

    Events in the Okta System Log

    Change to users, group memberships and application assignments from OIG Access Requests are stored as events in the Okta System Log like any other events. They can be explored using the System Log menu item in the Okta Admin console or you could develop custom reports in Okta Workflows.

    You could also plumb the events out to a SIEM or reporting tool, as the Okta system log only stores events for a limited time. But we don’t cover that here.

    Native Events and Reporting

    All events from the OIG Access Requests component currently show as coming from one of two actors:

    • Okta AtSpoke Connector (PublicClientAppEntity) – for all user, group, application events, and
    • Okta AtSpoke Connector (PublicClientApp) – for OIDC access token messages

    Note, this actor name will likely change at General Availability. You can filter on this actor name to see all events from Access Requests.

    Access Requests Events in the Okta Syslog

    These events show the changes to the Okta objects, but not all of the detail of the request/approval flows in Access Requests.

    Reporting with Workflows

    I love Okta Workflows – it is our Swiss Army knife for any form of automation. It is reasonably straightforward to build some flows to extract OIG Access Request events from the system log. The [Okta] Search System Logs card with an Actor Display Name of “Okta AtSpoke Connector” (see note about about pre-GA name above) will return all Access Request events from the syslog. Note that you need to Grant the okta.logs.read scope in the Okta Workflows OAuth application for this card to work.

    Search System Logs Card

    We won’t go into the structure or processing of the event log objects here. But the Target(s) object list may contain an AppUser (application user), an AppInstance (application), a User, or a UserGroup (group). These objects often contain the identifier (like username) and display name.

    I built a set of flows to accomplish this:

    1. A master flow that reads the syslog events using the card above, and streaming them to a subflow
    2. A sub (helper) flow to extract the event type and description, target list and published date/time. It then uses another helper flow to find the four targets (AppUser, AppInstance, User or UserGroup) and extract the name and ID. These are written to the table.
    3. A sub (helper) flow to find the specific target in the list and extract the name and ID.

    The resulting table of processes events looks like the following.

    Syslog Events Extracted and Formatted into a Workflows Table

    This is just an example, but Workflows does give a lot of flexibility in processing the outcome. You could export the table to a CSV file, store it on a Google drive and notify relevant people via email.

    Viewing Requests in the Access Requests UI

    To see the detail of the access request flow, including approvals, fields, and interactions, you need to use the OIG Access Requests UI as an administrator. An administrator can see all requests and use the filter function to home in on specific requests.

    Viewing All Requests

    To see all requests (historical and current) you can select the All option under the Requests menu item. You can also see the flows assigned to different teams.

    Viewing All Requests

    Selecting one of the requests shows the full history of that request.

    Request Details

    Note that it’s also including the chat history of the request – so this is providing a complete history of what occurred.

    Filtering Requests

    There is a Filters function for the Requests view. It allows you to select multiple fields, and for each field you can select multiple values.

    Filter by Requester

    The selection above is showing all requests where the Requester = Seymour Skinner. This results in a filtered list of requests.

    Filtered View

    Similarly I could select a specific workflow to filter on.

    Filter by Workflow Name

    Resulting in a list of all requests for that workflow.

    Filtered View

    Depending on how you structure your flows, this may be showing requests for specific groups (roles) or applications.

    As mentioned earlier, you can stack up filters. For example, I could see all requests from a specific user for a specific resource.

    Hook into an ITSM Tool in a Flow

    OIG Access Requests provides integration with ITSM tools, such as ServiceNow and Jira. You can include an action in a flow to write all of the request details into a ticket.

    The following figure shows a ServiceNow ticket logged in a flow.

    ServiceNow Ticket Raised in a Flow

    Note that this is implemented at the flow level – you need to include it in every flow you want to log a ticket from. However this could feed into any reporting already used in the ITSM tool.

    More details on the ServiceNow integration can be found in Integrating ServiceNow with OIG Access Requests.

    Conclusion

    Being able to see what went on in a security product like OIG Access Requests is a necessary feature. This article has explored the different places access request history is stored and how to access it.

  • Designing OIG Access Requests for Ease of Use

    Access Requests are designed to be used by all people in an organisation. So making the interface and information presented be more user friendly should be a goal of any deployment. In this article we look at what information is presented to end-users by Okta Identity Governance (OIG) Access Requests and how you can use that to improve the usability.

    The article has three sections:

    1. It looks at the use of names and descriptions in the workflows to make identifying the right access request flow easier,
    2. It explores the information presented to end users and how it can be improved so users can understand what’s going on with a request, and
    3. It shows how encouraging the use of messaging (chat) can improve responsiveness and usability.

    Use of Icon, Name and Description in Access Request Workflows

    The first interaction a user will have with an Access Request is via the Request Access UI or via one of the chat mechanisms (Slack or Teams). Both use the name, but only the UI uses the description. Lets look at how these are configured and displayed.

    Name and Description in the Workflow Builder

    Access Request workflows offer three fields that can be used to describe the workflow; the Icon, the Name and the Description.

    Set Icon, Name and Description on a Workflow

    The Icon could be used to give a visual indication of the type or purpose of the workflow. However the set of icons is limited and not customisable.

    Workflow Icon Set

    The colour of the icon displayed is based on the colour of the team assigned to own the workflow. You can’t set it in the workflow. For the above reasons, I don’t find the icon that useful.

    The most useful fields are the Name and Description. The Name will show in all interfaces, whereas the Description will only show in some interfaces (see the following sections). The Name and Description showing in the Request Access UI is as follows:

    Name and Description in Request Access UI

    As can be seen, there is a limit on the display length of the description so it makes sense to be terse.

    Display in the Request Access User Interface

    The Request Access User Interface displays tiles for all access request workflows that the user is entitled to see (based on groups assigned to the workflows). The tiles show the icon, name and description of the flow.

    Having both the name and description makes this interface very useful for the end-user. If using this interface, you could keep the name short and put more detail/instructions in the description (allowing for limited space for the description in the tile).

    You should also consider if you will be exposing additional Access Request functions (functions other that just requesting access) and how to name and describe them.

    The example above shows a traditional access request, another built to hand back an access badge and one for a temporary suspension of all access for a user. The names and descriptions make this clear.

    Display in Slack

    The Slack app has four ways to initiate an Access Request workflow:

    1. By selecting from the pulldown list in the Home tab of the Access Requests app in Slack
    2. By typing a request directly into the Messages tab of the Access Requests app in Slack,
    3. By using the /access prompt in any channel, or
    4. By messaging the user associated with the app to request access in any channel,

    The latter three will use some NLP and AI to try to match the request to available workflows, and gives the user the option to select from a list (the first will just present a list of available workflows). These selection lists will only present the workflow Name, not the Description.

    Lists of Available Workflows in Slack via the Access Requests app

    If Slack is going to be the primary interface for requesting access there’s no value in adding Descriptions to workflows – focus on making the Names descriptive (or rely on the NLP/AI built in to learn what users are requesting).

    More information on requesting access via Slack can be found in OIG Access Requests – Requesting Access in Slack.

    Workflow Information Presented to End Users

    When a user submits a request, they are presented with the message trail from that request, with the various questions, tasks and activities in the workflow. This could be confusing for end users. Whilst much of the information presented is fixed, based on the task/action being performed, there is some flexibility in naming of steps and items used in steps. The information presented will depend on whether the Request Access UI or chat is used.

    Information Presented in Request Access UI

    If a request is initiated in the Request Access UI (or initiated in chat, but followed in the Request Access UI) there is an extensive amount of information displayed. For example:

    Flow Information in the Request Access UI

    The above shows the flow name, instructions for the requester, the questions answered, the approval steps and access provisioning step. Some of this information is generated by the actions and cannot be changed. However an administrator can set:

    • The flow name (e.g. “Carpark Access”)
    • The step names (e.g. “Manager Approval”, “Parking Mgr Approval”, “Provision”)
    • The question field names (e.g. “Justification” and “Site”)

    You should think about how you name the flow, steps and any fields you expect the user to provide responses for.

    Information Presented in Slack

    Whilst running a request in Slack or Teams will run the same flows as running a request from the Request Access UI, the information displayed will be different. This section looks at the information displayed in Slack.

    When the flow is started (access requested) any questions are displayed in a dialog box. The item labels are set in the flow.

    Questions Asked in Slack

    When the flow runs, the requester will see a summary of the flow, and can drill into the questions they just answered and the next step (tasks) and who it’s assigned to.

    Flow Initiation in Slack

    However when the flow completes, all of this request detail is removed from the Slack view.

    Flow Completion in Slack

    For a completed flow, the requester can click on the link (e.g. Badge Access #107) to be taken to the Request Access UI to see the full details of the request. They can also click on the replies link (e.g. 3 replies) to see some more information.

    Flow Completion in Slack Replies

    If Slack (or Teams) is the primary interface, there is value in thinking about the flow name, step names and question field name. However the information displayed in Slack is not a rich, particularly after the request is done, so it may be worth considering encouraging users to also use the Request Access UI to review any completed requests.

    Encouraging the Use of Messaging (Chat)

    One of the great usability benefits of OIG Access Requests is the ability to chat in real time between the requester and approvers or administrators. Rather than rely on a slow disjointed process (like sending emails), use of chat is far more effective. This is available via the Request Access UI and chat tools (Slack/Teams).

    Messaging via the Request Access UI

    There is a messaging function built into the flows and exposed in the Request Access UI. When a flow starts a response can be added. In the following, a manager (reviewing the access request) is asking for some more info.

    Manager Asking for Additional Information in Request Access UI

    The user will see these messages appear in their view and can enter responses.

    Requester Responds in Request Access UI

    The manager will see the responses in their view.

    Manager Sees Responses in Request Access UI

    This works best if the parties have the Request Access UI open.

    Messaging via Chat Tools

    Obviously chat tools like Slack and Teams are designed for realtime messaging. The access requests function leverages that. A flow similar to the above in Slack looks like the following.

    Manager Messaging in Slack

    The requester will see the messages in the app and also in a new thread.

    Requester Replies to Messages in Thread

    The manager sees these in the access requests app

    Responses inline in the Request

    The messages (irrespective of whether they were entered in the Request Access UI or via a chat tool) are stored with the request.

    Messaging Stored in the Request History

    Thus, use of messaging can be a very effective way of making the access request process for end users and lot simpler and faster. It should be encouraged.

    Conclusion

    Identity Governance is as much about people and process as it is about the technology. Users of IGA functions, like Access Requests, will be from across the organisation and represent the full spectrum of “IT-savviness”. You need to consider how to make your Access Requests implementation more consumable by the entire user population. This article has explored a number of ways to make the Okta Identity Governance Access Requests more usable, including use of names and descriptions, step names and field labels, and use of messaging to improve responsiveness. Hopefully this will help guide you in your deployment of OIG.

  • OIG Access Requests – Requesting Access in Slack

    A key benefit of Okta Identity Governance is the ability to interface with access request flows via chat tools such as Slack and Microsoft Teams. This article provides a summary of the different ways users can request access in Slack and how to monitor the progress of a request in Slack.

    Overview of OIG Access Requests and Slack

    Okta Identity Governance Access Requests provides the ability to build and execute access request workflows. There are multiple ways that users can interact with these workflows, including using the Request Access UI or a chat tool like Slack and Microsoft Teams. Both Slack and Teams run apps that provide this access and interact with the OIG Access Requests workflow engine. This is shown in the figure below.

    OIG Architectural Overview with the Chat Interfaces highlighted

    When using the Slack access request app, there are multiple ways you can initiate an access request flow. Once a workflow has been initiated you normally monitor its progress in the Messages tab of the app. These are covered in the following sections. Of course, living in Slack (or Teams) means that requesters and reviewers can message directly to improve the responsiveness of requesting access.

    Requesting Access via Slack

    There are four ways to initiate an access request flow in Slack:

    1. Selecting the flow in the Home tab of the App
    2. Messaging the app in the Messages tab of the App
    3. Using the /access command in any channel
    4. Messaging the App user in any channel

    These are shown in the following sections.

    Selecting an Access Request Flow from the App List

    The Okta access requests app appears in the Apps list in Slack. In my example it has been renamed to okta_accessrequests, but it may be named something like okta or oktapreview. When selecting the app, the Home tab provides a pulldown list of access request workflows.

    Selecting an Access Request Flow in the App

    The user selects from the list to start the access request workflow. If there are questions to be answered, a dialog is presented in Slack for the requester to supply information.

    Questions Dialog for the Flow in Slack

    When the user Submits the request, Access Requests will continue the workflow. The progress and final result will be displayed in the Messages view (see below).

    Messaging the App Directly

    The second way is to use the chat function to message the app directly in the Messages tab of the app.

    Messaging the App Directly

    The access requests app will use its AI to try to match the access request flow and offer the best match or prompt you to select from the list.

    Access Request flow not found

    Selecting a Flow from the List

    Once selected, it will present a dialog as shown above, and continue the flow.

    Use of the /access Command in Any Channel

    You can call the app from any channel by using the /access command.

    Details of the /access command in Slack

    Using the /access Command

    Results of the /access Command

    From here the access request is processed as above.

    Message to the App User from any Channel

    The last way to initiate an access request flow is to message the app user from any channel. As you type @ and the app name, Slack will find the matching user.

    Searching for the App User in Slack

    Click to complete the name and enter the access you want.

    Requesting Access via the App User

    It will find the access request workflow (or not) as above.

    Initiating the Access Request Flow

    Then the flow proceeds.

    This concludes the four ways to initiate an access request flow in Slack. The next section looks at how you can monitor a submitted flow.

    Monitoring the Access Request in Slack

    Once the request has been submitted by one of the means above, you can monitor its progress in the Messages tab of the app (and you will see visual notification of updates if you’re in other Slack channels). When the request is first submitted, there is an update to say it’s submitted.

    Messages After a Request is Submitted

    When it has been through the various flow steps (like approvals and provisioning) the view is updated to show the completion status.

    Messages After a Request is Completed

    You can click on the link (e.g. I need carpark access #117) to be taken to the Request Access UI to see all details. A summary can be found in the Replies (click on the view thread link).

    Message Thread in Slack on Completion

    Conclusion

    Using a chat tool like Slack to request access is a great for end users – it provides the function where they work, rather than needing to go off to another website. Okta Identity Governance provides apps to initiate and monitor Access Request flows. This article has shown the four different ways users can use the Slack app to request access and how to monitor their access request.

  • Integrating ServiceNow with OIG Access Requests

    One of the standard integration points with Okta Identity Governance (OIG) Access Requests is to log a ticket of an access request in an ITSM tool like ServiceNow. This article explores the integration between OIG Access Requests and ServiceNow.

    Overview of Integration

    The primary focus of the Okta Identity Governance (OIG) Access Requests function is to present workflows for users to request access, and optionally have some review/approval mechanism, before applying access changes to entitlements in Okta (such as group memberships or application assignments). It can also integrate with ITSM/ticketing tools, like ServiceNow and Jira, to log tickets. This is shown in the following figure.

    Okta Identity Governance Architectural Overview with ITSM Integration

    Why would you need to integrate with a ticketing system if OIG Access Requests is providing the service catalog and access request workflows (that could also be done in a tool like ServiceNow)? You probably wouldn’t. If you are already using ServiceNow to expose an access catalog and have access request flows, you’re probably not going to also use OIG Access Requests for the same function.

    But there are use cases where it makes sense to log a ticket on the back of an OIG Access Request flow, such as when all change must be logged in the ticketing tool for audit or reporting purposes. OIG Access Requests has integration with Jira and ServiceNow for that use case. The remainder of this article will look at the ServiceNow integration.

    ServiceNow Integration Setup

    OIG Access Requests has four integrations currently: Slack, Jira and ServiceNow, and Okta itself (Microsoft Teams is planned to be available at GA). Each is configured in the Settings page in the Access Request interface.

    Integrations in OIG Access Requests

    The first time you click the Connect button for ServiceNow you are prompted to enter the ServiceNow Instance ID, Client ID and Client Secret. The OIG product documentation describes how to setup for OAuth and get the Client ID and Secret.

    With the connection established, you need to assign Teams and the Actions (one only in this case) for the connection. This is the same as you would have done for the Okta connection.

    Selecting Teams for ServiceNow Integration

    With this done, you’re ready to add the ServiceNow Create request action to a flow.

    Adding ServiceNow Ticket Creation to a Flow

    For this example, I’m going to add a ServiceNow action to an existing workflow. At the bottom of the workflow builder screen, there are new actions available as shown below.

    Adding the ServiceNow Action into the Flow

    Selecting ServiceNow > Create request will add the [ServiceNow] Create request action to the flow.

    There are two arguments (fields) for this action, Requested for (who the ticket is being logged for) and Assignment group (group in ServiceNow who will own the ticket).

    The assignment groups were pulled from the ServiceNow instance when the connection was made and stored in a Configuration item list called Assignment groups. The appropriate group is selected and assigned to the Assignment group field.

    Specifying the Assignment Group in Action

    Note that this means that if you want to assign the ticket to different teams, you may need different workflows, or a workflow with appropriate Logic to call different actions with different Assignment groups.

    The configured action is shown below.

    ServiceNow Action Configured

    Finally, some logic is added so it will only run if the request was approved by the manager and the Okta provisioning step completed.

    Logic Applied to Step in Flow

    This flow is now ready to run.

    Executing the Flow

    The workflow appears in the relevant users App Catalog.

    User Selects the Access Request

    The flow runs, with approval and provisioning steps, then runs the Log Ticket in SNow step. You can see the request number in the flow results (which is a link to the ticket in ServiceNow).

    Completed Flow in Access Requests

    Checking ServiceNow, the new request has appeared in the Requests list.

    Ticket List in ServiceNow

    Within the request, we can see the Requested for field is populated (this is the Requested for field in the Access Requests action). The Description field contains all of the information from the request flow in Access Requests. The Short description is the name of the workflow in Access Requests.

    New Ticket in ServiceNow

    Thus was have created a ticket in ServiceNow from the request flow in Access Requests.

    Conclusion

    Okta Identity Governance Access Requests has the ability to log tickets in ITSM tools like ServiceNow and Jira. This article has shown how to configure the integration and how to add an action to create a ServiceNow ticket within an access request workflow.

  • OIG Access Requests – What Else Can You Do?

    The Okta Identity Governance (OIG) Access Requests module is built for requesting (and reviewing/approving) access to applications or groups in Okta. However, the module can do a lot more with the actions provided for the Okta integration. This article explores these and gives some examples of how they can be used.

    Please note that an earlier version of this article included Okta actions that have been removed.

    Okta Actions Available In Access Requests

    The Okta integration with OIG Access Requests provides a number of actions (using Okta API calls) into Okta. The standard actions used for requesting access are Assign individual app to user and Add user to a group. These will be the latter part of an access request workflow where the user has initiated the request, supplied some information (like a justification) and some form of approval has run.

    But there are more actions available to interact with Okta.

    In addition to adding a user to an entitlement (group or app), you can also run a flow to remove the user from an entitlement (Remove user from a group and Remove user from app). These may be combined with a Timer (another new features) to provide time-bound access.

    There are some actions that will query information in Okta and display the results in the request history: List groups assigned to user, List groups assigned to app, and List apps assigned to user.

    We will look at some examples in the following sections.

    Example – List All My Apps

    As a user, you can see the applications you’re assigned to in the Okta Dashboard, so the following example may not be that useful. But the approach applies for all four of the “[Okta] List ***” actions and shows how you can use the actions.

    The actions have been written with privacy in mind, so that the results of the action (i.e. the requested list) will only be shown to the workflow owner (assignee, such as the IT admin administering the processes). So, they will need to copy the results to the chat/flow to make the results available to the requester.

    Let’s start with a simple flow. It has a single action to run the [Okta] List apps assigned to user action.

    List My Apps action

    When the flow is executed, it runs the Okta action to retrieve the data. The following is what the requester sees.

    Flow getting the list of applications from Okta

    The action returns the list of applications to the flow, visible to the flow owner. The following is what the assignee (owner of the flow) sees.

    Copying result of action into the flow response

    The flow owner can copy the resulting text (the list of apps) into a message for the flow so it is visible to the requester. The following is the view for the requester.

    Result visible to the requester.

    This example shows how this information can be presented back to the user. Obviously this is just the beginning with these actions – there is a lot of scope to expand on use of the returned data in Access Request workflows, such as providing context to a reviewer before approving an access request or providing a personalised list.

    Example – Remove Me From an Application

    An ask I had recently from a customer was for users to be able to request removal of an application via self-service. We can easily do this with Access Requests using the [Okta] Remove user from app action (or the [Okta] Remove user from a group action for group/role membership). The following is a simple flow for removing a specific app selected by the requester.

    The [Okta] Remove user from app action requires an application to be specified. In this example, it’s the application selected from the Application dropdown list.

    Requesting App removal

    The flow will run and automatically remove the user from the selected app.

    Flow for Remove App Access

    The result is shown in the Okta System Log.

    System Log showing app removal

    This is a trivial example to show the basic mechanics.

    Conclusion

    In addition to the access request actions for group membership and application assignment, there are a number of other actions available from OIG Access Requests into Okta, such as listing entitlement information. This article has explored these and has shown two examples of using these additional Okta actions.

  • Requesting Roles Through OIG Access Requests

    This article looks at how Okta Identity Governance (OIG) can be used to provide a role-request feature in Access Requests. The example used is roles for Salesforce.

    Role Request for Salesforce

    What Roles?

    If you’re familiar with the Okta Identity Cloud data model, you will know there are users, groups and applications but no roles (other than roles to administer Okta itself). But groups can be used to “group” users for different functions, such as applying authentication policy and application entitlements. Many customer deployments treat groups as roles for the latter – groups assigning users to applications may be tied to a job function.

    In addition to this coarse-grained assignment, many applications in Okta support fine-grained entitlements. For example when looking at Salesforce.com, users or groups can be assigned to specific SFDC roles and licenses. It makes sense (even “best practice”) to assign groups to these applications and set these fine-grained entitlements at the group level, and then manage user membership to the groups rather than assigning individuals to applications. This strengthens the model of groups as roles – providing both coarse- and fine-grained entitlements. See http://davidedwardsphotos.com/iamdavid/2022/03/22/fine-grained-entitlement-reporting-with-workflows/ for more discussion on managing fine-grained entitlements in Okta.

    The following figure shows the relationships discussed above.

    An Example – Salesforce.com and Some Role Groups

    Let’s look at an example of this. I’ve created four groups in Okta to represent roles against Salesforce.com.

    Role Groups in Okta

    These are assigned to the Salesforce.com application.

    Role Groups assigned to Salesforce.com

    If you drill into the group-level assignments you see that a specific Salesforce.com role has been assigned to the Okta group.

    Role Group assignment to Salesforce.com Role

    Thus the Okta groups represent roles, and also assign a fine-grained permission (in this case a role) in Salesforce.com.

    How do we expose these to be requested in Okta Identity Governance (OIG) Access Requests? Let’s have a look at two ways – a group request and a label-based request. Note that the approaches shown below are based on the current Limited Early Access code and features may be added to OIG Access Requests in the future that may mean different approaches can be used.

    Requesting The Role Groups Directly

    A key driver for Access Requests is to keep it as simple as possible for end users. If you have a simple and well-understood naming standard applied to your groups, you could just expose them in an Access Request flow as they are.

    We will use the groups and group assigments above.

    Using Configuration Items for a List of Groups

    The first thing needed is a Configuration item with the groups you want to expose.

    Configuration Items (for SFDC)

    This list contains the four groups.

    Groups in Configuration Item

    Access Request Flow For The Group List

    Next we can build a workflow to assign the user to the role. It will prompt for the group and a justification, get manager approval and then assign the user to the group.

    The following figure shows the entire workflow – we will drill into the detail of each step below.

    Actions to Add User to Group

    The first step, Role, is a simple Dropdown question using the Configuration Item from above.

    Role Selection (Question) step

    It’s important that the Role is a required field as the flow will fail if nothing is selected. The Dropdown is assigned to the Configuration item SFDC-Role-Groups from above. The logic assumes a single role is selected (there is no logic in the example flow to support multiple selections).

    The Justification and Manager Approval steps are straightforward.

    The last steps (Assign User to XYZ) are basically a case statement, with a single step for each role group that could be chosen in the Role question. Let’s look at one of them (they are all the same)

    This step uses the standard [Okta] Add user to group action. When enabling the Run automatically checkbox, the required fields (email and group) are exposed. The email address is that of the requester (the user to be assigned to the group). To get the group, we need to select 1. A configuration list item, then 2. the Groups object (the full list of Okta groups), and finally 3. the actual group to be assigned.

    The image above shows the logic applied to the step. It will only run if the Manager has approved the request and the role selected by the user matches the group name for this step.

    Logic for Step

    As the second condition is based on the role value from the question, and that is tied to the Configuration item with the list of groups, so you can only select a value from that Configuration list for this condition.

    Running the Access Request Workflow

    Let’s see this in action. The user initiates the Access Request workflow.

    User Selects a Role Group

    There request flows and is approved.

    Worklflow Runs

    The user is added to the group in Okta.

    User in SFDC Group in Okta

    This proves the workflow works as intended.

    Requesting The Role Groups via a Label

    The previous example shows the user being presented a list of role groups, where the group names follow a standard making them easily understood. But what if the Okta group names assigned to the application don’t make sense to the end user? You can use the same approach, but instead of presenting a list of group names, you can present a list of labels.

    I will summarise below, rather than going into the detail as above.

    Configuration Item for Role Labels

    For this example, I have duplicated the above Configuration item and changed the group names to labels.

    Configuration Item List for Role Labels

    This will be used in the Access Request workflow.

    Access Request Workflow for the Role Label List

    The flow is basically the same as the previous one, except using in the new SFDC-Role-Labels Configuration Item list, and different Logic for the conditional steps.

    Access Request Workflow for Role Labels

    The Role dropdown question is using the new Configuration item – SFDC-Role-Labels, and the conditional logic in the Assign to XYZ steps check for each of the SFDC-Role-Labels values.

    Running the Access Request Workflow

    The end user experience is fundamentally the same but they see a list of role labels.

    Selecting Roles in Access Request

    The rest of the workflow proceeds as above.

    Conclusion

    This article has discussed how Okta groups can represent roles, and be used for both coarse-grained (application-level) and fine-grained (application attribute-level) entitlement assignment. It has shown two examples of using OIG Access Request Configuration item lists and workflows with conditional logic to present lists of roles (by group name or role label) and have the right role be assigned to the user.

  • Inactive Application Account Reporting with Okta Workflows

    I was recently asked about reporting, and possibly recertification, of inactive accounts in Okta. We can run reports in Okta on Okta profile states to find inactive users. We also have an Okta Workflows template to find and report on Okta users who haven’t accessed Okta in a period of time.

    But what about application account access? There is no out-of-the-box reporting. But, as always, our Swiss Army Knife Okta Workflows can be used to report on users who haven’t accessed applications via the Okta Dashboard in a period of time. The following article explores how this was implemented.

    Overview of the Scenario

    With Okta access itself, Okta stores the last login timestamp on the user profile, so it can be easily accessed. But with the application access, the only place the last login information is stored is in the Okta System Log against a User single sign on to app event. So we need to search the system logs. This can be a resource intensive operation if done badly, so the flows were designed to minimise the number of searches of the system log and leverage objects and a Workflows table for more efficient processing.

    The flows in the solution are shown below:

    Inactive Account Flows

    There are two parts to the solution:

    1. A set of flows will perform a single search of all SSO authentication events in the system log over a given period (say 30days before today). The results are streamed to a subflow that will process each event and store them in a Workflows table for logins. This could be run daily as a middle-of-the-night batch job.
    2. A flow for each application that you want to identify inactive accounts. The main flow will identify each user in that application, then a subflow will check each user against the logins table and if there are no entries found, that user is stored in an application-specific inactive account table. Once all users have been processed and all inactive accounts stored in the table, another sub-flow will export the table to a google drive, add an application owner to the file on the drive and send an email about the report.

    The solution includes some common re-usable components. For example, some of the variables used are stored in a separate table (rather than coding them into the flows) and a standard subflow is used to retrieve them.

    The remainder of this article will detail the flows.

    Part 1 – Find and Store All Login Events for a Period

    The first part of the solution involves finding all login events for a given period (such as 30 days) and storing them in a table. Note that Okta only stores events in the System Log for about 90 days. You may also have a large volume of login events that may take time to extract and store.

    There are two flows and table used (as well as some utility flows).

    The main flow is M30 – Get All App Logins for Period. It uses M31 – Process Individual SSO for each returned event. All login events are stored in a table T3 – All Recent Logins. These are explored in the next sections.

    Main Flow to Get All Login Events

    The flow is as shown below:

    There are four steps in the flow:

    1. Empty out the table that will store the login events
    2. Get the current date/time
    3. Take 30 days off the current date/time to provide the start window for logins (i.e. if an account hasn’t logged in during the past 30 days, we will consider it inactive)
    4. Search the Okta System Log for app login events and process each.

    The first three cards are trivial, but the last requires some explanation. There is an [Okta] Search System Logs action for the Okta connector. There are multiple way you can configure a search – in this case we are specifying three arguments (Event Type, and Since and Until dates). The Event Type is hardcoded to the user.authentication.sso event type. The dates use the today-30 and today dates from the earlier date cards.

    As with many of the search cards, you can return a single record, a set of records up to a maximum (200 in this case) or stream the results. Given the volume of login events possible, we are streaming the results and passing each one to a second (helper) flow to write them to the table.

    Sub Flow to Process Each Login Event

    This helper flow is run for each event returned from the search.

    There are three stages to this flow:

    1. The flow is initiated for each login event and that event is passed as an object into the flow
    2. The next four cards will extract the user (actor), target system and login date/time from that object. As the event object is complex, there are multiple cards to extract different attributes.
    3. The last card will write a record to the table

    Even though the main flow may be extracting thousands of events, many of the sub flows will run in parallel to write events to the table to reduce overall processing time.

    All Recent Logins Table

    This table will store all recent login events (i.e. over the last 30 days).

    It’s storing six attributes from each login event:

    • ActorId – the Okta ID for the user profile
    • ActorName – the fullname (display name) of the user
    • ActorEmail – the email address of the user
    • Target1Id – the Okta ID for the application being SSOd to
    • Target1Name – the display name of the application
    • LoginDateTime – the event datetime

    There will be an event for every login, so there could be duplicates (different datetime) for a user accessing a specific application. We only really need to know if a user has logged into a specific application during this period, not every login. So the M31 flow (above) could have some smarts included to check if there is already a user-application event there before writing on. This would significantly reduce the amount of events in the table.

    The application-specific processing (next section) will leverage the contents of this table.

    Part 2 – Find Inactive Accounts for an Application and Report on Them

    In the second part of the solution we leverage the login table from above to check whether users belonging to an application have logged in over the period (30 days in this case). The following example is for one application, but could easily be duplicated for other applications (the application id, inactive user table and app owner email are parameterised, so the main flows can easily be replicated to use the different parameters).

    There are three main flows:

    The M40 – Get O365 Users and Check Login flow will find all users assigned to the Office365 application and pass them to the next flow (U00 – Check User in Login Table) for checking if the individual user logged in and if not write them to an inactive users table for the app. Then the last flow (U10 – Send Report via Email) will export that App Inactive Users table and distribute it to the application owner.

    These are explored in the following sections.

    Main Flow to Get Users Assigned to the Application

    This flow would be run as required or on a schedule.

    The first few cards will get the App Inactive Users table id (parameter stored in another table), clear that table, get the application id (another parameter) and use the [Okta] List Users Assigned to Application card to find all application users.

    For each user assigned to the app, it will use a subflow (U00) to check if they have logged in and if not, write them to the App Inactive Users table. When all users are processed, it uses another subflow (U10) to distribute the App Inactive Users table as a report via email.

    Sub Flow to Check if a User Has Logged In

    With the list of users assigned to the app, we need to check if they’ve logged in over the last period (30 days). This helper flow is called for each user assigned to the application.

    The flow has the following steps:

    1. The user object is passed into the flow
    2. Some of the user attributes are extracted from the user object
    3. The All Recent Logins table is searched for this user and application. The card has a set of where clauses that result in the where expression ‘”ActorId” = System Properties.User ID AND “TargetId” = appid‘ (the userid comes from the Get Multiple card from the user object and the appid is passed in to this flow from the calling flow).
    4. The length of the resulting list (i.e. number of matched login events) is calculated
    5. If the length (i.e. number of matching records) is >0 then the flow exits (the user has logged in during the last 30 days)
    6. Otherwise, this user is written to the App Inactive Users table

    This sub flow will progressively fill the App Inactive Users table.

    Sub Flow to Send the Report via Email

    The last flow that is called is a flow to download the App Inactive Users table, store it as a CSV on a Google drive, assign ownership to the application owner, and email them with details. This is a common flow I use across many reporting workflows.

    The first card is the Child Flow card which defines the parameters being passed to the flow. In this case it includes the recipient email, tableId for the table to export, and some report definitions.

    The two time cards will get the current date and time and covert it into a format to use in the filename. The report filename is built up of a prefix passed to the flow and the datetime.

    The next card exports the Workflows table to a CSV file (using the filename set in the previous card). The Compose card creates a string for the file description. The [Google Drive] Upload File card uploads the file, with description, to Google drive (based on the connector settings).

    The next Compose card will format a permission message. The [Google Drive] Create Permission card assigns the new file to the email address of the recipient (this will result in an email being sent to the recipient), like the one below.

    The next Compose card creates a HTML-formatted email body. Finally the [Office 365 Mail] Send Email card will send a second email to the recipient with more information. For example:

    Thus we have report delivery for action by the application owner.

    Application Inactive Users Table

    The App Inactive Users Table is a simple list of users who haven’t logged into the application in the given period.

    This is what is distributed to the application owner as a CSV file.

    Conclusion

    In this article I have shown how Okta Workflows can be used to produce inactive user reports. There is an out-of-the-box template for Okta users accessing Okta. But to produce a report on application access requires searching the Okta System Log. Whilst there are multiple ways to access the log, you need to consider performance and this example has shown one way to do so.

  • Managing Multiple AD Users in the AD-Joined Feature of ASA

    Okta recently released the AD-Joined feature for Okta Advanced Server Access. This feature extends ASA secured RDP access to Windows servers in an AD domain, leveraging user credentials also stored in Active Directory. The feature supports both traditional password-based access and passwordless access using AD certificates, with the flexibility of having a mix of both as needed. This article provides an overview of the mechanics of the new feature and how you can configure Okta to manage AD accounts in ASA.

    An Overview of the AD-Joined Feature

    Traditional ASA server connect flows with SSH and RDP to local servers involves an ASA client on the users workstation, leveraging the ASA and Okta cloud services for authentication and authorization, and an ASA server agent on the target servers (steps 1 – 4 in the following diagram). Traffic may be routed via ASA bastions and/or gateways. It relies on having that Server Agent deployed onto the target servers (and enrolled against projects) providing user/group management, certificate signing authority management and SSH daemon functionality on Windows.

    However this approach will not work in a Windows Active Directory environment, where users are managed centrally, and Windows servers come and go in AD. To support AD-Joined servers, the ASA gateway was enhanced to work with AD domain controllers in multiple ways as shown in the following figure.

    Components and Flows for AD-Joined

    First, as the servers in the domain change, we need to be able to maintain the server list in the projects. This is done through a discovery process tied to specific AD connections (step 0).

    Second, rather than deploying the ASA server agent onto each Windows server in the domain, the user connects (transparently) to the gateway. The gateway will perform user authentication (step 5) and the RDP to the individual Windows server (step 6).

    The user authentication to AD from the gateway supports multiple AD accounts associated with each Okta user, and each AD account could be authenticated with a password to AD or in a passwordless mode (with certificate-based authentication to AD). The remainder of this article will explore how we map the AD accounts to the user and how it flows down to ASA.

    Exploring the Mapping of AD Accounts in Okta and ASA

    To support the AD-Joined mechanism, two new attributes have been added to the ASA user schema in ASA: activeDirectoryIdentity and activeDirectoryPasswordlessIdentity. Both are string array values. They represent a set of AD accounts that can be used for a user in password or passwordless modes.

    ASA is an application in Okta with provisioning enabled, leveraging SCIM to provision user (and group) changes to ASA.

    Within Okta (Universal Directory) the ASA users are represented in the ASA (application) user profile. Both attributes can be mapped to Okta user profile attributes using standard profile attribute mapping. You could have both ASA attributes mapped to a single Okta string array attribute (i.e. the user could access each AD account with or without a password). Or you could have different Okta profile attributes to represent different sets of AD accounts (some requiting password access and some using passswordless). This is a design decision on your part.

    The final piece of the puzzle is where these AD accounts are coming from to populate the Okta profile attributes. One source is directly from AD, where the AD agent will provide AD accounts that can be mapped to one of these attributes. This makes sense when the Okta user is AD-mastered. The AD userName attribute is multi-valued so if there are multiple accounts for a user in AD, they can all be populated into the Okta profile attribute.

    There may be other AD accounts you want to associate with an Okta user. For example, perhaps you have some privileged accounts (like DBA shared accounts) that you want to allow users to request for a period of time. These could be tied to some access request (like in Okta Identity Governance) or other external process to assign them, then API calls or Okta workflows could apply the accounts to this Okta profile attributes.

    The following figure shows an example of how this mapping could occur.

    Attribute Mapping for AD Accounts into ASA

    In the diagram, the normal user AD accounts are imported via the AD agent and stored in the AD profile userName attribute. Profile attribute mapping will apply this set of values into a custom Okta profile attribute (asa_ad_accounts_passwordless) which is a string array. The profile attribute mapping will apply this attribute to the ASA profile attribute (activeDirectoryPasswordlessIdentity) and any profile change will trigger the provisioning to ASA.

    There are also a set of AD DBA accounts that can be requested. The mechanism isn’t important, but there is a Workflow flow to add/remove the three AD DBA accounts into a custom Okta profile attribute (asa_ad_accounts) which is a string array. The profile attribute mapping will apply this attribute to the ASA profile attribute (activeDirectoryIdentity) and any profile change will trigger the provisioning to ASA.

    Thus in this example, the end user will see their primary AD account(s) and three DBA accounts (if they have requested them) when they RDP. For example:

    ASA RDP Presenting A Selection of AD Accounts to Use

    The rest of this article will look at how it’s implemented.

    Implementing the Data Mapping

    The AD-Joined documentation (https://help.okta.com/asa/en-us/Content/Topics/Adv_Server_Access/docs/ad-user-manage.htm) covers how to implement the mapping. The following shows an example of implementing the above scenario.

    AD Profile Attribute

    We are using a standard (Base) attribute of userName (userPrincipalName) that will be imported into the AD profiles from the AD Agent.

    AD Profile Attributes

    An example is shown below.

    Example of AD userName

    Okta Profile Attributes

    In the Okta profile I added to new custom attributes, both string arrays.

    New Okta Profile Attributes for ASA AD Accounts

    They are standard string arrays on the profile.

    Detail of One of the Attributes

    An example is shown below.

    Example of Okta ASA AD Attributes

    ASA Profile Attributes

    Two new attributes have been added to the ASA schema. For existing Okta+ASA deployments they need be added. For newer deployments they should be there.

    New ASA Profile Attributes

    An example of this is shown below.

    Example of ASA Profile Attributes

    AD to Okta Profile Attribute Mapping

    In this example, we are mapping the AD userName attribute to the Okta passwordless attribute, and nothing is mapped to the other attribute, as shown below.

    Mapping from AD Profile to Okta Profile

    The other attribute, in this example is being managed by two Workflows tied to a dummy application (request access to dummy app triggers flow to update the password attribute, asa_ad_accounts, with a set of AD DBA accounts).

    Okta to ASA Profile Attribute Mapping

    The Okta to ASA Profile attribute mapping in this example has a 1:1 mapping from the two attributes in Okta to the corresponding attributes in ASA.

    Mapping from the Okta Profile to ASA Profile

    The end result of this can be viewed in the ASA administration console.

    View of Okta-provisioned AD Account Attributes

    With these attributes populated, the user can access the accounts when RDP’ing.

    ASA RDP Presenting A Selection of AD Accounts to Use

    This completes this article.

  • Separation of Duties (SoD) With Okta Workflows

    Implementation of Separation of Duties controls is often an Identity Governance requirement. Whilst SoD controls will find their way into the Okta Identity Governance product at some point, they can be implemented today using the Okta Identity Cloud data model and Okta Workflows. This article provides a sample implementation.

    Note that there is a later post on this site with an improved SoD mechanism based off calling Workflows from an Access Request. See OIG Checking SoD in an Access Request. Okta has also introduced it’s own SoD feature.

    Introduction

    A common requirement for Identity Governance is for Separation of Duties (aka Segregation of Duties, or just SoD) controls. SoD controls are intended to stop overlaying IT access that would allow compromising activities. The classic example is you wouldn’t want someone to be able to both raise a purchase order and also approve the same purchase order.

    SoD controls may be based on user groups, roles, jobroles, business activities or other identity objects that can represent a set of IT accesses. Often these need to be fine-grained accesses tied to application functions (think purchase order create and purchase order approve – both are likely functions or transactions within the one application). The definition of these roles may come from audit findings or local analysis, and defining them and the policies may be a considerable exercise (the cost of the consulting can outweigh the cost of the product to implement the controls).

    Controls may be proactive or reactive. It is common to implement a mechanism to check for SoD policy violations whilst access is being assigned, but also to run periodic SoD violation reporting. The example here is looking at the former – detecting violations during the access request process.

    Okta and Coarse- and Fine-Grained Entitlements with Groups

    The standard Okta Identity Cloud data model concerns users, groups and applications. Users can be members of multiple groups. Users and groups can be assigned to applications (although group assignment is considered best practice). Depending on the application, the user or group assignment can also set application profile attributes, such as a role, profile or permission sets. So users in Group A may inherit a specific application role, and users in Group B may inherit a different application role.

    Thus groups in Okta could represent sets of access. From the coarse-grained perspective a group represents a set of applications and may be granular enough for SoD policies. However group assignments, where assignment applications represent access, may also provide the granularity needed for SoD policies.

    Let’s use the Salesforce application as an example. The Salesforce.com (SFDC) application profile contains a number of access attributes that could be associated with group assignments, such as profile, role, permission sets and feature licenses. In this example we have defined four groups that are assigned to SFDC and represent a specific SFDC role, as shown below.

    Within each group assignment, a specific role has been selected.

    Thus anyone in the DO.SFDC.Role.Channel-Sales group will be assigned to the Channel Sales Team role automatically in SFDC. The other three groups shown are assigned to the corresponding roles in SFDC. This means each group represents a fine-grained permission in the application. We will use these groups in the example below.

    This model relies on the applications exposing that fine-grained access information and the integration with Okta consuming it and making it available for group assignment.

    Implementing an Example

    This section will explore the implementation of the example, with an overview, the mechanics in the different Okta components and finally what it looks like.

    Overview

    The basic premise in this example is that there are some SoD policies based on groups (representing fine-grained application permissions) and that adding a user to one of these groups may trigger a SoD policy violation.

    The components and flow are summarised in the following figure.

    The flow is initiated by a user being added to a group (1.) in Okta Identity Cloud (Okta). This could be from an administrator assigning the user to the group, an API call, a user Access Request in Okta Identity Governance or any other mechanism.

    The “user assigned to group” event in Okta will trigger a flow in Okta Workflows (2.). The flow will get the details of the user and new group, check if the group is subject to any SoD policies and if so evaluate the policies.

    It may be that the group change does not violate any policies. If it does, the policies are checked for enforcement. If enforcement is flagged, the flow will back out the group assignment (i.e. remove the user from the new group) (3.). The details of the violation are emailed to the user and their manager, and a summary is sent to a Slack channel (4.).

    There are various sub-flows and utility flows supporting this main flow.

    The component are detailed in the following sections.

    Okta Events

    Earlier I described how we can use groups and the group to application mapping to represent roles. In this example, I have four groups mapped to Salesforce.com (SFDC) with each setting a specific SFDC role. For example group DO.SFDC.Role.Channel-Sales will map to SFDC role “Channel Sales Team” (as shown above).

    The only event in Okta we are concerned with is when a user is added to one of these groups.

    Workflows Table for SoD Flows

    The Okta Workflows configuration consists of two tables and a set of flows.

    The main table holds the SoD Policies. It has a row for each policy with a policy name, description, whether to enforce the policy or not (i.e. whether to back out the group membership), scope (the allowed number of groups in the set, more than this number will be a violation), the groups and the severity (not actually used).

    This table could be managed externally in a CSV file, and wiped and re-imported from the CSV file as needed.

    The other table is an environment variables table. I tend to use this as a best practice for all my flow sets to centrally store and manage variables I use in the flows, with a single sub flow to access specific values. The only value I use in this set of flows is called “SoD_group” and it stores a list of groups that appear anywhere in the flows. This is used as a first pass to determine if the new group could trigger SoD policy violation. If the new group isn’t in this list, the complex SoD checking isn’t done. I have a flow that will go through all the SoD rules (in the SoD Policy table) and re-create this list.

    Main Okta Workflow for User Added to Group

    There are many flows in this set.

    But I will focus on the main flow – M00 – User Add to Group Check SoD. The other flows are sub flows (S**) for specific functions called from the main flow, or utility (U**) flows to setup data.

    The main flow is shown below:

    The flow (as shown above) will:

    1. Be triggered by the user being added to the group and check to see if the new group is in the list of SoD groups, if so it will continue
    2. Check the SoD table to see if the new group and the users existing groups cause any policy violations
    3. If SoD violations are found it will continue on (it is possible that the new group is the first group in a SoD policy and thus not cause a violation), and format a email body standard text
    4. Check to see if there are any enforce=yes policies that have been violated, and if so go remove the user from the group in Okta and construct the email/Slack message bodies, otherwise just construct the email/Slack message bodies (it also checks to see if the group removal was successful or not and format the email content appropriately)
    5. Read the user to get their emails and manager ID, and if there is a manager ID it reads that manager user to get their email (or sets the manager email to be the system admin) then sends the email to users and manager, and a slack message to a channel in Slack (i.e. the channel that the compliance team would monitor).

    The following paragraphs will drill into each of these sections of the flow, but you can skip ahead if you aren’t interested in the flow details.

    Section 1 – Trigger and Pre-Check

    The flow is triggered by a User Added to Group event in a standard Okta Connector card.

    A sub flow (S90 – Is SoD Group) is called with the new group name. This sub flow will check if the new group is in the list of groups in SoD policies and return a true/false. If the response (is_sod) is true, the flow will continue.

    This is done for scalability/performance reasons. There could be a lot of group membership activity in an Okta org, but you don't want to check SoD rules for each one.

    Section 2 – Check for Violations

    The next section will retrieve all groups the user belongs to (note that this will include the new group as Okta has already added the user to it).

    It strips the group names out from the returned group object list and puts it into its own text list. It then sets an empty list that will be used to store the violations that are found.

    Next the SoD Policies table is searched for each policy rule (row) and each row is processed against the current group list by the S00 – Compare Curr to SoD Group Lists sub flow. The key to this sub flow is that it compares the two group lists with a List Intersection and List Length cards (i.e. how many groups are common to both), and compares this to the scope from the policy table (section of sub flow shown below).

    For example, if two groups are in the current users group list and also in a SoD policy, and the scope was 1 (i.e. you could only have one group) then the policy is in violation.

    As the main flow iterates through the policy rules, any violations are written to that (initially empty) violation list. This is why a List Reduce card use used.

    Section 3 – If Violations, Format Standard Message Content

    Once all the policy table rows have been evaluated, the main flow check to see if any violations have been detected and if not will stop executing.

    Before processing the violations, it will setup some standard content for the emails (i.e. this text will be used no matter what state of violation).

    It is formatting the message that has come out of the violations (i.e. a HTML formatted bit of text for each violation) and putting together a standard email body prefix and suffix.

    Section 4 – Format Specific Message Content (and Remove Group)

    The next section looks for any violations that have been flagged as enforceable (enforce=yes). It does this by finding the first instance of “Enforce = Yes” in the violations list (not found will return a -1).

    If there are any enforceable violations, it will attempt to remove the user from the group and format email and slack messages to suit. If this fails, or there are no enforceable violations, then different messages are formatted. Note that the email bodies are using the standard prefix and suffix from earlier.

    Section 5 – Send Emails and Slack

    The last section sends the email and Slack messages.

    It reads the user from Okta to get emails, and checks for a ManagerID field. If found it reads the manager to get their email, otherwise it sets it to an admin account. The last card (not shown) will send a slack message to a standard channel and flag it as coming from SoDBot.

    This is how it’s constructed. The last section shows how it runs.

    The Outcome

    For this example, we manually added the user (Waylon Smithers) to the SFDC Marketing role group.

    The user appears in the group straight away.

    But refreshing the group shows that Waylon has been removed.

    Checking the Okta System Logs shows the user was added to the group and almost immediately removed from the group.

    So the flow has executed and as the user was removed from the group they triggered an enforceable SoD Policy. We can see this in the email sent to Waylon.

    There was also a Slack message sent showing a summary of the event.

    This shows the flow has run as expected.

    Conclusion

    This article has shown how Separation of Duties (SoD) policies can be implemented using standard Okta data objects, events and Okta workflows and tables. It is a sample implementation to show how it could be built, but could be used as the basis for a custom deployment.

  • Can ASA Work With a Shared User Directory and Linux Servers?

    Using a shared user directory for user authentication across server farms has been a common pattern since the 1990’s. Microsoft adopted it with Active Directory, but we’ve had NIS deployments for many years. Can Okta Advanced Server Access (ASA) work where user authentication is delegated to a central shared directory? Yes.

    This article looks at how ASA can work with a shared directory for Linux servers (AD-Joined is a new feature that will be discussed in future articles).

    Linux Servers and Directories

    Whilst Linux servers can have local users and groups (e.g. entries in the /etc/passwd/ and /etc/group files) they can also be configured to delegate authentication to an external directory. Sun introduced NIS+ (Network Information Service) in 1992, and using a LDAP-compliant directory in Unix/Linux environments has been common since then. In the modern cloud world where servers are dynamically being spun up/down, having a persistent store of users for authentication makes even more sense.

    To implement external authentication a Pluggable Authentication Module (PAM) is deployed to each server and the local authentication defers to that. One example is the System Security Services Daemon (SSSD) being configured to work with a specific PAM to integrate with an external datastore. The A Look at IAM in Red Hat Enterprise Linux article includes a discussion of how the SSSD and RedHat Directory Server can provide a centralised authentication solution.

    From an end-user perspective they don’t know or care whether they are being authenticated locally or via a central shared directory. But what about ASA and it’s need to provision users and groups to servers it manages?


    ASA and User/Group Provisioning

    The default model for ASA with Linux servers is to centrally manage users and groups and provision them to servers in a project. The ASA (Server) Agent will, by default, periodically check with ASA and apply changes to /etc/passwd and /etc/group.

    But this doesn’t have to be the case – a project can be configured to NOT provision users and groups to a server. The ASA SSH mechanism doesn’t care whether ASA has provisioned the users, only that the OS can authenticate the user passed from the SSH client. So as long as SSSD (or equivalent) is configured correctly and the ASA users are mapped to the directory users, then ASA SSH will work fine.

    Let’s look at how we configure ASA to do this.


    Configuring ASA to Work with a Shared Directory Deployment

    The following figure shows the components and flows for this.

    The primary flow (blue) is the user SSH’ing to the target Linux server, being authenticated against Okta and then validated against the shared directory via SSHR/PAM (or equivalent).

    The backend flow is between Okta (the Okta Identity Cloud), the ASA Cloud Service and the ASA (Server) Agent on the target server. Users and groups are managed in Okta and are provisioned to ASA. There is some mapping of usernames between the Okta format and the Unix format so that the user can be authenticated to Okta and validated against the shared directory.

    For this particular server there is a project configured to NOT perform user management (provisioning) to the servers. So when the ASA Agent connects to ASA it will only download/update the SSH certificate signing authority, not the users and groups.

    The following sections describe how we configure both the ASA project and the username mapping to support this. The last section looks at the user experience (the blue flow).

    Project Configuration

    To stop ASA provisioning users to managed servers, there is a flag that is set at the project level. It shows up as the Server User Management column in the project list.

    Currently there is no Admin Console UI flag to disable provisioning users in a project – it must be done via an API call. The documentation is at https://developer.okta.com/docs/reference/api/asa/projects/#create-a-project and the body attribute needs to include "create_server_users": false.

    This could be done in code, a script, postman, Okta Workflows, or anything else that can call a REST API.

    The following figure shows an example in Okta Workflows.

    The flow sets up the bearer token for the API call (not shown) and sets the team name (also not shown). The two compose cards are defining the API URL and the new project name. The third card is setting up the HTTP Body object. Of note is the create_server_users value of False. The last card is making a HTTP Post call to that project API URL, passing the bearer token in the HTTP Header and the object from the third card in as the HTTP Body.

    Note that you could theoretically turn off provisioning for an existing project with https://developer.okta.com/docs/reference/api/asa/projects/#updates-details-of-a-specific-project, but I have not tested it.

    Setting the Correct Unix Username in ASA for the Directory

    The unix username that the ASA client is passing via SSH needs to match the username known to the target Linux system. We may need to change how Okta and ASA map usernames to suit a shared directory. Let’s talk about how Okta and ASA do username mapping, then at how it can be implemented for this scenario.

    User and Account Mapping

    The ASA Client has two username-related functions – it must be able to authenticate the user against the ASA Cloud service/Okta, and it must pass a username over SSH. The user that the ASA Client is passing to the ASA Daemon on the Linux server must match the user that the Linux server can authenticate – in this scenario that’s the username for the account in the shared directory.

    For the ASA username, the ASA application definition (in Okta) will use the Okta username by default (so ASA can authenticate the user with Okta).

    For the Unix username there are two ways it can be set: automatically in ASA or from an Okta profile attribute mapping. There is an Okta user profile attribute, unixUserName, that can hold a value to be used by ASA, that is used to drive the username creation in ASA.

    If the value of unixUserName is blank in Okta, then when the user is provisioned to ASA, ASA will build the local UNIX_USER_NAME from the Okta username, whilst applying some translation rules such as special characters being converted to underscores. For example kent.brockman (Okta username) becomes kent_brockman (UNIX_USER_NAME). See https://help.okta.com/asa/en-us/Content/Topics/Adv_Server_Access/docs/user-management-linux.htm for details on the translation.

    If the unixUserName contains a value in Okta, then when the user is provisioned to ASA, this value will be passed in the user profile and set (with translation rules) as the UNIX_USER_NAME in ASA (and used for SSH).

    This gives us the building blocks to work with usernames in a shared directory.

    How to Apply Okta/ASA Mapping to the Shared Directory

    Before implementing the projects and attribute mapping, we need to understand the username format in the shared directory. Is there a standard that’s been applied to naming (e.g. firstname_lastname) or is it somewhat arbitrary? How well does it align to what you have in your Okta usernames (e.g. kent.brockman in Okta == kent_brockman in the directory)?

    If the directory username aligns directly with the Okta username, then you can let ASA build the unix username based off its standard transformation rules, i.e. the unixUserName attribute in the Okta profile is blank and not used, ASA takes the Okta username and translates it.

    If the directory username does not align directly, but is easily (and consistently) derivable from user attributes (e.g. unix username is always U<employee#> or unix username is always <first 7 char of firstname><first char of lastname>, then you could use Okta Expression Language in the profile mapping. For example:

    • String.append("U", user.employeeNumber) for the first example
    • String.append(String.substring(user.firstName,0,7), String.substring(user.lastName,0,1)) for the second example

    The first example is shown below for the ASA application attribute mapping.

    Otherwise, if you can’t guarantee a structure or uniqueness of the unix username in the shared directory, you will need to maintain the unixUserName attribute on the Okta user profile and rely on the default mapping of that to the unixUserName attribute in ASA.

    For example, with a value of linux_12345 in the Okta user profile, this will be mapped to the UNIX_USER_NAME field in ASA.

    How you maintain this unixUserName data in the Okta profiles will depend on the complexity of the usernames in the directory and whether there are exceptions. One option may be to deploy an Okta LDAP agent to the directory, have the users imported into Okta then have some automation (with Okta Workflows) to set the appropriate unixUserName values. Another option may be to apply a default standard naming based on the most-used naming standard in the directory, then manually manage the non-standard usernames.

    The above expects that same unix username to be used across all ASA-managed servers. If you need multiple different standards such that some servers need one unix username format whilst others need another, you may need to look to multiple ASA teams with different profile attribute mapping, and potentially different Okta profile attributes, or maybe even different Okta orgs.

    In summary, there will need to be some analysis of how the usernames are in the shared directory, and how Okta/ASA can effectively manage them (automatically or with some manual intervention).

    User Experience

    The user experience for SSH’ing to a server that is connected to a shared directory is exactly the same as for any other Linux server. A list of servers will show the server the same as for the other servers.

    When the user performs SSH (via sft, the following has ssh aliased to sft ssh) the experience is the same.

    The above example shows that Kent Brockman SSH’s as kent_brockman. But there is no user kent_brockman in the local /etc/passwd file – the user is in a directory (openLDAP) on another server connected to via SSSD.


    This concludes the article. We have shown how ASA can operate in an environment where Linux users are authenticated via a shared directory not locally. We have explored how to configure Okta and ASA to support this model and what it looks like from an end-user perspective.

  • ASA PreAuthorization with Okta Workflows

    This article explores how standard Okta self-service access requests and Okta Workflows can be used to implement Just-In-Time access to Okta Advanced Server Access. It assumes some understanding of Okta, Okta Workflows and Okta Advanced Server Access objects and capabilities.

    Just-In-Time Access with Okta Advanced Server Access

    A common request with Okta Advanced Server Access (ASA) is for just-in-time server access. This can be implemented in one of three ways – group membership, on-demand provisioning and preauthorizations.

    As ASA server access is tied to group membership in ASA projects, and the Okta Identity Cloud platform is managing group membership, you could dynamically allocate/de-allocate access using group rules or a request-based mechanism. This could include automation with workflows, such as the Okta Workflows Assign Temporary Group Memberships template.

    With a user in the appropriate group, ASA will provision that user. There is a project “On Demand User TTL” setting that is disabled by default, meaning a user is provisioned as soon as they are associated with the project. If one of the TTL values is selected ASA will only create a user on a server when a user attempts to access it, and users will be removed when the session ends or after the configured period. See https://help.okta.com/asa/en-us/Content/Topics/Adv_Server_Access/docs/on-demand-users.htm.

    ASA also provides a preauthorization capability. In addition to being in the appropriate group, a user also needs to be preauthorized to access servers in a project. Pre-authorization is set at the project level in ASA – some projects could require pre-authorization whereas others don’t. Perhaps the server risk analysis calls for some servers to have pre-authorization and you could put them in their own project.

    A user can be preauthorized in the ASA Admin Console by an ASA admin. Creating a preauthorization involves setting an expiry date/time for a specific user.

    Creating a preauthorization involves selecting the user and an expiry date/time.

    In addition to using the ASA Admin console, there is an ASA API to work with preauthorizations (https://developer.okta.com/docs/reference/api/asa/projects/), including fetch, create and update a preauthorization, and list preauthorizations for a project. This could be used from a service request system like ServiceNow, to request JIT access to servers.

    The API to create a preauthorization is implemented in the Okta Workflows ASA connector (https://help.okta.com/wf/en-us/Content/Topics/Workflows/connector-reference/advancedserveraccess/actions/createpreauthorization.htm) and is shown in this article. Preauthorizations will automatically expire at the expiry date/time.

    The rest of this article will look at how we can implement a preauthorization request function in Okta using Okta Workflows (and how we can cleanup after).

    Request ASA Preauthorization With Okta and Workflows

    The mechanism involves standard Okta features and Okta Workflows, as well as ASA.

    Overview

    To demonstrate the component and flow, I have a setup based on the need to preauthorize access to a set of Linux servers. The end goal is that the user needs to be able to SSH to a specific Linux server, but in addition to being in the right group, they also need to be preauthorized with an approval process.

    The components and flow are shown below.

    The sequence is:

    1. The user uses the Self Service component of the Okta Dashboard to request access to an application (a dummy application called “req Linux Server Access”). There may be a manager approval on the flow. Once approved the user is added to this application in Okta.
    2. The user added to application event in Okta triggers a workflow. This workflow will set a future date/time,
    3. Add the user preauthorization (using the ASA connector) and then
    4. Store the user and date/time in a Workflows table (which also acts as an audit trail)
    5. Periodically a second workflow will run through all the entries in the Workflows table to determine the expired preauthorizations and remove the associated user from the Okta app. This is needed because the preauthorization will automatically expire in ASA, but the user will still be assigned to the request app in Okta – if they weren’t removed, they couldn’t request it again.

    The rest of this article will look at how this is implemented and used.

    Preauthorization Components and Flow

    This implementation has components in Okta (Identity Cloud), Okta Workflows and Okta ASA.

    Okta Identity Cloud Configuration

    Within Okta there is a dummy application for the user to request, and the access request mechanism.

    The dummy application, called req Linux Server Access, is a bookmark app that will be exposed via the Self Service access request mechanism. It only needs a name/label, an icon (if you want) and a dummy URL. It will not be displayed to the end user or on the mobile app. It will never be used for SSO.

    The access request mechanism is the legacy Okta Lifecycle Management (LCM) self service access request mechanism. This will be replaced by the Access Requests feature of Okta Identity Governance in the future, but the outcome is the same – a user can request the app.

    In this example, no approval flow has been enabled, but it could have been set to require manager or app owner approval. As it is, the user just needs to request the application and it will automatically be granted.

    Okta Workflows Configuration

    For the request processing, there is one table and one flow (there are additional flows in the cleanup, covered later).

    The table is used to store all requests, serving as an audit trail, but is also used in the cleanup. Each row represents a request and contains who requested it, when, who it’s for (in this implementation it’s the same user), when it expires and when it was cleaned up.

    The MAIN – Add User to ASA Preauth workflow contains the event trigger and six cards.

    The event trigger is the User Assigned to Application event in Okta, looking for a specific application (the Id of the req Linux Server Access application).

    This event will return details of the administrator, the Okta user profile and the application user profile. To update ASA we will need the ASA username, which is the short Okta username (e.g. the bit before the @ in the Okta username). The Okta username is stored in the Alternate ID field. We want to strip off the ‘@’ and following parts to get the short username (Split and At cards).

    In the above example, Alternate ID is “kent.brockman@deadwood.com”, so we split on the ‘@’ into an array and get the first entry of “kent.brockman”.

    The next two cards (Now and Add) determine the current date/time and add two hours to it.

    The next card is the ASA Create PreAuthorization card. It requires three parameters, the short username, the project the user is to be preauthorized for and the expiration date/time (which is the current time plus two hours.

    The last card (Create Row) will write the details of the request into the PreAuth History table.

    Okta ASA Configuration

    The ASA configuration involves a project with the Require Preauthorization (Preauths Required) flag set.

    When the workflow above runs, you can see the preauthorization in the ASA Admin Console for the project.

    That is all that’s involved in the setup to request preauthorization. The last section of the article will look at the cleanup process.

    Cleanup Components and Flow

    As mentioned earlier, the ASA preauthorization feature will automatically expire at the expiry date/time. However as we’ve added an extra component to this flow, the dummy request app, we need to clean it up. We can do this with a scheduled workflow leveraging the information we stored in the table.

    This is done entirely in Workflows, with a main flow, a sub (helper) flow and the table shown above.

    The main flow could be run on a timer or on demand. There are three execution cards.

    The first card is determining the current date/time.

    The second card is searching through the PreAuth History table looking for all rows where the expiry date is less than the current date. This is just an example, and you would want something more scalable in a production deployment as this table will continue to grow.

    The last card calls a subflow for each row returned from the table. The subflow will be passed the PreAuth History row as an object.

    The first card extracts the row id, user id and cleanedup date/time. If the cleandup entry is empty, the flow continues.

    The third card will Remove User from Application – remove the user in the table row from the req Linux Server Access application.

    The last card updates the row in the table (using the row id from earlier) to set the cleanedup date/time to now.

    Running the flow results in multiple executions of the subflow, one for each row with an expired date/time in the past. The subflow will remove the user from the application and update the table.


    This concludes the article. We have shown how we can use standard Okta self service access requests with a dummy app and an Okta workflow to create an Okta ASA preauthorization to allow temporary access to a server.

  • Continuous Certification with Okta Workflows

    This article provides an approach to implementing continuous (re)certification using Okta Workflows. It discusses the concept and then walks through the sample implementation.

    IGA, Certification and Continuous Certification

    A key focus for Identity Governance and Administration (IGA) implementations is access certification (aka recertification or attestation). The aim of this is to periodically validate the access users have and provide an audit trail of that validation to address the audit need of “prove that the access has been reviewed”. This is usually done with periodic certification campaigns that are run for a period of time, and may review all users, users in a certain application or some other risk-based categorisation.

    Another approach is to use continuous certification. Rather than checking a set of accesses at a time, setup a mechanism that will detect a change in access and provide a review mechanism on that access change. This could be combined with a less-frequent periodic campaign to provide a baseline, then a continuous campaign to manage changes.


    Can We Do This In Okta?

    Okta, even without the new Okta Identity Governance product, has the capabilities to implement a continuous campaign mechanism.

    First, Okta knows when a user is added-to or removed-from an application. It also knows when a user is added-to or removed-from a group and what applications that group is associated with. So the data model and change events provide the means to drive a campaign.

    Second, Okta Workflows can trigger flows off one of those change events and implement a validation mechanism.


    Implementing a Continuous Certification Campaign in Okta

    So we have trigger events and Workflow flows to implement it.

    Trigger Events in Okta

    There are four events in Okta that could indicate a change in access: a user added to a group, a user removed from a group, a user assigned to an application, and a user unassigned from an application.

    These events are available in the Okta Connector in Okta Workflows. For details of the events, see https://help.okta.com/wf/en-us/Content/Topics/Workflows/connector-reference/okta/okta.htm.

    Workflows Flows

    There are ten flows used in this implementation (detailed below):

    • A00 – Suspend User – flow triggered off an API hook to suspend a user
    • F00/01/02/03 – Main flows off the four events listed above to process the access changes
    • S00/01/02/03 – Subflows to support the main flows
    • U02 – Export Audit Table to CSV – utility flow

    The main flows will run in response to an event in Okta and send an email to the users manager. The manager will review the email and is offered the option to suspend the user if they access change is suspect. (note, suspending the user is a safer option that removing them from the app or group as there may be group rules that have dynamically added them in the first place). It will also send a Slack message and write an audit event into a Workflows table.

    A sample email is shown below:

    This email has been generated because the user was added to a group (Sales) which means they get access to Salesforce. For completeness, the flows will also show the apps the user has (including the new one(s)) to identify any possible conflicts or inconsistencies.

    As mentioned above, the manager is given the option to suspend the user with a link. The link was kept in that form for demonstration purposes (show the API endpoint called) but you would obfuscate it or tokenise it.

    We will look at the flows contributing to this.

    Main Flows (F**)

    There are four main flows, one for each event.

    They all follow the same structure, so we will look at the first – F00 – User Added to Group. This flow will:

    • Trigger off the user added to group event
    • Lookup both the user and group to get additional details
    • Check the group is NOT the everyone group (it will stop the flow if it is)
    • Get the application list for the group and the user
    • Build the API endpoint (suspend) URL and get the manager email for the user
    • Format and send an email
    • Format and send a Slack message
    • Write and audit event

    Let’s look at each section of this flow.

    The flow is triggered by a User Added to Group event and the event will supply both the Okta user and group.

    A Read User card will get details of the user, including a custom field of Manager email. There is a Read Group card to get more information about the group.

    We don’t want to process events against the Everyone group, so there is a Continue If card to check if the group is not equal to “Everyone”.

    The next four cards use sub flows to get additional data via Call Flow cards:

    • The S00 – Get App List for Group flow will return a list of applications that the group is assigned to (in both a text string and a formatted HTML list)
    • The S03 – Get App List for User flow will return a list of applications already assigned to the user (in both a text string and a formatted HRML list)
    • The S02 – Get Flow Variable flow is passed an environment variable name and returns the value of the environment variable (which are stored in a Workflows table). In this case it’s returning the email of the system administrator and the URI of the suspend flow API endpoint.

    The values returned from these calls are used in later cards.

    The first means of communication is an email to the manager. The two Compose cards shown above will build the email subject and HTML-formatted body. These are passed to the Google Send Email card for emailing out.

    The second means of communication is to send a message to a Slack channel (note that it doesn’t send it to a specific user such as the manager, but it could if it had the SlackID of that user).

    It uses a Compose card to build the Slack message. Then it uses the S02 – Get Flow Variable sub flow mentioned above to get the SlackChannel environment variable. The outputs from these are then used in a Slack Send Message to Channel card.

    As this is a governance mechanism being implemented, it makes sense to produce an audit trail of the changes and result. A Compose card is used to write the audit message. Then a sub flow, S01 – Write Audit Event, is used to write this event to the audit trail (table).

    The other three main flows are similar.

    API Endpoint Flow (A00)

    The A00 – Suspend User flow is triggered by the manager clicking the link in the email.

    The link was built from the API Endpoint card that starts the flow (and stored in the environment variables table mentioned above).

    When the flow is triggered, it is passed the userid via the URL query string. Within a Try/On Error card, it will attempt to suspend the user with an Okta Suspend User card.

    Whether successful or not, the rest of the flow is basically the same as the earlier flows:

    • Read the user to get user details for use in emails, slack and the audit message
    • Format and send an email
    • Format and send a Slack message
    • Format and write an audit trail event

    That concludes the discussion of the main flows. The next sections look at the called flows (now called Helper flows in Workflows terminology).

    Sub Flows (S**)

    I have a number of common flows, like shared subroutines, called from the main flows. I’ve called them “Sub flows” but in Workflows terminology they are just helper flows. They are:

    All of the flows and their purposes have been mentioned above. I will walk through some of them to highlight some Workflows capabilities.


    The first flow, S00 – Get App List for Group will retrieve the list of applications assigned to a group. The flow is passed the groupId for the group the user has just been added to (or removed from).

    There is (currently) no Okta card to get the apps for a group, so a Custom API Action card is used with a Compose card used to build the API URL. The Custom API Action card, if successful, will return the results in the HTML body object.

    The List Pluck card is used to pull the label attribute out of the Body. This is the app name list. The second card, List List to Text, will format that list into a text string (in this case only a space is the separator). The third card, List List to HTML (it’s actually a List to Text card), will format the list into a string with a <li> separator.

    A Compose card is used to build the HTML string for an unordered list of app names. Then the Return card will return both the string and HMTL formatted lists to the calling flow.


    The S01 – Write Audit Event flow is passed the affected user, who the event was performed by, and the message shown above. It determines the current date/time and the timezone (environment variable) and formats the time. These values are written to the Audit table.

    The S02 – Get Flow Variable flow is passed an environment variable name. It performs a lookup against the environment variable table and returns the corresponding value. An example of the table is shown below.

    The S03 – Get App List for User flow is almost exactly the same as the S00 flow. The only difference is the API URL used (/api/v1/users/$userid/appLinks).

    Utility Flows (U**)

    The last set of flows are the utility flows. In Workflows terminology they are also Helper flows. The distinction is that these flows don’t support the main flows above, but rather are standalone utilities.

    The only one of interest here is U02 – Export Audit Table to CSV. It is a simple flow to dump all the rows in the Audit table to a CSV file. It is run on demand but could be scheduled.

    It uses a single Tables Export to CSV card. The flow could easily be expanded to store the CSV file on a google drive, and send an email to someone with the link to the file.

    Design Points

    The above article has shown how the Okta events and Okta Workflows can be used to implement a continuous campaign mechanism. The implementation of the flows in Workflows also highlights some design considerations.

    • Use of sub flows (sub routines) – the structure of Workflows means helper flows will be necessary for any repetitive task. It makes sense to structure helper flows so that they implement common functions and can be used across multiple main flows. It may mean passing more data so the sub flow can be leveraged from multiple main flows, but it makes the implementation more efficient and easier to understand.

    • Use of environment variables in a table – this implementation needs to use some common “environment variables” across the different flows. Rather than hardcoding them in each flow, it’s more efficient to store them in a single place and access them via a common helper flow. A workflows table makes sense, but it could be an external datastore accessed via a lambda function, a file stored on a drive or other ways Workflows can get to data.

    • Use of a table for the Audit trail – this is a governance implementation where an auditor would like to see evidence of what has occurred, such as user access changes. It was simple to implement this by using a common sub flow to write audit records to a Workflows table (and having a utility flow to export it).

    • Naming standards – Okta Workflows does not enforce naming standards on flows or tables. But it makes sense to give them meaningful names. I find it useful to prefix the flows (and tables) by unique identifiers to indicate the type of flow and to order them alphabetically.

    Hopefully these points will help when you’re designing and implementing processes in Workflows.