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.
Workflow Architecture & Execution Steps
-
Trigger & Account Check:
Trigger the workflow on ISC lifecycle state changes (e.g.,Active→Terminated). Verify whether the identity has an active NERM account. -
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. -
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.
-
-
Update NERM Records via API:
Invoke NERM PATCH/PUT APIs to update thesponsorattribute across all identified non-employee records.
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"
}
}
]
}
]
}
