Generic Workflow to Auto-Approve/Reject an access request

This workflow will auto-Approve/reject an access request based on some access request attributes. In situations where the access request doesn’t meet the workflow use-case, the request will be kept assigned to the individual for approval.

Why did we build this workflow?

We wanted a way to show automated governance, which is possible with SailPoint workflows and APIs.

In reality, some requests should be automatically approved based on some access request attributes like requester, requestFor, approver or accessItem. This workflow also allows the approvers to focus on the higher risk requests and not be burdened by the low-risk or pre-define approved requests.

What is the high-level design?

This solution is implemented as a workflow process: The workflow’s trigger is Scheduled Trigger (runs automatically based on CRON setting).

The workflow runs on an hourly schedule. It retrieves all pending approvals in the IdentityNow tenant, and then loops over the ones as per the defined condition in the loop node. The loop simply calls the Approve Access Request node, passing details of the request approval id, then approves it and with a comment.

Be aware of Workflow Limitations

  • As of August '23, a workflow loop only supports 100-items.
    • If you had > 100 pending approvals, some won’t be processed when the workflow runs. This isn’t an issue in demos, but something to remember.
  • As of August '23, the fastest a scheduled workflow can run every 1-hours.
    • In production, this could factor into the #-pending approvals, which could accumulate > 100
    • In demos, you can either update the CRON statement (in the Scheduled Trigger of the master workflow) so it runs at about the right time in your demo, or you can run it manually in test mode after creating the access requests.
  • Visibility into the loop/executions isn’t great.

Deploying Instructions

Note: Deploy on your sandbox tenant first, then perform all the testing and validate all the sandbox testing results before moving the workflow to the production.

  1. Download the Workflow json files (see below)
  2. Log into IdentityNow with Admin rights and create a Personal Access Token (PAT). In the PAT, assign the scope sp-scopes-all. This client ID/secret pair will be needed for all API calls in the child workflow.
  3. Upload the Workflow json files into your IdentityNow tenant
  4. Edit the workflow in the Workflow Builder
  5. Update the schedule trigger with a proper Cron value as per the business need
  6. Change the HTTPRequest API URLs for the API calls to refer to your IdentityNow tenant
  7. Change the Client ID/Secret values (for the API calls) to use your PAT token.
  8. Update the loop list filter with the object.id and its value:
    1. Objects can be:
    1. requester.ID
    2. requestFor.id
    3. owner.id
    4. requestObject.id
  9. Update the Compare String node with the loop input object and its value as in the previous step
  10. Enable the workflow

Test Steps

  1. Generate a Test Execution for the workflow.
  2. Edit the workflow (select the workflow name and then press [Edit in Builder])
  3. On the workflow details page, press [Test Workflow]
  4. In the Workflow Test Input text area, replace the default text with the following text:
  5. {}
  6. Verify the results
  7. Check the status of requests items for auto-approved and the comment.

Screen shots from the approved request in IdentityNow:

Here are the workflow definition file : “Access Requests Auto-Approve/Reject Workflow"
Access Requests Auto-approval Workflow.json (2.5 KB)

5 Likes

Great content @Bassem_Mohamed thank you for sharing!

3 Likes

Can this workflow be used to auto-reject access request older than 60 days?

Hi @johnpaul_tran,
yes, you can use the same workflow just need to change the loop input to
$.hTTPRequest.body to get all the pending access requests and replace the compare string with compare date to compare the request creation $.loop.loopInput.requestCreated with Is Before X days ago where x = 90 days

Please, keep in mind the workflows loop limitations.

1 Like

Great content @Bassem_Mohamed, I have enabled this workflow in our SandBox and how to know if the workflow running or not? I have setup scheduled time but it seems nothing happen at scheduled time.

1 Like

Hi @dongrenfei, you can go to admin → Workflows then Click on the workflow and go to Executions tab, there you can check if the workflow was executed successfully or failed, Also you can download a report with the workflow processing

Please, let me know if it’s not clear.

1 Like

@Bassem_Mohamed - Is it possible to use requiredComment in a compare string. I have updated above code but it’s not entering into Loop.

{
“name”: “Auto-approved Requests testing”,
“description”: “Testing Auto-Approve WF”,
“modified”: “2024-02-15T15:40:24.783849721Z”,
“modifiedBy”: {
“type”: “IDENTITY”,
“id”: “495aa92b91xxxxxxxxxxxxxxxxxxxx”,
“name”: “hxxxxxxx”
},
“definition”: {
“start”: “HTTP Request”,
“steps”: {
“End Step — Success”: {
“type”: “success”
},
“HTTP Request”: {
“actionId”: “sp:http”,
“attributes”: {
“authenticationType”: “OAuth”,
“jsonRequestBody”: {
“input”: “{{$.loop.loopInput}}”
},
“method”: “get”,
“oAuthClientId”: “f6exxxxxxxxxxxxxxxxxxxxxxxxx”,
“oAuthClientSecret”: “$.secrets.d571f33xxxxxxxxxxxxxxxxxxxxx”,
“oAuthCredentialLocation”: “oAuthInHeader”,
“oAuthScope”: null,
“oAuthTokenUrl”: “https://coxxxxx-dev.api.identitynow.com/oauth/token”,
“requestContentType”: “json”,
“requestHeaders”: {
“Accept”: “application/json”
},
“url”: “https://coxxxxx-dev.api.identitynow.com/v3/access-request-approvals/pending”
},
“nextStep”: “Loop”,
“type”: “action”,
“versionNumber”: 2
},
“Loop”: {
“actionId”: “sp:loop:iterator”,
“attributes”: {
“input.$”: “$.hTTPRequest.body[?(@.requesterComment == “Request submitted by the Role Access Management Tool”)]”,
“start”: “Compare Strings”,
“steps”: {
“Approve Access Request”: {
“actionId”: “sp:approve-request”,
“attributes”: {
“approvalId.$”: “$.loop.loopInput.id”,
“comment”: “Auto-Approved by the Workflow”
},
“nextStep”: “End Step — Success 1”,
“type”: “action”,
“versionNumber”: 1
},
“Compare Strings”: {
“choiceList”: [
{
“comparator”: “StringEquals”,
“nextStep”: “Approve Access Request”,
“variableA.$”: “$.loop.loopInput.requesterComment”,
“variableB”: “Request submitted by the Role Access Management Tool”
}
],
“defaultStep”: “End Step — Success 2”,
“type”: “choice”
},
“End Step — Success 1”: {
“type”: “success”
},
“End Step — Success 2”: {
“type”: “success”
}
}
},
“description”: null,
“nextStep”: “End Step — Success”,
“type”: “action”,
“versionNumber”: 1
}
}
},
“creator”: {
“type”: “IDENTITY”,
“id”: “495aaxxxxxxxxxxxxxxxxxxxx”,
“name”: “hgxxxxx”
},
“trigger”: {
“type”: “SCHEDULED”,
“attributes”: {
“cronString”: “10 21 * * *”,
“frequency”: “cronSchedule”,
“timeZone”: “Asia/Calcutta”
}
}
}

Thanks,
Harish G

Great Content.
Thanks for sharing @Bassem_Mohamed

1 Like

Hi @harishhaleon, I think you json filter is not correct, Can you please try this json filter?

$.hTTPRequest.body.requesterComment[?(@.comment == “Request submitted by the Role Access Management Tool”)]

1 Like

Thanks @Bassem_Mohamed for sharing. We a similar use case and we want to auto approve the manual sources provisioning tasks.

1 Like

Yes, It worked. Thank you!

1 Like

This is very useful content.
Great Work

1 Like