Handling Non-Employee Data in Sponsor Termination: A Workflow Template

Problem

When an internal employee or non-employess who acts as a sponsor is terminated or leaves active status (on-Leave, terminated, etc), their associated non-employee accounts risk becoming orphaned. Without an active sponsor assigned in Non-Employee Risk Management (NERM), organizations face governance gaps, unmonitored third-party access, and blocked lifecycle or certification actions.

Diagnosis

In environments integrating Identity Security Cloud (ISC) and NERM, sponsor assignments are typically stored as static attributes on non-employee records. When an identity’s lifecycle state transitions out of active status in ISC:

  • No Default Auto-Reassignment: NERM does not automatically inherit or reassign sponsorship upon employee termination without explicit logic.

  • Manager Role Constraints: The departing sponsor’s direct manager may not possess an active NERM account or the requisite Sponsor permissions to inherit the accounts automatically.

  • Data Inconsistencies: Manual reassignment processes are error-prone and frequently result in unassigned contractor records.

Solution

Implement an automated ISC Workflow and Form pattern integrated with NERM APIs triggered whenever a sponsor’s lifecycle state changes from active to any other state.

:gear: Workflow Architecture & Execution Steps

  1. Trigger & Account Check:
    Trigger the workflow on ISC lifecycle state changes (e.g., Active → Terminated). Verify whether the identity has an active NERM account.

  2. Retrieve Sponsored Assignments:
    Query NERM to fetch all active non-employee assignments where the terminated identity is designated as the sponsor. If no assignments are found, gracefully end the workflow.

  3. Manager Validation & Interactive Form Fallback:
    Check whether the identity’s manager has a valid NERM account with the Sponsor role:

    • If valid: Automatically designate the manager or route for confirmation.

    • If invalid/missing role: Send an ISC Form to the manager prompting them to select a qualified replacement sponsor who already holds the Sponsor role.

  4. Update NERM Records via API:
    Invoke NERM PATCH/PUT APIs to update the sponsor attribute across all identified non-employee records.

:light_bulb: Implementation Note: This serves as a baseline template. Ensure authentication (OAuth/PAT), API endpoint URLs, tenant IDs, and profile-type schema mappings are updated to match your specific environment, along with any business requirements for sponsor handling.

ISC Workflow:

