Introducing IDM Workflow

ForgeRock Identity Management includes an OOTB workflow engine based on BPMN (Business Process Model & Notation). This isn’t unique, most identity management solutions have some form of workflow engine. However in my experience they are typically based on some proprietary technology and/or very painful to work with.

I have recently had to build some workflows for various customer Proof of Concepts and I am really impressed by how quickly you can pull something together so I wanted to write up a blog entry.

So in this blog we are going to use a brand new instance of IDM (installed locally) and create a simple request and approval workflow which we will then test.

I am going to use Eclipse for this, there are other BPMN editors. I am also not going to spend much time talking about BPMN beyond what we need to build a meaningful workflow. Much more information is available here. In the spirit of this blog I am just going to get on with it and walk you through the basic steps to build and test a simple workflow.

Additionally, the workflow samples that ship with IDM are a brilliant place to start. I highly recommend taking a look at them and using them as the basis of your workflows until you get comfortable building them yourself.

Getting Started

I am going to assume you have an installation of ID already, if not check out my IDM beginners series.

IDM ships with a built in version of the Activiti workflow engine: https://www.activiti.org/. We are going to use the free Eclipse Activiti Workflow Designer to build our workflows.

Firstly, download and install the Eclipse IDE.

When you have Eclipse installed, fire it up and navigate to help -> install new software:

Click Add:

Enter the following location: https://www.activiti.org/designer/update/ and press OK.

Wait for the installation process to complete, now that is all out of the way. Lets get started!

Create a New Project

Navigate to File -> New Project:
Then select General -> Project (we do not need an Activiti Project):
Give your project a name:

And press Finish.

Building a New Workflow

Right click on the new project, select New File:
Give it a name similar to the following:

 

.bpmn20.xml is the convention we use for workflow files in IDM.
Finally right click on our new workflow, select Open With and Other…

 

Finally right click on our new workflow, select Open With and Other…

 

And select Activiti Diagram Editor.
Ok, you should now have a blank canvas that looks a bit like this:
Lets get started. First thing we need is a Start Event. Drag one over from the menu on the right and drop it somewhere on the workflow canvas.
Now, we need some workflow steps. As we are building a simple request and approval workflow so we probably need:
  • A step to actually create a request for something (that is actually our StartEvent we just created).
  • A step to gather some information and determine who the request needs to go to for approval.
  • A step for the actual approval.
  • A step for processing the result. Typically you also want to send an email containing the response. In fact, we probably need two steps here, one for success and one for failure.
We will build the workflow steps and connect them together first, before implementing the actual logic. Select a Script Task from the menu on the right and drag it on to our canvas.
You should now have something like this:
We probably want to give our Script Task a name, click on it and give it a new name:
Just replace the Name value with something appropriate:
We also need to make sure that all Script Tasks have script defined so that IDM can parse them successfully. The easiest way to do this is to add a simple logging statement to the task. Select the Process Request task again. then the Main config tab and add some simple script:
Now you can use either javascript or groovy for scripting. I tend to use groovy but that is just personal choice.
java.util.logging.Logger logger = java.util.logging.Logger.getLogger("")
logger.info("SimpleWorkflow - Process Request")
Make sure you save your work.
Now select the Start Event, you should see the following menu:
Click on the Create Connection arrow, but keep the mouse button held down and drag a connection over to our Process Request task. We now have a flow linking the two tasks in sequence:
Next we need a User Task, similar to before select User Task from the menu on the right, drag it into the canvas, give it a name and connect it to the Process Request task.
Ok, now things get a little more complicated, as a request could be either approved or rejected. So we need a Gateway, specifically an Exclusive Gateway:
We also need to new Script Tasks, build the workflow as below:
Remember to add some simple script to Main config for each new task, otherwise parsing of the workflow will fail.
Finally we need an EndEvent:
Put this to the right of the Approved and Rejected tasks, and connect them to it as below:
We now have a basic workflow outline, time to make it actually do something.

Workflow Logic

