Workflow to remove roles

I have a workflow that I have configured to remove roles upon moving to the inactive lifecycle state.

However, it appears that my workflow is failing within the loop step with the error message containing “child workflow execution error task failed: activity error. request failed: 400 - 400 Bad Request. type: sp:access:manage.” I have cross referenced with another workflow here and verified that mine is similar. Does anyone know what I am doing incorrectly in my workflow configuration?

{
	"name": "Remove Access - Lifecycle State moved to Inactive",
	"description": "",
	"definition": {
		"start": "Get Identity",
		"steps": {
			"Compare Strings": {
				"choiceList": [
					{
						"comparator": "StringEquals",
						"nextStep": "Get Access",
						"variableA.$": "$.trigger.changes[?(@.attribute == 'cloudLifecycleState')].newValue",
						"variableB": "inactive"
					}
				],
				"defaultStep": "End Step — Success",
				"displayName": "Lifecycle State is inactive?",
				"type": "choice"
			},
			"End Step — Success": {
				"type": "success"
			},
			"Get Access": {
				"actionId": "sp:access:get",
				"attributes": {
					"accessprofiles": false,
					"entitlements": false,
					"getAccessBy": "specificIdentity",
					"identityToReturn.$": "$.getIdentity.id",
					"roles": true
				},
				"displayName": "Get Roles",
				"nextStep": "Loop",
				"type": "action",
				"versionNumber": 1
			},
			"Get Identity": {
				"actionId": "sp:get-identity",
				"attributes": {
					"id.$": "$.trigger.identity.id"
				},
				"description": "Get the identity whose lifecycle state changed",
				"nextStep": "Compare Strings",
				"type": "action",
				"versionNumber": 2
			},
			"Loop": {
				"actionId": "sp:loop:iterator",
				"attributes": {
					"input.$": "$.getAccess.accessItems",
					"start": "Manage Access",
					"steps": {
						"End Step - Success": {
							"displayName": "",
							"type": "success"
						},
						"Manage Access": {
							"actionId": "sp:access:manage",
							"attributes": {
								"comments": "User is now inactive, removing all roles.",
								"removeDuration": null,
								"removeIdentity.$": "$.getIdentity.id",
								"requestType": "REVOKE_ACCESS",
								"requestedItems.$": "$.loop.loopInput"
							},
							"displayName": "Remove Roles",
							"nextStep": "End Step - Success",
							"type": "action",
							"versionNumber": 1
						}
					}
				},
				"displayName": "",
				"nextStep": "End Step — Success",
				"type": "action",
				"versionNumber": 1
			}
		}
	},
	"creator": {
		"type": "IDENTITY",
		"id": "",
		"name": ""
	},
	"trigger": {
		"type": "EVENT",
		"attributes": {
			"attributeToFilter": "cloudLifecycleState",
			"description": "Triggers when cloudLifecycleState identity attributes change.",
			"filter.$": "$.changes[?(@.attribute == \"cloudLifecycleState\")]",
			"id": "idn:identity-attributes-changed"
		}
	}
}

Hi @dominick-miller ,

You are doing it all wrong while designing the workflow. It is flawed from the first step. I looked at your workflow and found that you are pulling all the identities regardless of the value of ‘cloudLifecycleState.’ This is problematic because your workflow is triggering for undesired identities as well. Instead, you should filter those identities whose attribute value has changed to ‘Inactive.’

$.changes[?(@.attribute == "cloudLifecycleState" && @.newValue=="Inactive")]

That way you are not pulling unnecessary identity and you also don’t need comparison step that you are using. And that filter will trigger workflow only for desired identities.

And what you are doing wrong in the “Manage Access” step is that you are not passing the id. You should pass id of the access item to manage.

$.loop.loopInput.id

I hope that helps.
Let me know if you have any more questions.
Thanks.

Hi @dominick-miller,

If you are planning to revoke all the roles, you don’t necessarily need a loop operator.

A Get Access Action along with a Manage Access Action should remove all the roles.

Attached is a sample workflow you can try.

RemoveAccessLifecycleStatemovedtoInactive.json (1.5 KB)

And as of your original workflow, you seem to have missed the loop context part.

Context inside the loop :

Use the Loop context in the remove roles action to get the identity id :

Hi @jesvin90, have you verified that this workflow works? I have tried your example exactly as provided and keep receiving the following error message:

{
        "type": "ActivityTaskFailed",
        "timestamp": "2024-06-13T19:56:51.610140662Z",
        "attributes": {
            "displayName": "Manage Access",
            "error": "request failed: 400 - 400 Bad Request:  (type: HTTP Response Returned a Client Error, retryable: false): request failed: 400 - 400 Bad Request",
            "stepName": "manageAccess",
            "task": "sp:access:manage"
        }
    }

I was able to get your provided workflow working by adding a wait immediately after the trigger. The issue I was seeing is due to a race condition between the workflow trying to remove roles and roles automatically getting unassigned upon the lifecycle state moving to inactive. By adding a wait, the automatic unassignment occurs first and the workflow cleans up by removing the roles that are left on the identity (requested roles).

Hi @dominick-miller,

Glad to know that it worked for you.

And yes, since the birthright roles cannot be revoked via workflows, keeping a wait operation before the role removal operation does the trick.

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