{
	"definition": {
		"start": "Compare Strings",
		"steps": {
			"Compare Strings": {
				"actionId": "sp:compare-strings",
				"choiceList": [
					{
						"comparator": "StringDoesNotEquals",
						"nextStep": "Get Identity",
						"variableA.$": "$.trigger.changes[?(@.attribute == \"cloudLifecycleState\")].newValue",
						"variableB": "active"
					}
				],
				"defaultStep": "End Step - Success",
				"displayName": "",
				"type": "choice"
			},
			"Compare Strings 1": {
				"actionId": "sp:compare-strings",
				"choiceList": [
					{
						"comparator": "StringMatches",
						"nextStep": "Loop",
						"variableA.$": "$.defineVariable1.managerNeUserId",
						"variableB": "-"
					}
				],
				"defaultStep": "Form",
				"displayName": "",
				"type": "choice"
			},
			"Compare Strings 2": {
				"actionId": "sp:compare-strings",
				"choiceList": [
					{
						"comparator": "StringEquals",
						"nextStep": "End Step - Success 5",
						"variableA.$": "$.hTTPRequest.body.error",
						"variableB": "no user profiles found"
					}
				],
				"defaultStep": "Get Accounts 1",
				"displayName": "No profiles found?",
				"type": "choice"
			},
			"Define Variable": {
				"actionId": "sp:define-variable",
				"attributes": {
					"id": "sp:define-variable",
					"variables": [
						{
							"description": "",
							"name": "neUserId",
							"transforms": [],
							"variableA.$": "$.getAccounts.accounts[?(@.sourceName==\"User Source\")].nativeIdentity"
						}
					]
				},
				"displayName": "Get nativeIdentity for NE user account",
				"nextStep": "Verify Data Type",
				"type": "Mutation"
			},
			"Define Variable 1": {
				"actionId": "sp:define-variable",
				"attributes": {
					"id": "sp:define-variable",
					"variables": [
						{
							"description": "",
							"name": "managerNeUserId",
							"transforms": [],
							"variableA.$": "$.getAccounts1.accounts[?(@.sourceName==\"User Source\")].nativeIdentity"
						}
					]
				},
				"displayName": "Get NE user id for manager",
				"nextStep": "Compare Strings 1",
				"type": "Mutation"
			},
			"Define Variable 2": {
				"actionId": "sp:define-variable",
				"attributes": {
					"id": "sp:define-variable",
					"variables": [
						{
							"description": "",
							"name": "managerNeUserId",
							"transforms": [],
							"variableA.$": "$.getAccounts2.accounts[?(@.sourceName==\"User Source\")].nativeIdentity"
						}
					]
				},
				"displayName": "Define managerNeUserId",
				"nextStep": "Loop 1",
				"type": "Mutation"
			},
			"End Step - Success": {
				"actionId": "sp:operator-success",
				"displayName": "",
				"type": "success"
			},
			"End Step - Success 1": {
				"actionId": "sp:operator-success",
				"displayName": "",
				"type": "success"
			},
			"End Step - Success 2": {
				"actionId": "sp:operator-success",
				"displayName": "",
				"type": "success"
			},
			"End Step - Success 5": {
				"actionId": "sp:operator-success",
				"displayName": "",
				"type": "success"
			},
			"Form": {
				"actionId": "sp:forms",
				"attributes": {
					"deadline": "1d",
					"formDefinitionId": "79c85f30-029b-41f8-8572-7a5f2389a6ec",
					"inputForForm_originalSponsorName.$": "$.trigger.identity.name",
					"notificationBody": "Open the following form to select a valid sponsor for the non-employees currently reporting to {{$.trigger.identity.name }} that has been inactivated.",
					"notificationSubject": "Reassign Non-Employees",
					"recipient.$": "$.getIdentity.managerRef.id",
					"reminder": "1d"
				},
				"displayName": "Send form to ask for new sponsor",
				"nextStep": "Get List of Identities",
				"type": "action",
				"versionNumber": 1
			},
			"Get Accounts": {
				"actionId": "sp:get-accounts",
				"attributes": {
					"getAccountsBy": "specificIdentity",
					"identity.$": "$.trigger.identity.id"
				},
				"displayName": "",
				"nextStep": "Define Variable",
				"type": "action",
				"versionNumber": 1
			},
			"Get Accounts 1": {
				"actionId": "sp:get-accounts",
				"attributes": {
					"getAccountsBy": "specificIdentity",
					"identity.$": "$.getIdentity.managerRef.id"
				},
				"displayName": "Get manager account",
				"nextStep": "Define Variable 1",
				"type": "action",
				"versionNumber": 1
			},
			"Get Accounts 2": {
				"actionId": "sp:get-accounts",
				"attributes": {
					"filterCriteria": "identityId",
					"getAccountsBy": "specificIdentity",
					"identity.$": "$.getListOfIdentities.identities[0].id",
					"operator": "eq",
					"value": null
				},
				"displayName": "Get Accounts for new sponsor",
				"nextStep": "Define Variable 2",
				"type": "action",
				"versionNumber": 1
			},
			"Get Identity": {
				"actionId": "sp:get-identity",
				"attributes": {
					"id.$": "$.trigger.identity.id"
				},
				"displayName": "",
				"nextStep": "Get Accounts",
				"type": "action",
				"versionNumber": 2
			},
			"Get List of Identities": {
				"actionId": "sp:get-identities",
				"attributes": {
					"inputQuery": "name: {{$.form.formData.newSponsor}}",
					"searchBy": "searchQuery"
				},
				"displayName": "Get Identity for selected sponsor",
				"nextStep": "Get Accounts 2",
				"type": "action",
				"versionNumber": 2
			},
			"HTTP Request": {
				"actionId": "sp:http",
				"attributes": {
					"method": "get",
					"param_authenticationRef": "oauth",
					"param_oauth": {
						"mapping": {
							"auth_client_id": "clientId",
							"auth_client_secret": "clientSecret",
							"auth_credential_location": "credentialLocation",
							"auth_token_url": "tokenURL"
						},
						"paramID": "efbd8474-4663-40a2-b213-898b7d5bda99",
						"paramType": "1.4",
						"refID": "ebbcf4a8-f7f6-4ebb-9eb0-ccc3bb60bbd4"
					},
					"param_oauth_scopes": {
						"mapping": {
							"auth_scopes": "scopes"
						},
						"paramType": "3.1"
					},
					"requestHeaders": {
						"Accept": "application/json",
						"Content-Type": "application/json"
					},
					"url": "https://TENANT_URL/api/user_profiles",
					"urlParams": {
						"metadata": "true",
						"ne_attribute_id": "9729c9f0-d338-4db4-92a1-b37315738b86",
						"user_id": "{{ $.defineVariable.neUserId }}"
					}
				},
				"description": "call ne for list of profiles that identity is the sponsor for",
				"displayName": "UPDATE: Get profiles that user is a sponsor",
				"nextStep": "Compare Strings 2",
				"type": "action",
				"versionNumber": 3
			},
			"Loop": {
				"actionId": "sp:loop:iterator",
				"attributes": {
					"context.$": "$.defineVariable1",
					"input.$": "$.hTTPRequest.body.user_profiles[*].profile_id",
					"start": "HTTP Request 1",
					"steps": {
						"End Step - Success 3": {
							"actionId": "sp:operator-success",
							"displayName": "",
							"type": "success"
						},
						"HTTP Request 1": {
							"actionId": "sp:http",
							"attributes": {
								"jsonRequestBody": {
									"profile": {
										"attributes": {
											"sponsor": "{{$.loop.context.managerNeUserId}}"
										}
									}
								},
								"method": "patch",
								"param_authenticationRef": "oauth",
								"param_oauth": {
									"mapping": {
										"auth_client_id": "clientId",
										"auth_client_secret": "clientSecret",
										"auth_credential_location": "credentialLocation",
										"auth_token_url": "tokenURL"
									},
									"paramID": "efbd8474-4663-40a2-b213-898b7d5bda99",
									"paramType": "1.4",
									"refID": "ebbcf4a8-f7f6-4ebb-9eb0-ccc3bb60bbd4"
								},
								"param_oauth_scopes": {
									"mapping": {
										"auth_scopes": "scopes"
									},
									"paramType": "3.1"
								},
								"requestContentType": "json",
								"requestHeaders": {
									"Accept": "application/json",
									"Content-Type": "application/json"
								},
								"url": "https://TENANT_URL/api/profiles/{{$.loop.loopInput}}"
							},
							"description": "Update Profile",
							"displayName": "UPDATE: Update Profile",
							"nextStep": "End Step - Success 3",
							"type": "action",
							"versionNumber": 3
						}
					}
				},
				"description": "a",
				"displayName": "",
				"nextStep": "End Step - Success 2",
				"type": "action",
				"versionNumber": 1
			},
			"Loop 1": {
				"actionId": "sp:loop:iterator",
				"attributes": {
					"context.$": "$.defineVariable2",
					"input.$": "$.hTTPRequest.body.user_profiles[*].profile_id",
					"start": "HTTP Request 2",
					"steps": {
						"End Step - Success 4": {
							"actionId": "sp:operator-success",
							"displayName": "",
							"type": "success"
						},
						"HTTP Request 2": {
							"actionId": "sp:http",
							"attributes": {
								"jsonRequestBody": {
									"profile": {
										"attributes": {
											"sponsor": "{{$.loop.context.managerNeUserId}}"
										}
									}
								},
								"method": "patch",
								"param_authenticationRef": "oauth",
								"param_oauth": {
									"mapping": {
										"auth_client_id": "clientId",
										"auth_client_secret": "clientSecret",
										"auth_credential_location": "credentialLocation",
										"auth_token_url": "tokenURL"
									},
									"paramID": "efbd8474-4663-40a2-b213-898b7d5bda99",
									"paramType": "1.4",
									"refID": "ebbcf4a8-f7f6-4ebb-9eb0-ccc3bb60bbd4"
								},
								"param_oauth_scopes": {
									"mapping": {
										"auth_scopes": "scopes"
									},
									"paramType": "3.1"
								},
								"requestContentType": "json",
								"requestHeaders": {
									"Accept": "application/json",
									"Content-Type": "application/json"
								},
								"url": "https://TENANT_URL/api/profiles/{{$.loop.loopInput}}"
							},
							"description": "Call update sponsor in NE",
							"displayName": "UPDATE: Update Profile",
							"nextStep": "End Step - Success 4",
							"type": "action",
							"versionNumber": 3
						}
					}
				},
				"displayName": "",
				"nextStep": "End Step - Success 2",
				"type": "action",
				"versionNumber": 1
			},
			"Verify Data Type": {
				"actionId": "sp:compare-unary",
				"choiceList": [
					{
						"comparator": "IsPresent",
						"nextStep": "HTTP Request",
						"variableA.$": "$.defineVariable.neUserId"
					}
				],
				"defaultStep": "End Step - Success 1",
				"description": "does the identity have a ne lifecycle account",
				"displayName": "does identity have ne user account",
				"type": "choice"
			}
		}
	},
	"trigger": {
		"type": "EVENT",
		"attributes": {
			"filter.$": "$.changes[?(@.attribute == \"cloudLifecycleState\")]",
			"id": "idn:identity-attributes-changed",
			"integrationId": null
		}
	},
	"name": "NE Reassign Sponsor",
	"description": "Reassign the sponsor of a non-employee assignment to their manager when the sponsor becomes inactive."
}