StartEvent

We are going to start with our StartEvent. What this actually translates to is the form that a user will complete in self service to make their request.
Click on the StartEvent and select the Form tab
 Click New, You should see the following:
Fill it in exactly as I have below then press OK:

 

We should now have an attribute on our form:
Let’s add another one, justification is a common field when making a request, add it in exactly the same way:
One more thing before we test this in IDM. Click somewhere on the canvas until you can edit the process Name.
Change My process to something meaningful like Request with Justification. Make sure you save the workflow.

Testing the Workflow in IDM

Although our workflow isn’t really doing anything yet, this is a good time to quickly test what it looks like in IDM.
Fire up IDM and navigate to the openidm directory, create a new workflow directory:
Now copy the SimpleWorkflow.bpmn20.xml file into the new workflow directory, you should see IDM pick it up in the logs. In fact you will probably see a warning which we will ignore for now.
Login to IDM as a user other than openidm-admin, someone you have created previously, I’m using a user called jbloggs. Remember to login to user self service: http://localhost.localdomain.com:8080/#login/
You should see the dashboard, and our new process!
Click Details and you can see the form we created earlier! You can enter a request and justification but do not hit Start, because right now nothing will happen.

More Workflow Logic

Ok, so we can make a request now, but it doesn’t go to anyone. Let’s fix that, there are a few things to do here. Firstly we need to gather some more information about the requestor for the approver. Select the StartEvent then Main config and set Initiator as “initiatorId”:
Select the Process Request task and enter the following script as groovy into main Config then save your work.
java.util.logging.Logger logger = java.util.logging.Logger.getLogger("")
logger.info("SimpleWorkflow - Process Request " + initiatorId);
// find user
readStartUserFromRepoParams = [_queryId:'for-userName',uid:initiatorId]
qresults = openidm.query('managed/user', readStartUserFromRepoParams)
// get user details
users = qresults.result
execution.setVariable("userId", users[0]._id)
execution.setVariable("userName", users[0].userName)
execution.setVariable("givenName", users[0].givenName)
execution.setVariable("sn", users[0].sn)
execution.setVariable("mail", users[0].mail)
// set approver
execution.setVariable("approverId", "openidm-admin")
All we are doing here is retrieving the user data for the initiating user and setting it as variables in the workflow process. We are also assigning the user who will approve the request (simply as a static Id here but you can easily make this dynamic, for example assign the task to a group or to a manager – I may cover this in a later blog).
A few more steps, we need to set the assignee for the approval task. Select the Approve Request task and enter the following for assignee:
We also need to configure the approval form as below to show the data we just collected:
We also need to add the request fields the user just filled in:
We also need to add an approvalResult, to the form. This field is a little different as it is an enum:
Because this field is an enumeration we need to add some form values for the user to choose, press New:
And configure the Form Value configuration as below and press OK:
Do the same for “rejected”, and you should end up with the following:
Save your work.

Back to IDM

Again, copy the workflow file into IDM. Now logout, login as a user and select the workflow and populate the request:

 

Press Start. All being well you should see confirmation the workflow process has been started. Now log out and log back in as openidm-admin, you should see that there is a request to be approved on the dashboard:
And if you select Details, you can see the request itself and the additional information we put into it, as well as our approval drop down:

However as before do not click Complete just yet, as we need to actually make this do something.

Final Workflow Logic

Back to the workflow editor, lets take a look at the exclusive gateway we added a bit earlier:
So what we need now is some logic, based on the approval result to send the workflow to the right place. Click on the flow to the Approved task:
Take a look at the Main config, and specifically the Condition field:
Enter the following:
${approvalResult=='approved'}
Do something similar for the Rejected flow:
${approvalResult==’rejected’}
You will notice these two conditions are based on the enum we defined earlier, depending on the selection made by the approver we flow will go to either the Approved or Rejected task.
Now lets finish the workflow, select the Approved task and Main config and Script, enter the following:
java.util.logging.Logger logger = java.util.logging.Logger.getLogger("")
logger.info("SimpleWorkflow - Approved")

