Examples of workflows
This section presents grant workflow examples featuring workflow nodes. For detailed information on each node, refer to Workflow nodes.
Application grant workflow
In this example, an administrator wants to create an application grant workflow that:
-
Requires the manager to approve the request.
-
If approved, check what line of business (LOB) the application is in.
-
Based on the LOB, the workflow requires a separate approver to approve the request.
Assumptions
-
Each application has an application owner. You populate this value for each target application.
-
You create an application glossary attribute LOB, and populate the LOB for each application. For this scenario, the LOBs are:
-
Sales
-
Finance
-
Human Resources
-
-
Your end users have a manager assigned to them. An administrator populates this property and isn’t modifiable by the end user.
Example
-
1 Using an Approval node, the manager of the end user must approve the request.
-
2 If approved, a Script node checks the application glossary attribute
lineOfBusiness
(LOB), and sets the outcome based on the LOB of the application. Based off the outcome, a Switch node evaluates the LOB.Click to display LOB script
var content = execution.getVariables(); var requestId = content.get('id'); var requestObj = null; var appId = null; var appGlossary = null; var lob = null; try { requestObj = openidm.action('iga/governance/requests/' + requestId, 'GET', {}, {}); appId = requestObj.application.id; } catch (e) { logger.info("Validation failed: Error reading application grant request with id " + requestId); } try { appGlossary = openidm.action('iga/governance/application/' + appId + '/glossary', 'GET', {}, {}); lob = appGlossary.lineOfBusiness; execution.setVariable("lob", lob); } catch (e) { logger.info("Could not retrieve glossary with appId " + appId + " from application grant request ID " + requestId); }
-
3 If the LOB is:
-
sales
— An Approval node requires members of the roleSales App Approver
to approve the request. -
finance
— An Approval node requires members ot the foleFinance App Approver
to approve the request. -
humanResources
— An Approval node requires members of the roleHuman Resources App Approver
to approve the request. -
null
— An Approval node requires the application owner to approve the request.
-
-
4 If the required approvals are met, a Script node runs a validation check.
Click to display App Grant Validation script
logger.info("Running application grant request validation"); var content = execution.getVariables(); var requestId = content.get('id'); var failureReason = null; var applicationId = null; var app = null; try { var requestObj = openidm.action('iga/governance/requests/' + requestId, 'GET', {}, {}); applicationId = requestObj.application.id; } catch (e) { failureReason = "Validation failed: Error reading request with id " + requestId; } // Validation 1 - Check application exists if (!failureReason) { try { app = openidm.read('managed/alpha_application/' + applicationId); if (!app) { failureReason = "Validation failed: Cannot find application with id " + applicationId; } } catch (e) { failureReason = "Validation failed: Error reading application with id " + applicationId + ". Error message: " + e.message; } } // Validation 2 - Check the user does not already have application granted // Note: this is done at request submission time as well, the following is an example of how to check user's accounts if (!failureReason) { try { var user = openidm.read('managed/alpha_user/' + requestObj.user.id, null, [ 'effectiveApplications' ]); user.effectiveApplications.forEach(effectiveApp => { if (effectiveApp._id === applicationId) { failureReason = "Validation failed: User with id " + requestObj.user.id + " already has effective application " + applicationId; } }) } catch (e) { failureReason = "Validation failed: Unable to check effective applications of user with id " + requestObj.user.id + ". Error message: " + e.message; } } if (failureReason) { logger.info("Validation failed: " + failureReason); } execution.setVariable("failureReason", failureReason);
If any Approval node has the
Reject
outcome, a Script node denies the request.Click to display Reject Request script
logger.info("Rejecting request"); var content = execution.getVariables(); var requestId = content.get('id'); logger.info("Execution Content: " + content); var requestIndex = openidm.action('iga/governance/requests/' + requestId, 'GET', {}, {}); var decision = {'outcome': 'denied', 'status': 'complete', 'decision': 'rejected'}; var queryParams = { '_action': 'update'}; openidm.action('iga/governance/requests/' + requestId, 'POST', decision, queryParams);
-
5 If the If/else node outcome is:
-
validationSuccess
— A Script node provisions the application to the end user.Click to display Auto Provisioning script
logger.info("Auto-Provisioning"); var content = execution.getVariables(); var requestId = content.get('id'); var failureReason = null; try { var requestObj = openidm.action('iga/governance/requests/' + requestId, 'GET', {}, {}); logger.info("requestObj: " + requestObj); } catch (e) { failureReason = "Provisioning failed: Error reading request with id " + requestId; } if(!failureReason) { try { var request = requestObj.request; var payload = { "applicationId": request.common.applicationId, "startDate": request.common.startDate, "endDate": request.common.endDate, "auditContext": {}, "grantType": "request" }; var queryParams = { "_action": "add" } logger.info("Creating account: " + payload); var result = openidm.action('iga/governance/user/' + request.common.userId + '/applications' , 'POST', payload,queryParams); } catch (e) { failureReason = "Provisioning failed: Error provisioning account to user " + request.common.userId + " for application " + request.common.applicationId + ". Error message: " + e.message; } var decision = {'status': 'complete', 'decision': 'approved'}; if (failureReason) { decision.outcome = 'not provisioned'; decision.comment = failureReason; decision.failure = true; } else { decision.outcome = 'provisioned'; } var queryParams = { '_action': 'update'}; openidm.action('iga/governance/requests/' + requestId, 'POST', decision, queryParams); logger.info("Request " + requestId + " completed."); }
-
validationFailure
— A Script node doesn’t provision the application to the end user.Click to display Validation Failure script
var content = execution.getVariables(); var failureReason = content.get('failureReason'); var decision = {'outcome': 'not provisioned', 'status': 'complete', 'comment': failureReason, 'failure': true, 'decision': 'approved'}; var queryParams = { '_action': 'update'}; openidm.action('iga/governance/requests/' + requestId, 'POST', decision, queryParams);
-
Download the JSON file for this workflow here. For information on how to import or export workflows, refer to Workflow UI canvas. |
Entitlement grant workflow
In this example, an administrator wants to create an entitlement grant workflow that:
-
Requires an entitlement owner to approve the request.
-
If approved, check if the entitlement is marked as privileged.
-
If the entitlement is privileged or null, the workflow requires an additional approver, the end user’s manager, to approve the request.
Assumptions
-
Each entitlement has an entitlement owner.
-
You create a boolean entitlement glossary attribute ,
isPrivileged
. For each entitlement, this attribute is populated. -
Your end users have a manager assigned to them. An administrator populates this property and isn’t modifiable by the end user.
Example
-
1 An Approval node requires the entitlement owner to approve the request.
-
2 A Script node checks the value of the entitlement glossary attribute
isPrivileged
and sets outcomes.Click to display the Entitlement Privileged script
var content = execution.getVariables(); var requestId = content.get('id'); var requestObj = null; var entId = null; var entGlossary = null; var entPriv = null; //Check entitlement exists and grab entitlement info try { requestObj = openidm.action('iga/governance/requests/' + requestId, 'GET', {}, {}); entId = requestObj.assignment.id; } catch (e) { logger.info("Validation failed: Error reading entitlement grant request with id " + requestId); } //Check glossary for entitlement exists and grab glossary info try { entGlossary = openidm.action('iga/governance/resource/' + entId + '/glossary', 'GET', {}, {}); entPriv = entGlossary.isPrivileged; execution.setVariable("entPriv", entPriv); } catch (e) { logger.info("Could not retrieve glossary with entId " + entId + " from entitltment grant request ID " + requestId); }
A switch node routes outcomes based off the script. If the outcome is:
-
privileged
ornull
— An additional Approval node requires the end user’s manager to approve the request. -
notPrivileged
— An additional approval isn’t required.
-
-
3 If the required approvals are met, a Script node runs a validation check.
Click to display the Entitlement Grant Validation script
logger.info("Running entitlement grant request validation"); var content = execution.getVariables(); var requestId = content.get('id'); var failureReason = null; var applicationId = null; var assignmentId = null; var app = null; var assignment = null; var existingAccount = false; try { var requestObj = openidm.action('iga/governance/requests/' + requestId, 'GET', {}, {}); applicationId = requestObj.application.id; assignmentId = requestObj.assignment.id; } catch (e) { failureReason = "Validation failed: Error reading request with id " + requestId; } // Validation 1 - Check application exists if (!failureReason) { try { app = openidm.read('managed/alpha_application/' + applicationId); if (!app) { failureReason = "Validation failed: Cannot find application with id " + applicationId; } } catch (e) { failureReason = "Validation failed: Error reading application with id " + applicationId + ". Error message: " + e.message; } } // Validation 2 - Check entitlement exists if (!failureReason) { try { assignment = openidm.read('managed/alpha_assignment/' + assignmentId); if (!assignment) { failureReason = "Validation failed: Cannot find assignment with id " + assignmentId; } } catch (e) { failureReason = "Validation failed: Error reading assignment with id " + assignmentId + ". Error message: " + e.message; } } // Validation 3 - Check the user has application granted if (!failureReason) { try { var user = openidm.read('managed/alpha_user/' + requestObj.user.id, null, [ 'effectiveApplications' ]); user.effectiveApplications.forEach(effectiveApp => { if (effectiveApp._id === applicationId) { existingAccount = true; } }) } catch (e) { failureReason = "Validation failed: Unable to check existing applications of user with id " + requestObj.user.id + ". Error message: " + e.message; } } // Validation 4 - If account does not exist, provision it if (!failureReason) { if (!existingAccount) { try { var request = requestObj.request; var payload = { "applicationId": applicationId, "startDate": request.common.startDate, "endDate": request.common.endDate, "auditContext": {}, "grantType": "request" }; var queryParams = { "_action": "add" } logger.info("Creating account: " + payload); var result = openidm.action('iga/governance/user/' + request.common.userId + '/applications' , 'POST', payload,queryParams); } catch (e) { failureReason = "Validation failed: Error provisioning new account to user " + request.common.userId + " for application " + applicationId + ". Error message: " + e.message; } } } if (failureReason) { logger.info("Validation failed: " + failureReason); } execution.setVariable("failureReason", failureReason);
If any Approval node has the
Reject
outcome, a Script node denies the request.Click to display Reject Request script
logger.info("Rejecting request"); var content = execution.getVariables(); var requestId = content.get('id'); logger.info("Execution Content: " + content); var requestIndex = openidm.action('iga/governance/requests/' + requestId, 'GET', {}, {}); var decision = {'outcome': 'denied', 'status': 'complete', 'decision': 'rejected'}; var queryParams = { '_action': 'update'}; openidm.action('iga/governance/requests/' + requestId, 'POST', decision, queryParams);
-
4 If the If/else node outcome is:
-
validationFlowSuccess
— A Script node provisions the application to the end user.Click to display Auto Provisioning script
logger.info("Auto-Provisioning"); var content = execution.getVariables(); var requestId = content.get('id'); var failureReason = null; try { var requestObj = openidm.action('iga/governance/requests/' + requestId, 'GET', {}, {}); logger.info("requestObj: " + requestObj); } catch (e) { failureReason = "Provisioning failed: Error reading request with id " + requestId; } if(!failureReason) { try { var request = requestObj.request; var payload = { "entitlementId": request.common.entitlementId, "startDate": request.common.startDate, "endDate": request.common.endDate, "auditContext": {}, "grantType": "request" }; var queryParams = { "_action": "add" } var result = openidm.action('iga/governance/user/' + request.common.userId + '/entitlements' , 'POST', payload,queryParams); } catch (e) { failureReason = "Provisioning failed: Error provisioning entitlement to user " + request.common.userId + " for entitlement " + request.common.entitlementId + ". Error message: " + e.message; } var decision = {'status': 'complete', 'decision': 'approved'}; if (failureReason) { decision.outcome = 'not provisioned'; decision.comment = failureReason; decision.failure = true; } else { decision.outcome = 'provisioned'; } var queryParams = { '_action': 'update'}; openidm.action('iga/governance/requests/' + requestId, 'POST', decision, queryParams); logger.info("Request " + requestId + " completed."); }
-
validationFlowFailure
— A Script node doesn’t provision the application to the end user.Click to display Validation Failure script
var content = execution.getVariables(); var failureReason = content.get('failureReason'); var decision = {'outcome': 'not provisioned', 'status': 'complete', 'comment': failureReason, 'failure': true, 'decision': 'approved'}; var queryParams = { '_action': 'update'}; openidm.action('iga/governance/requests/' + requestId, 'POST', decision, queryParams);
-
Download the JSON file for this workflow here. For information on how to import or export workflows, refer to Workflow UI canvas. |
Role grant workflow
In this example, an administrator wants to create a role grant workflow that:
-
Checks the risk level of the role.
-
Based on the risk level, separate approvals are required. Specifically, if the risk level is
high
, send two approvals, in parallel, to the end user’s manager and the role owner.
Assumptions
-
Each role has a role owner.
-
You create a role glossary attribute (string with enumerated value),
riskLevel
, that has the following values:-
low
-
medium
-
high
For each role, this attribute is populated.
-
-
Your end users have a manager assigned to them. An administrator populates this property and isn’t modifiable by the end user.
Example
-
1 A Script node checks the value of the role glossary attribute
riskLevel
and sets outcomes.Click to display Risk Level script
var content = execution.getVariables(); var requestId = content.get('id'); var requestObj = null; var roleId = null; var roleGlossary = null; var riskLevel = null; try { requestObj = openidm.action('iga/governance/requests/' + requestId, 'GET', {}, {}); riskId = requestObj.risk.id; } catch (e) { logger.info("Validation failed: Error reading role grant request with id " + requestId); } try { roleGlossary = openidm.action('iga/governance/role/' + roleId + '/glossary', 'GET', {}, {}); riskLevel = roleGlossary.riskLevel; execution.setVariable("riskLevel", riskLevel); } catch (e) { logger.info("Could not retrieve glossary with roleId " + roleId + " from role grant request ID " + requestId); }
-
2 A Switch node determines the path to take based off the Script node.
-
3 If the risk level is:
-
low
— An Approval node requires either the role owner or the end user’s manager to approve the request. -
medium
— An Approval node requires the role owner to approve the request.
-
-
4 If the risk level is
high
ornull
then:-
A Switch node sends two approval tasks in parallel.
-
An Approval node requires the role owner to approve the request.
-
An Approval node requires the end user’s manager to approve the request.
-
A closing Switch node waits for both approvals before proceeding to provision the role.
-
-
5 If the required approvals are met, a Script node runs a validation check.
Click to display the Role Grant Validation script
logger.info("Running role grant request validation"); var content = execution.getVariables(); var requestId = content.get('id'); var failureReason = null; var roleId = null; var role = null; try { var requestObj = openidm.action('iga/governance/requests/' + requestId, 'GET', {}, {}); roleId = requestObj.role.id; } catch (e) { failureReason = "Validation failed: Error reading request with id " + requestId; } // Validation 1 - Check role exists if (!failureReason) { try { role = openidm.read('managed/alpha_role/' + roleId); if (!role) { failureReason = "Validation failed: Cannot find role with id " + roleId; } } catch (e) { failureReason = "Validation failed: Error reading role with id " + roleId + ". Error message: " + e.message; } } if (failureReason) { logger.info("Validation failed: " + failureReason); } execution.setVariable("failureReason", failureReason);
If any Approval node has the
Reject
outcome, a Script node denies the request.Click to display Reject Request script
logger.info("Rejecting request"); var content = execution.getVariables(); var requestId = content.get('id'); logger.info("Execution Content: " + content); var requestIndex = openidm.action('iga/governance/requests/' + requestId, 'GET', {}, {}); var decision = {'outcome': 'denied', 'status': 'complete', 'decision': 'rejected'}; var queryParams = { '_action': 'update'}; openidm.action('iga/governance/requests/' + requestId, 'POST', decision, queryParams);
-
6 If the If/else node outcome is:
-
validationFlowSuccess
— A Script node provisions the application to the end user.Click to display Auto Provisioning script
logger.info("Auto-Provisioning"); var content = execution.getVariables(); var requestId = content.get('id'); var failureReason = null; try { var requestObj = openidm.action('iga/governance/requests/' + requestId, 'GET', {}, {}); logger.info("requestObj: " + requestObj); } catch (e) { failureReason = "Provisioning failed: Error reading request with id " + requestId; } if(!failureReason) { try { var request = requestObj.request; var payload = { "roleId": request.common.roleId, "startDate": request.common.startDate, "endDate": request.common.endDate, "auditContext": {}, "grantType": "request" }; var queryParams = { "_action": "add" } var result = openidm.action('iga/governance/user/' + request.common.userId + '/roles' , 'POST', payload,queryParams); } catch (e) { failureReason = "Provisioning failed: Error provisioning role to user " + request.common.userId + " for role " + request.common.roleId + ". Error message: " + e.message; } var decision = {'status': 'complete', 'decision': 'approved'}; if (failureReason) { decision.outcome = 'not provisioned'; decision.comment = failureReason; decision.failure = true; } else { decision.outcome = 'provisioned'; } var queryParams = { '_action': 'update'}; openidm.action('iga/governance/requests/' + requestId, 'POST', decision, queryParams); logger.info("Request " + requestId + " completed."); }
-
validationFlowFailure
— A Script node doesn’t provision the application to the end user.Click to display Validation Failure script
var content = execution.getVariables(); var failureReason = content.get('failureReason'); var decision = {'outcome': 'not provisioned', 'status': 'complete', 'comment': failureReason, 'failure': true, 'decision': 'approved'}; var queryParams = { '_action': 'update'}; openidm.action('iga/governance/requests/' + requestId, 'POST', decision, queryParams);
-
Download the JSON file for this workflow here. For information on how to import or export workflows, refer to Workflow UI canvas. |