Querying SailPoint IdentityNow Virtual Appliance Clusters with PowerShell

Today I was configuring an Integration Module for SailPoint IdentityNow. As part of that integration I needed the ID of an IdentityNow Virtual Appliance Cluster. It seemed I hadn’t previously documented doing this and I couldn’t find my previous script. So here’s a quick post for the next time I need to get info about the SailPoint Identity Now Virtual Appliance Clusters in my environment.

The following script uses v3 Authentication as detailed in this post.

Update;

  • line 2 with your IdentityNow Orgname
  • line 5 with your Admin Account Name
  • line 6 with your Admin Password
  • line 16 with your IdentityNow v3 API Client ID
  • line 17 with your IdentityNow v3 API Client Secret

 

 

Forefront/Microsoft Identity Manager – Attempted to access an unloaded AppDomain

This post is more a note-to-self for future me in case I’m in this scenario again. Today I encountered the error Attempted to access an unloaded AppDomain.

I have a custom Forefront/Microsoft Identity Manager Management Agent that requires multiple credentials for the Web Service it is integrating with. In order to secure parts of the credentials that cannot be provided as part of the Connectivity configuration tab on the Management Agent Proporties I have generated them and exported them using Export-Clixml as detailed in this post here.

Today I was migrating a Management Agent from one environment to another and was sure I’d regenerated the credentials correctly. However the Management Agent wasn’t working as expected. Looking into the Applications and Services Logs => Forefront Identity Manager Management Agent Log ….

Forfront Identity Manager Management Agent.PNG

i found the following error ….

Unhandled exception, the CLR will not terminate: System.AppDomainUnloadedException: Attempted to access an unloaded AppDomain

Attempted to access an unloaded AppDomain.PNG

Retracing my steps, I had logged on to the Synchronisation Server with the incorrect credentials to generate my protected credentials XML file.

When the Synchronisation Server was running the Management Agent and attempting to run Import-clixml “credentialFilename” the credentials/account that had exported the credentials did not match the service account that the synchronisation server was running with. And the error listed above was thrown.

Summary

Import-clixml and Export-clixml do exactly what they are supposed too and respect the context by which the credentials were exported and will only be able to access them when imported under that same context. The error doesn’t really tell you that but does hint at it with Attempted to access an unloaded AppDomain if you know what you are trying to do.

 

Winner: Microsoft Graph Security Hackathon

Recently I entered my second Hackathon. My submission was my first ever Web Application for the Devpost / Microsoft Graph Security Hackathon. This morning (Australian time) the winners were announced and ……. I WON.

To say I’m thrilled and honoured would be an understatement as the hackathon was judged by the esteemed Ann Johnson, Scott Hanselman, Troy Hunt, Rick Howard, Mark Russinovich and Olli Vanhoja. Big thanks also have to go to Preeti Krishna from Microsoft who was super responsive on queries around the Microsoft Security Graph.

Microsoft Security Graph Hackathon Judges.PNG

My entry; Microsoft USER (User Security Evaluation Reporter) is an application that reports on any user within an Active Directory/Azure Active Directory and their associated security posture with respect to Risk Events, Enrolled MFA Methods, Password Pwned Status and Azure Password Reset Events. The UI provides a quick summary overview as shown immediately below with the ability to then drill down into each evaluation area.

User Secure Score Summary

Additional details about my submission can be found here including the architecture and technical details but here is a walk through demo of it.

 

Indexing a SailPoint IdentityNow Attribute in an Identity Cube for use in Correlation Rules

Joining/Matching rules in any Identity and Access Management Solution can make or break an Identity Lifecycle Management implementation. Out of the box SailPoint IdentityNow provides a number of common Identity Attributes that can be used for Correlation rules (joining/matching) from Identity Sources (connected systems).

Often though you want to add additional attributes to the list of Identity Attributes that can be used for correlation. The IdentityNow Portal does not provide this functionality, but it is possible via the IdentityNow API. However the documentation and guidance around this is a little sparse. This post details how to use the API to enable additional attributes for use with correlation rules.

NOTE: The guidance is to be pragmatic with the number of additional attributes that you add as Identity Attributes for Correlation. The guidance is a maximum of 7 additional attributes 

