Workflow to Remove Roles from User When Inactive

Hey All,

I am looking for a way to iterate over requestable Roles (not membership driven) on a user.
The issue I am currently running into is that most of these Roles are on the same source, so i continue to get errors on the removal.
Error: Please contact your administrator Request completed An unexpected error occurred: Identity:[identityID] already locked by wps [ID]
(i have commented out the personal IDs)

I have tried:

  • a Loop with an HTTP Request to Revoke each Requestable Role
  • a Manage Access after a get Role Access

Are there any other ways to get around this so that when an ID goes to Inactive, it will remove the access gracefully.

Thanks in Advance!

Hello @masd1,

It is a bug. please raise a support ticket for it.

Thanks
Sid

1 Like

Hello @masd1

I think there is something wrong. Contact them or raise a ticket

Thanks
Manvitha

The issue is I have raised a ticket and they have told me this is the expected behavior as it is a “multi-threaded” environment.

any other ideas?

Mean while Try below Solutions

  1. Sequential Processing (Role-by-Role with Delay)
    Even if looping, you need to wait until the identity is unlocked before revoking the next role.
    Add a wait or retry mechanism in your loop between revocations (10–30 seconds delay is common).
    After revoking a role, poll the identity’s request status before revoking the next.
    Pseudo Logic:
    bash
    for role in requestableRoles:
    revokeRole(role)
    waitUntilRequestFinishes(identityID) # poll /v3/access-requests or similar

  2. Use IdentityNow Access Request API with a Combined Payload
    Instead of revoking roles one-by-one, bundle all roles into a single access request:
    json
    {
    “type”: “ACCESS_REQUEST”,
    “requestedFor”: {
    “type”: “IDENTITY”,
    “id”: “”
    },
    “operation”: “REMOVE_ACCESS”,
    “items”: [
    {
    “type”: “ROLE”,
    “id”: “roleID_1”
    },
    {
    “type”: “ROLE”,
    “id”: “roleID_2”
    }
    ]
    }
    This avoids locking because it’s one request for the identity, processed atomically.

  3. Use Lifecycle Events or Access Profiles Where Possible
    If you’re driving this from a status change (e.g., ACTIVE → INACTIVE):
    Use IdentityNow lifecycle states and associate access revocation policies with Inactive.
    Avoids needing to manually trigger revocations through API or loop logic.

  4. Retry on Lock Error (WPS Lock Retry Logic)
    If you’re scripting this (e.g., in PowerShell, Python, or JavaScript), implement a retry mechanism on the error:
    Error: Identity:[ID] already locked by wps [ID]
    Retry after 20–30 seconds (or exponential backoff).
    Max out at 3–5 attempts.

  5. Use the /v3/access-requests API to check active requests on the identity before issuing new ones.
    Monitor /beta/identities/{id}/access to verify role status before and after revocation.
    Avoid mixing UI-based requests with API-based ones at the same time on the same identity.

2 Likes

Hi @masd1,

Apologies for overlooking the issue earlier. Upon review, it has come to my attention that this is expected behavior. When multiple deprovisioning actions occur simultaneously, the identity may enter a WPS lock state. This happens because, in a microservice environment, each action must complete before the next one can proceed.

I recommend trying @GK91’s suggestion—adding a wait action after the manage access step. This might help resolve the issue.

Thank you!


Thank You @sidharth_tarlapally - I have tried to run a Loop with the Wait in there, but it seems when a Loop runs, it hits all of the available items in there at once and submits per each. Inside of the Loop, can either you or @GK91 you explain how to add in that wait and retry?

@masd1

Note : manage access operation is not properly configured in this json , please change accordingly .
RevokeRolesonIdentityInactive20250523.json

Thank you

Thanks @sidharth_tarlapally — that workflow only allows for one error, correct?
or is it more recursive?

Yes you are right , it is not recursive . It will wait according to allotted time and reattempt . If it fails again it will send an email

Thank You…
That gets me closer, but unfortunately, we will not know how many roles the person will have so that will become a very long workflow to add in a step every time we find a person with more than allotted for. Appreciate your assistance!