java.text.SimpleDateFormat formatUTC = new java.text.SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.S'Z'");     
formatUTC.setTimeZone(TimeZone.getTimeZone("UTC"));
requestDate = formatUTC.format(new Date());
               
def requesterNotification = [
   "receiverId":  userId,
   "requesterId" : "",
   "requester" : "",
   "createDate" : requestDate,
   "notificationType" : "info",
   "notificationSubtype" : "",
   "message" : "The access request was accepted"
];
                
openidm.create("repo/ui/notification/", null, requesterNotification)
This bit of script simply uses the IDM notification engine to let the user know that their request has been approved.
Save your work for the last time and copy the work flow into IDM.

Back to IDM for the Last Time

So now, we should have a complete workflow.
Login to IDM as jbloggs and make a request.
Login to IDM as openidm-admin to approve the request.
Finally, log back in as jbloggs and you should see a notification the request has been approved.
And thats it, very basic workflow but hopefully you can begin to see what is possible. In future blogs I’ll look at actually at assigning a role based on the approval and also enabling a request drop down dynamically.

This blog post was first published @ http://identity-implementation.blogspot.no/, included here with permission from the author.

Delegated RBAC CRUD Via Workflow

OpenIDM provides a powerful delegated administration model, for both REST endpoint access and workflow process access.

A simple way to provide scoped access into the IDM functions, is to simply wrap a workflow process around it and then delegate access to that workflow to a certain of group of users.

A basic example could be that of role based access control administration.  The basic create, read, update and delete tasks often associated with object management.  So RBAC-CRUD to save a few letters.

Each CRUD function can be wrapped into a workflow, with access to those workflows then given members of the rbac-admins internal authorization role.

I created 5 workflows, four for the role-admins and 1 for the end user:

role-admins: createRole.bar

 

A simple wrapper that takes two arguments and runs an openidm.create() to create the role.

role-admins: deleteRole.bar

Opposite of create…and does a lookahead using some JS stored within the form HTML to get a list of roles that can be deleted.  Before the openidm.delete() function is called, it clears down the members list first.

role-admins: addRoleToUserTemporal.bar

So we have a role, now we want to add some users.  Again, does a lookahead to create a dynamic select drop down, then free text to add a username.  You could add some checking logic here I guess to make sure the user exists before submission, but I wrap a conditional check in the workflow before I patch the role anyway.

The other attribute is a timer – this is just based on the Activiti Timer element and I’ve set it to take just a time.  In reality you would accept a date, but for demo’s a time is much easier.  So, after the time has been passed, the initial role to user association is reversed, taking the role away.

role-admins: removeRoleFromUser.bar

Simple manual process to remove a role from a user.  Note all the patches in the workflows work against managed/role.  Whilst you can add and remove roles from the managed/user/_id, by using managed/role endpoint, I can restrict the access the role-admins get via access.js more accurately.

openidm-authorized:requestRole.bar

We then have one workflow left – that is available to any user.  Eg it’s a standard end user workflow, and this time for an access request.

This again does a look ahead and performs an approval step before provisioning the role to the user. The default manager approval is in the workflow and remmed out alongside the ability to use any member of the role-admins authorization role.  So you can flip between the two approval journeys.

The use of role-admins leverages the Activiti:Candidate users attribute – eg role-admins could contain 10 users – the approval goes to all 10 and the first one to claim the task can approve.

A couple of points on access.  The workflow access is governed by the ../conf/process-access.json file.  In there add in the pattern of the role _id along with the internal authorization roles that should have access – note internal role and not just managed/role.

The access.js file in the ../script directory also needs updating to allow full control to the managed/role endpoint to the role-admins users.

Code for this set is available here.

Note, thanks should also go to Marek Detko and some code crib from his role collection example.

This blog post was first published @ http://www.theidentitycookbook.com/, included here with permission from the author.

Workflow Approval Via Encrypted Email Links

