Workflow to remove access by identity based on special conditions

Problem

Sometimes, it is desirable to remove access to an identity based on special criteria. For example, you may only wish to remove all entitlements from a JDBC source for an identity that has changed departments. Using the “Get Access” and “Manage Access” actions will not work in this scenario since “Get Access” does not have the ability to filter access for an identity based on arbitrary criteria, like source name. Instead, you have to use the HTTP Request action to manually invoke the search API and the submit access request API, and then use a loop to apply the special filter criteria to revoke access that meets your criteria.

The Workflow

This workflow will allow you to filter access items from a search query by applying custom filter criteria with a JSONpath expression.

HTTP Request to search for identity access items

The first HTTP Request will execute a search query to get all access items that belong to the identity whose attributes changed. You will need to update the client ID, client secret, and tenant URL for this action to work in your environment.

Filter criteria in the loop

Next, you will need to use a JSONpath expression to specify which access items you want to include in your access requests. The sample workflow script already has an example filter expression as follows:

$.hTTPRequest.body[0].access[?(@.type == "ENTITLEMENT" && @.source.name == "My Source")]

This expression will filter out any access item that is an entitlement and that belongs to the source “My Source”, and it will send these access items to the loop to be included in the access request. You can change this JSONpath expression as needed to fulfill your filter criteria.

HTTP Request to submit an access request

Each access item will invoke a single access request to revoke the access. The HTTP Request is already configured with the proper request body to revoke each item in the loop. All you need to do is update the client ID, client secret, and tenant URL. If you want to grant access instead, just change the REQUEST_TYPE in the request body to GRANT_ACCESS.

Workflow script

Here is the workflow script to get you started. Download this script to your computer, upload it to your workflow environment, and update the steps according to your needs and environment.

Revokeentitlementsbysource20230707.json (2.3 KB)

10 Likes

Hello I am trying to do something similar. I am unable to download the JSON path can you assist I need help configuring the HTTP Requests. I am looking at the documentation, but I still have some questions

1 Like

Hi Dawn. Why are you unable to download the JSON file? Is it being blocked by your company?

1 Like

I can share you the error

1 Like

I updated the JSON file to hopefully fix that error. Try download it again and uploading it to your workflow.

2 Likes

Thank you so much it works!

2 Likes

Hey @colin_mckibben,

Appreciate this workflow example. Do you have any suggestions for how to handle if that user has more than 100 entitlements in the filtered source? My understanding is the loop is limited to 100 and we have some cases where a user may have many more than just 100 in a specific source.

I thought about checking and looping again if any were found, but I felt like that may have pitfalls depending on how long it takes to remove entitlements. Or in AAD’s case where it also recognizes on-prem groups as entitlements, it would still report back entitlements it can’t remove.

Appreciate any insight you may have.

1 Like

If you have more than 100 items, you can look into using recursion, as described in this blog post.

This blog offers a more practical example of recursion in action.

1 Like

@colin_mckibben Appreciate this!

I’m trying to proof of concept this using a combination of this workflow and the recursive one. The step I’m running into issues trying to think through is how to pass the filtered criteria (example: $.hTTPRequest.body[0].access[?(@.type == “ENTITLEMENT” && @.source.name == “My Source”)]) to the external trigger since the HTTP request action doesn’t seem to convert this into something json friendly, along with the identity id for the loop in the child workflow. Would appreciate if you have any thoughts/insights.

Ah, therein lies the catch. I have not found a way to pass in additional context to recursive workflows, like an identity ID, so recursion probably won’t work in this case. I describe that caveat in the “pros and cons” section:

The simplest approach may very well be to have multiple loops. If you think you will never have an identity with more than 1,000 entitlements, then you would need 10 loops to process each set of 100 entitlements.

1 Like

Hi @colin_mckibben ,

I need to implement this functionality as i’m getting this while revoking entitlements in a a loop:

“Err: Input has 116 iterations which exceed 100 iteration limit”.

Can you show me an example of using 2 or more loops to go through array bigger than 100 elements? I’m trying to find a way to filter/limit entitlements returned by getAccess but i can’t find this kind of functionality in JsonPath.

@maciej_itrun, it looks like JSONpath can’t select a slice of data from a filtered array. If you have more than 100 access items to process, then you could look into a more advanced Search query. For example, this search query will return all access items for the given identity that come from the source “airtable v4” and are of type “ENTITLEMENT”.

{
    "indices": [
        "identities"
    ],
    "query": {
        "query": "id:2c9180867624cbd7017642d8c8c81f67",
        "innerHit": {
            "type": "access",
            "query": "source.name.exact:\\\"airtable v4\\\" AND type:ENTITLEMENT"
        }
    }
}

This will return an array of access items.

[
    {
        "privileged": false,
        "displayName": "User",
        "name": "User",
        "standalone": false,
        "id": "439ede5a1cd342d09a924e696f177f69",
        "source": {
            "name": "airtable v4",
            "id": "c6dc37bf508149b28ce5b7d90ca4bbf9"
        },
        "attribute": "entitlements",
        "requestable": false,
        "type": "ENTITLEMENT",
        "value": "user",
        "_type": "access",
        "_originalType": "identity",
        "_version": "v7"
    }
]

Now you can use JSONpath array slicing to break this array into 100 item chunks and feed them into each loop. For example, let’s say the above query returns 116 access items. The input for the first trigger will be $.hTTPRequest.body[:100]. For the second loop, it will be $.hTTPRequest.body[100:200]. And so on.

Is there a benefit of doing this instead of increasing the limit for the loop operator?
Seems to just add more work in configuring and testing the workflows, the same number of operations will be executed in the end.

Increasing loop limits is being considered by product. There are performance implications to increasing the limit, but there’s a possibility the limits will be raised in the future. Until the limits are increased, the methods that I describe above are how users can workaround these limits for now.