JSONPath nested conditions workaround in Workflow (Complete Work Item)

Hi all,

I’ve a part of workflow that is creating account in a disconnected source and upon creation of the account ISC is creating manual task for the Source Owner. The end goal here is to complete the manual task via http request using this API complete-work-item | SailPoint Developer Community. And this is where I am facing the issue because in the request URL I am providing the following:

https://acme.api.identitynow.com/v3/work-items/{{$.hTTPRequest2.body[?(@.approvalItems[?(@.application == “Emergency Terminations (Test) [source]”)])].id}}

this is working well when the Source Owner have just one task in his queue, but if there are more than 1 tasks this is not working as apparently ISC is not supporting nested conditions in JSONPath or simply I don’t have the knowledge to do it.

The whole setup is the following:

HTTP Request to get the Source:
https://acme.api.identitynow.com/v3/sources/b56714a386425db7c891bd2aea9931

HTTP Request to get the SourceOwner tasks:
https://acme.api.identitynow.com/v3/work-items?ownerId={{$.hTTPRequest1.body.owner.id}}

Result:

{
    "displayName": "Get All Tasks of the Source Owner",
    "result": {
        "body": [
            {
                "approvalItems": [
                    {
                        "account": "A000007",
                        "application": "Emergency Terminations (Test) [source]",
                        "id": "ed0d3aab5a2e45d1be409b7646ce01c6",
                        "name": "groups",
                        "operation": "Create",
                        "state": null,
                        "value": "12345"
                    },
                    {
                        "account": "A000007",
                        "application": "Emergency Terminations (Test) [source]",
                        "id": "bced7d01164c455c86d5042dcd527002",
                        "name": "emgTerminationFlag",
                        "operation": "Create",
                        "state": null,
                        "value": "1"
                    }
                ],
                "completed": null,
                "created": "2025-02-28T14:52Z",
                "description": "Manual Changes requested for User: A000007",
                "form": null,
                "id": "553c28405f904f3faa1b89d7cdf44acb",
                "modified": "2025-02-28T14:52Z",
                "name": null,
                "numItems": null,
                "ownerId": "6ddf3618a4bb44cda87133d680be78b7",
                "ownerName": "661048",
                "remediationItems": [],
                "requesterDisplayName": "Doe, Bobby",
                "requesterId": "5fdd81e8520d4d1faecb4b8d1f39f167",
                "state": "Pending",
                "type": "ManualAction"
            },
            {
                "approvalItems": [
                    {
                        "account": "A000006",
                        "application": "Workflow Testing [source]",
                        "id": "2b5e1ab31safda4da48de7566c8bc16483",
                        "name": "groups",
                        "operation": "Add",
                        "state": null,
                        "value": "8807sa09"
                    }
                ],
                "completed": null,
                "created": "2025-02-28T14:46Z",
                "description": "Manual Changes requested for User: A000006",
                "form": null,
                "id": "a471e7cd5dcf43sa69b02056793857004e",
                "modified": "2025-02-28T14:46Z",
                "name": null,
                "numItems": null,
                "ownerId": "6ddf3618a4bbsa44cda87133d680be78b7",
                "ownerName": "661048",
                "remediationItems": [],
                "requesterDisplayName": "Doe, Bobby",
                "requesterId": "5fdd81e8520dsa4d1faecb4b8d1f39f167",
                "state": "Pending",
                "type": "ManualAction"
            }
        ],
        "headers": {},
        "responseTime": "0.076503 seconds",
        "statusCode": 200
    },
    "stepName": "hTTPRequest2",
    "task": "sp:http",
    "technicalName": "HTTP Request 2"
}

HTTP Request to Complete the Owner Task:
https://acme.api.identitynow.com/v3/work-items/{{$.hTTPRequest2.body[?(@.approvalItems[?(@.application == “Emergency Terminations (Test) [source]”)])].id}}

In the third request if there are more than one tasks in the Source Owner Task Manager, it will return all values for ID ignoring the explicitly defined application in the condition.

I am really new to Sailpoint world and still have to learn a lot, so most probably there is more elegant way to do this in a workflow. Can you guys give me some directions or workarounds in this scenario?

Have a great weekend!

If the task is always in the first position, maybe you could do something like this with only taking first item in the index?

$.hTTPRequest2.body[?(@.approvalItems[0].application==‘Emergency Terminations (Test) [source]’)].id

Thanks, I am going to test it and return with a feedback.