ISC Form:

{
    "name": "NE Reassign Sponsor",
    "description": "Used to select a new sponsor for non-employees if an existing sponsor is terminated.",
    "owner": {
        "type": "IDENTITY",
        "id": "{{owner_identity_id}}",
        "name": "{{owner_identity_name}}"
    },
    "usedBy": [],
    "formInput": [
        {
            "id": "originalSponsorName",
            "type": "STRING",
            "label": "originalSponsorName",
            "description": ""
        }
    ],
    "formElements": [
        {
            "id": "1285348169028",
            "elementType": "SECTION",
            "config": {
                "alignment": "LEFT",
                "description": "",
                "formElements": [
                    {
                        "config": {
                            "description": "<p>Select a new sponsor for the non-employees that are currently sponsored by the person who is now inactive.</p>\n<p>If the desired sponsor is not listed, request sponsor access for the person and refresh this page once access is granted.</p>",
                            "label": "Description Field",
                            "showLabel": true
                        },
                        "elementType": "DESCRIPTION",
                        "id": "1301168585512",
                        "key": "",
                        "validations": []
                    },
                    {
                        "config": {
                            "default": "",
                            "description": "",
                            "helpText": "",
                            "label": "Original Sponsor",
                            "placeholder": "",
                            "required": false
                        },
                        "elementType": "TEXT",
                        "id": "669182238043",
                        "key": "originalSponsor",
                        "validations": []
                    },
                    {
                        "config": {
                            "dataSource": {
                                "config": {
                                    "aggregationBucketField": "attributes.uid.exact",
                                    "indices": [
                                        "identities"
                                    ],
                                    "query": "@access(name:\"Sponsor\")"
                                },
                                "dataSourceType": "SEARCH"
                            },
                            "forceSelect": true,
                            "helpText": "",
                            "label": "New Sponsor",
                            "maximum": 1,
                            "placeholder": "",
                            "required": true
                        },
                        "elementType": "SELECT",
                        "id": "433831700613",
                        "key": "newSponsor",
                        "validations": [
                            {
                                "validationType": "DATA_SOURCE"
                            },
                            {
                                "validationType": "REQUIRED"
                            }
                        ]
                    }
                ],
                "label": "New Sponsor",
                "labelStyle": "h2",
                "showLabel": true
            },
            "validations": []
        }
    ],
    "formConditions": [
        {
            "ruleOperator": "AND",
            "rules": [
                {
                    "sourceType": "INPUT",
                    "source": "originalSponsorName",
                    "operator": "NOT_EM",
                    "valueType": "STRING",
                    "value": ""
                }
            ],
            "effects": [
                {
                    "effectType": "SET_DEFAULT_VALUE",
                    "config": {
                        "defaultValueLabel": "originalSponsorName",
                        "element": "669182238043"
                    }
                },
                {
                    "effectType": "DISABLE",
                    "config": {
                        "element": "669182238043"
                    }
                }
            ]
        }
    ]
}

1 Like