Prerequisites

  1. Authentication. I using the v3 method that I detail here
  2. On an Identity Profile you’ll need to map the attribute from a Source to an attribute in the Identity Profile.
    • In the IdentityNow Portal go to Admin => Identities => Identity Profiles => Your Identity Profile => Mappings => Add Attribute

Process

I’m using PowerShell, but the process can be transposed to any language that you can use to make Web Requests. The high-level process is;

  1. Get the list of Identity Attributes
  2. Locate the attribute you want to be available for Correlation rules
    • this is required as addressing the attribute to make it available is case-sensitive
  3. Update the object to make it Searchable
    • making the attribute Searchable promotes it to being available for Correlation Rules

The Script

The steps in the script below assume you are authenticated to the IdentityNow API as detailed in the prerequisites. You should only need to then update line 12 for the attribute name you want to make searchable and available for correlation rules.

The script steps (that you will want to manually step through);

  •  Get the list of Identity Attributes
    • The attribute you want to promote to be searchable should be present, as you’ve mapped it in an Identity Profile as detailed in the prerequisites
  • Get the attribute to modify
  • Modify the attribute object to make it searchable
    • modify other aspects of the Identity Attribute to allow the attribute changes to be written back to IdentityNow
  • Update the attribute in IdentityNow

Summary

As the script above shows, the process to update an attribute to make it searchable and available for correlation rules is a little more involved that just flipping an attribute value, but once you know how reasonably trivial.

Building SailPoint IdentityNow Azure AD Source Filters

When you have a large Azure AD tenant it is likely that you want to scope your SailPoint IdentityNow Source based on the different type of identities it contains. Using the Filtering and Scoping section of the Azure AD Source Configuration Guide from Compass I first started constructing queries as I normally would with Azure AD against the Microsoft Graph API.

However the queries/filters I was using against Microsoft Graph were not working for the Azure AD IdentityNow Source. On aggregation the Source Connector would throw errors such as;

….java.lang.RuntimeException – sailpoint.connector.ConnectorException: Exception occurred. Error message – Exception occurred in processReadRequest. Error – Response Code – 400 Error – Bad Request Property ‘msGraphAADAttribute’ does not exist as a declared property or extension property…..

Following some discussions with the IdentityNow Professional Services guys I learned that the IdentityNow Azure AD Source Connector uses the Azure AD v1 Graph API endpoint.

With this information I was then able to use the Azure Active Directory v1 Graph API Explorer to develop queries that would then work for ‘User Filters’.  This is extremely quick and useful. For guidance on using Azure AD Filters this Microsoft document will get you started.

Azure AD v1 Graph Filter Tester.PNG

Configuring Azure AD Source Filters

To configure Source Filters for the IdentityNow Azure AD Source I use PowerShell as per the many IdentityNow Configuration and Automation posts I’ve previous written.

SailPoint IdentityNow Authentication

The script snippets below just show the commands to create three different Azure AD Source Filters (if you need all three like me you will need to configure three separate Sources with a different filter on each). In order to utilise these you will need to be authenticated to the SailPoint IdentityNow API. This post details connecting to the SailPoint IdentityNow v3 API endpoint using PowerShell.

Below shows three snippets for scoping the Azure AD Source down to specific User Types;

  • AAD Guest Accounts (B2B)
  • AAD Hybrid Accounts (On Premise AD and Azure AD)
  • AAD Cloud Only Accounts

To update a source you send a POST request to the Update Source API where yourOrg is your Tenant Org Name and SourceNumber is the number of the Source to update (e.g. 12345). The body is the connector_userFilters attribute with the value for the filter.

https://yourOrg.api.identitynow.com/cc/api/source/update/SOURCENumber

Hybrid Accounts

The following shows the tail of the output from the returned object after updating the Source for a filter for Azure AD Hybrid Accounts;

dirSyncEnabled eq true and userType eq 'member'

Hybrid Users.PNG

Azure AD Cloud Only Accounts

The following shows the tail of the output from the returned object after updating the Source for a filter for Azure AD Cloud Only Accounts;

dirSyncEnabled eq false and userType eq 'member'