Unfortunately this is not supported either. As a workaround I will write a PowerShell or Python script that will run multiple times a day and close these tasks. Not an elegant solution but at least is automated and the Source Owner will not be obligated to track these requests.

Bummer. Let us know how it turns out!

Working well. I am sending the sanitized code below, didn’t include the functions for the log and connection to ISC as it is a bit sensitive information. Most probably this can be done with the PS SDK from Sailpoint but I haven’t had time to check on this.

# Function to complete work items
function Complete-WorkItem {
    param (
        [string]$WorkItemId,
        [string]$BaseURL,
        [string]$AuthToken
    )

    try {
        $Headers = @{
            "Authorization" = "Bearer $AuthToken"
            "Content-Type"  = "application/json"
        }

        $Uri = "$BaseURL/v3/work-items/$WorkItemId"
        
        Write-Log -Message "Completing WorkItem: $WorkItemId" -Level "INFO" -ModuleName "WorkItemCompletion"
        Invoke-RestMethod -Uri $Uri -Method POST -Headers $Headers
        
        Write-Log -Message "Successfully completed WorkItem: $WorkItemId" -Level "INFO" -ModuleName "WorkItemCompletion"
    }
    catch {
        Write-Log -Message "Failed to complete WorkItem: $WorkItemId. Error: $_" -Level "ERROR" -ModuleName "WorkItemCompletion"
    }
}

# Main script execution

# Define API base URL
$BaseURL = "https://acme.api.identitynow.com"

# Authenticate and retrieve token
    
try {
    $AuthToken = Connect-SailPointAPI -BaseURL $BaseURL
    Write-Log -Message "Authentication Successful"  -ModuleName "WorkItemCompletion"
    

}
catch {

    Write-Log -Message "Authentication failed. No token received." -Level "ERROR" -ModuleName "WorkItemCompletion"

}

# Step 1: Get the Source Owner
try {
    $SourceId = "<SOURCE_ID>"
    $Headers = @{
        "Authorization" = "Bearer $AuthToken"
        "Content-Type"  = "application/json"
    }

    $SourceUri = "$BaseURL/v3/sources/$SourceId"
    $SourceResponse = Invoke-RestMethod -Uri $SourceUri -Method GET -Headers $Headers
    $SourceOwnerId = $SourceResponse.owner.id
    $SourceOwnerName = $SourceResponse.owner.name

    Write-Log -Message "Retrieved Source Owner ID: $SourceOwnerId $SourceOwnerName" -Level "INFO" -ModuleName "GetSourceOwner"
}
catch {

    Write-Log -Message "Retrieved Source Owner ID Failed. Error: $_" -Level "ERROR" -ModuleName "GetSourceOwner"

}

# Step 2: Get all work items where Source Owner is the owner
try {

    $WorkItemsUri = "$BaseURL/v3/work-items?ownerId=$SourceOwnerId"
    $WorkItemsResponse = Invoke-RestMethod -Uri $WorkItemsUri -Method GET -Headers $Headers

    Write-Log -Message "WorkItemsResponse Execution Complete" -Level "INFO" -ModuleName "GetAllWorkItems"

}
catch {

    Write-Log -Message "WorkItemsResponse Retrieval Failed. Error: $_" -Level "ERROR" -ModuleName "GetAllWorkItems" 

}

# Filter tasks where application is of your choice
try {
    $FilteredWorkItems = $WorkItemsResponse | Where-Object {
        $_.approvalItems.application -eq "<APP_TO_FILTER>"
    }

    if (-not $FilteredWorkItems) {

        Write-Log -Message "Filtered Work Items Which Fulfills the Criteria Not Found. Exiting..." -Level "INFO" -ModuleName "GetFilteredWorkItems"
        exit

    }

    Write-Log -Message "Found $($FilteredWorkItems.Count) pending work items for the source owner." -Level "INFO" -ModuleName "GetFilteredWorkItems"

}
catch {

    Write-Log -Message "Filtered Work Items Failed. Error: $_" -Level "ERROR" -ModuleName "GetFilteredWorkItems"

}



# Step 3: Complete each work item
foreach ($WorkItem in $FilteredWorkItems) {
    try{

    Complete-WorkItem -WorkItemId $WorkItem.id -BaseURL $BaseURL -AuthToken $AuthToken
    
    }catch{

    Write-Log "$($WorkItem.id) Work Item Failed to Complete. Error: $_" -Level "INFO" -ModuleName "CompleteWorkItem" 

    }
}

Write-Log -Message "All applicable work items processed." -Level "INFO" -ModuleName "MainScript"
1 Like

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.