A common workflow process is often the access request scenario – a user requires access to something, and that something requires an approval before the provisioning can be completed. Typically this is done via notifications, a dashboard and perhaps an email notifying the approver that they have a task that requires their attention.

However, what if the approver doesn’t want to, or cannot, access their dashboard to approve the request?  An alternative is to embed workflow approval questions into an email, with fully self-contained links that contain encrypted payloads to approve or reject the request. (NB a further extension to this is to be able to respond to workflow requests directly via email / SMTP).

A way to do this is to simply send an email during the workflow instantiation that contains links to approve or reject the request.  But how can those links be securely created to avoid tampering, replay and misuse?  There a few neat steps in the ForgeRock platform that can simply come to the rescue. (NB this assumes that the email traffic / account is secure, which might not be the case…!).

My use case will look like something like this:

  1. Helpdesk operator requests access to impersonate an end user for a set period of time – say 5 minutes
  2. The end user will receive an email notification with two links – Approve or Reject
  3. Each link will go to two specific OpenIDM custom endpoints – ../endpoint/approveImpersonation or ../endpoint/rejectImpersonation
  4. Each endpoint will take a ?payload= argument that will contain an encrypted value
  5. That encrypted value will be contain the end user’s Id and a unique reference to their workflow task instance
  6. As every request into OpenIDM needs to be authenticated, we’ll route the request via OpenIG to add in an authentication header
  7. The custom endpoints will verify the payload, decrypt, find the appropriate workflow task instance and complete the workflow request task
  8. If approved…the workflow will provision the end users Id into the helpdesk operators account under an attribute called impersonationId
  9. The workflow will then suspend and return n-minutes later, based on the time selected in step 1 and deprovision the attribute in step 8.
The architecture at a high level looks something like this:

The main element of this is the workflow.  This is a simple access request style workflow with two interesting components. First is the sending of an email with the two links – both of which are encrypted using the openidm.encrypt function. The second is a time boundary that removes any changes the workflow makes after a selected time window.  The encrypted email payload contains a unique reference that is attached to the task instance.  The unique reference is created using the openidm.hash function, that takes the requester Id, requestee Id and the current time in ms.

To trigger the workflow, the enduser and a time element are entered.

This triggers the sending of the notification email with the two links.

The end user simply selects the appropriate link.  The link automatically redirects via IG to snowball the appropriate authentication headers and completes against the OpenIDM endpoint.

The endpoint verifies the payload argument exists, that the encrypted value is in tact, decrypts, finds the appropriate workflow task, compares the two hashed verification codes and completes the appropriate approve or reject action.

The workflow then contains an intermediate timer event that is used to act as a stop watch – to basically reverse any changes that are made, acting like a temporal condition.

<intermediateCatchEvent id=”timer”>
<timerEventDefinition>
<timeDuration>PT${lengthOfImpersonation}M</timeDuration>
</timerEventDefinition>
</intermediateCatchEvent>

The length variable is taken from the submitted workflow form.  After the timeDuration has completed a simple patch removes any values provisioned to the user.

<scriptTask name=”Cleanup User” id=”cleanupRequestingUser” >
<script>