Cloud Only Users.PNG

Azure AD Guest (B2B) Accounts

The following shows the tail of the output from the returned object after updating the Source for a filter for Azure AD Cloud Only Accounts;

userType eq 'guest'

B2B Guests.PNG

Summary

Knowing the API the IdentityNow Azure AD Source is using allows us to construct filters to scope the Azure AD Source to the specific users for an implementation.

Changing SailPoint IdentityNow Identity Profiles Priorities using PowerShell

In SailPoint IdentityNow a single user is highly likely to be represented on multiple Sources, that in turn are likely to be authoritative for differing SailPoint IdentityNow Identity Profiles. Often the first or last Identity Profile you create isn’t the one you wish to have the highest or lowest profile and you therefore need to change an Identity Profiles precedence so that the correct Identity Profile is associated with your identities.

The priority of IdentityNow Identity Profiles cannot be changed through the Portal, but it is possible to perform the change via the API as detailed in this Compass document.

Rather than following the Postman path described in that document, knowing I’m going to need to do this irregularly but relatively quickly I’ve written a little PowerShell script to make the changes.

By default an Identity Profile when created is added to the bottom of the list and their priority increased by 10 from the last Identity Profiles’ priority. The script will by default make the Identity Profile you choose 5 higher that the Identity Profile you’re moving it above.

The following screenshot shows 5 Identity Profiles in their priority order. Let’s say we wanted to move the System Accounts Identity Profile from the bottom priority to between Cloud Identities and Badged Identities.

IdentityNow Priority List.PNG

Using the script (at the bottom of this post) we can authenticate to IdentityNow and retrieve the IdentityNow Profiles with their Priorities. It will ask which IdentityNow Profile you wish to increase the priority of. By default it defaults to the one at the lowest priority.

Identity Profile Priority Changer 1.PNG

You are then prompted for where you would like to move it. Type the name of the Identity Profile you want to move it above.

Identity Profile Priority Changer 2a.PNG

Confirm your selections by typing ‘y’. Anything else will cancel the operation.

Identity Profile Priority Changer 3.PNG

The update will be made in IdentityNow and the output will indicate the updated priority given to the Identity Profile that was moved.

Identity Profile Priority Changer 4.PNG

Checking in the IdentityNow Portal we can see that they Identity Profile was moved from the bottom to between Cloud Identities and Badged Identities.

IdentityNow Priority List Updated.PNG

The Script

Below is the script that performs the changes to Identity Profiles priorities. Update the following script for;

  • Line 2 for your Client ID
  • Line 4 for your Client Secret
  • Line 8 for your Org name
  • Line 10 for your Admin Account name
  • Line 11 for your Admin Account password

Summary

Using this script is a quick way to change the priority of Identity Profiles in SailPoint IdentityNow.

SailPoint IdentityNow Identity Profiles Mapping Report

Last year I wrote this post here that detailed using the SailPoint IdentityNow API to generate an IdentityNow Sources HTML Report using PowerShell.
In a similar vein here is a post that does a similar function, but for the IdentityNow Identity Profiles. The example script below will connect to IdentityNow and extract all the Identity Profiles and pull out the details for the Mappings and create an HTML Report with a section for each Identity Profile.

SailPoint IdentityNow Identity Profiles Report.PNG

Report Script

Update the script below for;

  • Line 2 for your v1 API ClientID
  • Line 4 for your v1 API Client Secret
  • Line 8 for your Org Name
  • Line 10 for your Admin Name
  • Line 11 for your Admin Password
  • Line 22 for an image path for the report
  • Line 27 for the output path for the report

The Report

The resulting report that will be located in the output path you specified, will let you expand each of your Identity Profiles and see the attributes mapping configuration associated with it. A snippet of an Identity Profile is shown below.

SailPoint IdentityNow Identity Profiles Report Details.PNG

Summary

The ability to report on the attribute mappings for Identity Profiles gives a quick way to document or report on the attribute mappings. If you’re so inclined the script can be easily extended to report on all other aspects of the configuration items of an IdentityNow Identity Profile.

The image I’m using in the report is from this page and sized at 240 x 82 px.

Aggregating SailPoint IdentityNow Sources via API with PowerShell

Aggregating an IdentityNow Source can be achieved in a number of ways, but when you are in a development environment there will be times where you need to add additional attributes for a Source to load. If the additional attribute(s) is/are used for Correlation, it’s at this time you will need to perform a full aggregation from a Source to re-evaluate each object with the new Correlation rules and to bring in the additional attributes for each identity on the Source.

The LoadAccounts API briefly mentions this in this SailPoint IdentityNow Compass document. It also details the option that needs to be disabled disableOptimization so that each identity is imported and re-evaluated.

This post details how to call the LoadAccounts API using PowerShell and disable optimization.

Prerequisites

The LoadAccounts API is a Private API that has a different authentication process that the v2 and v3. In this post I detail accessing the v1 Private API’s using PowerShell.  That post gives some more detail around the v1 Private API’s.

The following script will aggregate a SailPoint IdentityNow Source disabling optimisation.

Update;

  • Line 2 with your API ClientID
  • Line 4 with your API Client Secret
  • Line 8 with your IdentityNow Org Name
  • Line 10 with your IdentityNow Admin Account Name
  • Line 11 with your IdentityNow Admin Account Password
  • Line 25 with the SourceID (5 digit number) for the Source to Aggregate

Line 29 contains the Web Request Post Body disableOptimization=true” that disables optimisation for the aggregation. If you just require an aggregation of a source omit the body.

Executing the script with valid credentials and a Source will result in the aggregate variable returning a summary for the trigger of the aggregation. You will notice in the attributes that optimizedAggregation is disabled.

Returned Object when initiating IdentityNow Aggregation via API with optimisation disabled.PNG

This is also reflected in the Aggregation Summary from the Portal when completed.

IdentityNow Aggregation via API with optimisation disabled.PNG

Summary

Using the above script it is possible to quickly perform a full aggregation and re-evaluation of correlation rules for an IdentityNow Source.

 

Creating SailPoint IdentityNow Access Profiles via API and PowerShell

Managing SailPoint IdentityNow Access Profiles is easy enough to do using the SailPoint IdentityNow Portal. But what if you have the requirement to update, report on, or create numerous Access Profiles? That’s where the SailPoint IdentityNow API comes into play. The Access Profiles API is documented here but doesn’t go into a lot of detail. In this post I’ll detail interfacing with it using PowerShell primarily to create and update Access Profiles.

Prerequisites

You will need to Authenticate to the IdentityNow API. Both v2 and v3 authentication methods work. I detail the v2 method here and the v3 method here. Personally I’m using the v3 method. Just make sure you change your Headers for the requests to whatever method you use and the naming of your variables.

For reference my v3token variable is $v3Token so my Authentication Header is then @{Authorization = “$($v3Token.token_type) $($v3Token.access_token)”}

Getting Access Profiles

The Access Profiles API URI is

https://$($yourOrgName).api.identitynow.com/v2/access-profiles

If you know the ID of the Access Profile you can return just that Access Profile via it’s ID (where $accessProfileID is the ID that looks like 2c91808466a64e330112a96902ff1f69)

https://$($yourOrgName).api.identitynow.com/v2/access-profiles/$($accessProfileID)

The following script will return Access Profiles from your SailPoint IdentityNow Tenant. Update;

  • Line 2 for your IdentityNow Org name

Updating Access Profiles

To update an Access Profile the API URI is;

https://$($orgName).api.identitynow.com/v2/access-profiles/$($accessProfileID)

The following will update an existing Access Profile to make Request Comments Required and Denied Comments Required equal False.

Update;

  • Line 2 for your IdentityNow Org name
  • Lines 6 for the ID of the Access Profile you want to update
  • Lines 9,10 for the settings to update

Preparing to create an Access Profile

In order to create an Access Profile, there are a number of configuration items that you will need to provide. The key items are;

  • SourceID is the (currently) five digit ID of a source that you can get from the IdentityNow Portal when looking at the properties of a Source. Or via API as I detailed in this post.
  • OwnerID is the Identity ID for the user you will make the owner. To do that you will need to query IdentityNow for the user (see below for an example)
  • Entitlements
    • In order to get the Entitlements ID(s) to assign to the Access Profile you will need to query the Source. This post here details querying Sources to get Entitlements whereby you can get the ExternalID of Entitlements.