queryParams = [“_queryFilter”: ‘/userName eq “‘+startUserId+'”‘]
userToPatch = openidm.query(“managed/user”, queryParams)

patchParams = [[operation:’replace’, field: ‘idToImpersonate’, value : “”]]
openidm.patch(‘managed/user/’+userToPatch.result[0]._id, null, patchParams)
</script>
</scriptTask>

The code for the above sample is available here.

This blog post was first published @ http://www.theidentitycookbook.com/, included here with permission from the author.

In flight Authorization Management

This blog post was first published @ identityrelationshipmanagement.blogspot.co.uk, included here with permission.

Access request, or authorization management is far from new.  The classic use case is the use of a workflow process that, via approval, updates a profile or account with a persisted attribute/group/permission in a target system.  At run time, when a user attempts to perform an action on the target system, the system locally checks the profile of the user and looks for particular attributes that have been persisted.

A slight variation on this theme, is to provide a mechanism to alter (or at least request to alter) the persisted permissions at near run time.  An example of this, is to leverage OAuth2 and use of a tokeninfo endpoint that can convert access_token scope data into scope values, that are used by resource server to handle local authorization.  Dependent on the content of the scope values, the resource server could provide a route for those persisted entries to be updated – aka an access request.

In the above example, we have a standard OAuth2 client-server relationship on the right hand side – it just so happens we’re also using the device flow pin and pair paradigm that is described here. Ultimately the TV application retrieves user data using OAuth2 – one of the attributes we send back to the TV, is an attribute called waterShedContent – this is a boolean value that governs whether the user can access post 9pm TV shows or not.  If the value is false, the TV player does not allow access – but does then provide a link into OpenIDM – which can trigger a workflow to request access.

Above flow goes something like this:

  1. User performs OAuth2 consent to allow the TV player access to certain profile attributes (0 is just the onboarding process for the TV via pin/pair for example)
  2. OpenAM retrieves static profile data such as the waterShedContent attribute and makes available via the ../tokeninfo end point accessible using the OAuth2 access_token
  3. Client interprets the data received from the ../tokeninfo endpoint to perform local authorization (if waterShedContent == true || false for example) providing a link into OpenIDM that can trigger an access request
  4. The BPMN workflow in IDM searches for an approver and assigns them a basic boolean gateway workflow – either allow or deny.  An allow triggers an openidm.patch that updates the necessary attribute that is then stored in OpenDJ
  5. The updated attribute is then made available via the ../tokeninfo endpoint again – perhaps via a refresh_token flow and the updated attribute is available in the client
Triggering a remote workflow (step 3) is pretty trivial – simply call /openidm/workflow/processinstance?_action=create with the necessary workflow you want to trigger.  To work out who to assign the workflow to, I leveraged the new relationship management feature of IDM and used the execution.setVariable(‘approver’, approver) function within the workflow.  The approver was simply an attribute within my initial user object that I set when I created my managed/object.

The code for the PoC-level TV-player with the necessary OAuth2 and workflow request code is available here.

Certification in ForgeRock OpenIDM Episode I: Initial Reconciliation

This blog post was first published @ www.fedji.com, included here with permission.

If this was a book, what we have here is a prologue. Just as you don’t expect the prologue to throw a full story at you, so does this web log unveil absolutely no details around Certification in ForgeRock OpenIDM. What it does though is to setup a ‘plot’ for a possible video demonstration on Certification facility in ForgeRock’s Identity Management Solution. And that’s coming soon…

So in the video log, that’s actually a visual representation of the brilliant ForgeRock Documentation on OpenIDM, you’ll see:
– Installation of ForgeRock OpenDJ
– Configuration of OpenDJ as an external resource managed by OpenIDM (using sample files)
– Performing the initial reconciliation using REST to load users from OpenDJ to OpenIDM

Soon we’ll put all those users in action for Certification in OpenIDM. For now, just as you’d skim through the prologue of a book, take a quick look at the ~5 minute video

ForgeRock OpenIDM User Provisioning Workflow

This blog post was first published @ www.fedji.com, included here with permission.

ForgeRock OpenIDM, very simply put, manages the identity, not necessarily of users all the time. In a short video demonstration that follows, I’ve taken efforts to show you a very simple user provisioning workflow in OpenIDM. When an employee in an organization initiates an onboard contract, the workflow is launched and the request reaches a manager, who then pickups the request and approves (or reject) it. Consequently, the new user’s identity is provisioned on a resource.

This video demonstration owes heavily to this section of ForgeRock documentation.

What’s in the video is a simple exercise and I strongly encourage anyone interested in ForgeRock’s Identity Management solution to try it and see. Well, if you say you aren’t familiar with the OpenIDM installation, that isn’t difficult either, you can watch it here.

Enjoy!