Search for Owner ID Request Object

Here is an example Search Request JSON Object required for the Search User call. Update it for a unique attribute for an Identity to query and return.

Update for your criteria. e.g if you copy the JSON below;

  • create a variable name
    • $requestFilter = ‘JSON snippet content from below’
  • Update the search criteria for your search
    • $newRequestFilter = $requestFilter .Replace(“darren.robinson@customer.com.au”,”yourUser@mydomain.com”)
  • Then search for the user and get the ID of the identity
  • Update
    • Line 2 for your Orgname
    • Line 8 for the user to search for that matches the JSON object from above

Creating an Access Profile

Finally, now that we have the prerequisite information to create an Access Profile we can create it. Modify for your environment based off information retrieved from the processes above. Namely;

  • Line 1 for your Orgname
  • Line 2 for the SourceID associated with the Access Profile
  • Line 3 for the Access Profile Owner’s ID
  • Lines 7-10 for your Access Profile Details
  • Line 14 for the Entitlements
  • Line 19 for the Approver (see below for more details)

Access Profile Approvers

For Approvers you can provide the order for approval. For the approval by the Access Profile Owner and then the Manager use the following when creating the Access Profile in Line 19 above.

  • $accessProfile.add(“approvalSchemes”,”accessProfileOwner, manager”)

Other options are:

  • SourceOwner
  • appOwner
  • Governance Group. See managing Governance Groups here to get the Governance Group ID (GUID format)
    • workgroup: 86929844-3391-4ce2-80ef-760127e15813

Summary

Whilst the creation of an Access Profile via API does require some configuration, if you have multiple to create and you know the criteria it is possible to automate the task. I hope this helps others.

 

Searching and Returning SailPoint IdentityNow Entitlements using the API and PowerShell

Entitlements on IdentityNow Sources can be leveraged for many purposes within IdentityNow. Recently I’ve been looking to automate some Access Profiles that will in-turn have entitlements associated with them.

This post details how to query for Entitlements in IdentityNow using the v3 API and PowerShell.

Prerequisites

You will need to Authenticate to the IdentityNow API. The v3 authentication method is required. I detail the v3 method here. The Headers for the requests detailed in this post use the following variables for the JWT oAuth Token.

My v3token variable is $v3Token so my Authentication Header is then
@{Authorization = “$($v3Token.token_type) $($v3Token.access_token)”; “Content-Type” = “application/json”}

Searching for Entitlements

The Base API URI to search for entitlements is;

https://$($org).api.identitynow.com/cc/api/entitlement/list

You will also need to provide a timestamp and a source for which you want to retrieve entitlements for.

Generating the Timestamp

The timestamp is in Unix format which can be generated in PowerShell like this;

$utime = [int][double]::Parse((Get-Date -UFormat %s))

Getting a list of Sources

I’ve previously described listing IdentityNow Sources in this post and this post. Essentially though you can return a list of all sources by performing a GET request to

https://$($orgName).api.identitynow.com/cc/api/source/list

Obtain the Source ExternalID from the source of  your choice that you then wish to return entitlements for.

Entitlement Results

You can limit the number of entitlements returned by using the limit option. The following will return the first 1000 entitlements for a source starting at 0

&start=0&limit=1000

If the source has more than 1000 then you will need to page the results to return the next 1000 results. Continue until you’ve returned all.

&start=1000&limit=1000

Of course you can just not provide a limit and all entitlements will be returned in a single call.

Finding an Entitlement on a Source

Using the power of PowerShell it is quick to find the Entitlement you want if you know some of the information about it. For referencing an Entitlement when creating an Access Profile via the API you will need the Entitlement ID  e.g

$myEntitlement = $sourceEntitlements.items | Select-Object | Where-Object {$_.displayName -like "*Sydney*"}
$myEntitlement.id

Summary

Using the IdentityNow API and the v3 endpoints we can retrieve entitlements for a Source and quickly locate the entitlement and the entitlement ID for use during automation of IdentityNow tasks such as Access Profile creation.