What to consider when building services

This document describes some common problems and solutions that you may encounter when starting out with developing services.

What do I need to think about before creating a service?

There are multiple types of services you can create using Zervicepoint. These aspects are important to consider before you start:

Is the whole process known today and does the whole process need to be implemented from the first version

It is important that you understand the process and how it works before automating it. This is typically not a big question on smaller processes like ordering software or adding system access. But larger processes needs to be analyzed further.

Hiring for example has many parallel processes for HR and IT etc. From creating and signing the agreement to order computer, phone number, access cards, system accesses and physical desk. Some parts can not be automated like setting up a physical desk for the employee but a notification can be sent to the janitor to arrange this at a given time. Which parts of the process is most valuable to automate?

If you are attempting to design a service for a grander process it is important that you group up with the people that are a part of this process today to extract the necessary steps but it is also important to include people that have the mandate to take decisions about the process. In some cases minor changes to the process can have a great impact on how to efficiently automate it. If you are in a workshop with this kind of group try to avoid getting stuck in discussing how the process works today and focus more on how you'd like the process to work in the future.

Sometimes it can be a good idea to start with less automation and work more with Manual Tasks just to minimize the overhead and idle time between tasks. The biggest problem with the new hire process is often that there is not horizontal system that keeps track of the process as a whole and Zervicepoint fits in well there.

The larger and longer your automation process is the more likely it is to have errors appear. In our New Hire example you may have a part where you create an AD account that the employee can use to login with and later you make changes to this account as the process progress. A real example is a customer who have an on-premises/cloud hybrid directory environment where the account is first created on-premises and then the Dir-sync takes over to synchronize the user to Azure. When Zervicepoint tries to assign a license for mail to this users it will not work if the Dir-sync hasn't done it's job resulting in an error and possibly a stopped workflow. In these cases it can be very useful to have parts of the grander process exposed as separate services in Zervicepoint. You can minimize the development time by utilizing the Grouped activities.

Often it is also important to decide what happens when things go wrong. When a handled error occurs in the workflow Zervicepoint can do whatever you decide like send an email or create a ticket for someone to act on. Another solution is to create a ticket directly when a process is initialized and update with comments throughout the workflow. The workflow then ends when the process is completed and the ticket is closed. This way if a ticket is still open after a period of time the support personel can look at the ticket and see how long in the workflow the process has went and also take the necessary actions to finalize the process.

Access

By default, if the setting Visible for roles is empty, then the page/service will be available to anyone who have access to the zervicepoint portal. (This would typically be anyone with a account in either your AD/AzureAD environment)

There are usually cases where you want to restrict access to service desk, managers or HR. Always keep this in mind in order to avoid exposing sensitive services to all your users.

Deeper access control

Here's an example:

  • You have a service called "Edit User" that edits users in your local Active Directory.
  • You have a drop down at the very top where you want the user to search for a user to edit.
  • You do not want every user to be able to search and select all users.
  • You want Swedish admins to only be able to edit Swedish users and you want Polish admins to only be able to edit Polish users.

To achieve this you basically have two options:

Option 1

  • Make two services. One for Swedish admins and one for Polish admins
  • Create a role for each admin type: SweAdmin, PolAdmin
  • Set the membership rule return user.hasClaim('Group', 'SwedishAdminsGroup'); assuming you have an AD group called SwedishAdminsGroup and the admins are a member of that group.
  • Make the services visible to only to corresponding roles.
  • The services will need to have two separate data sources for the user selection drop down. Ex: DropDown.SWEUsers

Option 2

  • Make one service.
  • Like above, create the roles and set the membership rules but do not restrict the visibility to any one role.
  • Create one dynamic drop down and use the config.roles variable do determine the output in the code.

Option 1 is is a bit simpler to implement and will suffice as long as you do not have that many roles. One drawback is that you will need to have one drop down for each service. Another drawback is that when you want to update Edit User you need to do it on every service making it harder to maintain.

Option 2 is a little harder to implement as you will need to either define the role configuration in one of our plugin drop downs or create your own custom drop down but once you have done that you have a drop down that can be reused in other services where you want the same access control.

Read more about how to implement access control here

Self-service or Admin tool

Self-service

Typical services for self-service is Order Hardware, Order Software, Request time off etc.

When creating services for end-users there's some questions you need to take into consideration. For example:

  • Should you only be able to order to yourself?
  • If you are a manager, should you be able to order to your staff?
  • If the order needs approval, who will approve?
  • If the requester's manager is the default approver what should happen if the requester doesn't have a manager?
  • In some cases more than one approval may be required from the business. Ie if the requested hardware is very expensive.

A typical solution for most of the possible scenarios of these points is:

  • Add a drop down at the top of your form labeled Request for:
  • The data source behind this drop down should have a GetDefault function that returns the current user (config.currentuser can be used) so that when a user opens the form he/she is pre-selected.
  • The Search function can check if the current user has any directReports (AD attribute) and if so allow the user to search on them.
  • The Search function can also check for a specific role that lets you search on all users.
  • When the form is loaded (onLoad) have a webservice fetch the manager of the current user and show the information like below:

  • If the webservice returns no manager this must be handled in the call as well:

  • The same webservice needs to be called onChange on the drop down to show the correct information if the reciever is changed.

    // Example of a javascript function that will generate this approval message.
    // This example requires the webservice Get-ZPADManager from our AD plugin.
    // Put it onLoad on the RequestFor drop down.
    // Call it onChange on the RequestFor drop down.
    window.updateApprovalInfo = function() {
        var args = {
            // Identity will be empty onLoad but the webservice Get-ZPADManager will default to currentUser
            Identity: Z('#RequestFor').val()
        }
        Z.call('Get-ZPADManager', args).done(function(manager) {
            if (manager[0] !== null) {
                Z('#ApproverRTF').val('This order needs to be approved by ' + manager[0].GivenName + ' ' + manager[0].sn + '.');
                Z('#RequestFor').valid(true);
            } else {
                Z('#ApproverRTF').val('<font color=red>The selected user does not have a manager. Please contact Service Desk.</font>');
                Z('#RequestFor').valid(false); // This will block the order from being placed.
            }
        });
    }
    updateApprovalInfo();
    

Admin services

Typical admin services are Edit user, Migrate Mailbox, Install computer etc.

The difference between admin services are usually bigger than with self-service but let's look at some questions that may arise in a typical Edit service. In an Edit service you typically want to expose a set of properties from an entity in another system, like an Azure User, TFIM Person, mailbox, an entity living in a database etc. So usually you have a drop down at the top where you can select or search for the object to edit and below you have TextFields to show properties of the selected object. The user is free to edit the TextFields and then place the order with the intention to update these properties.

  • What should happen if the user empties a property field? Should this clear the property or not touch it?
  • How do we ensure that the admins only use the services as we intended?
  • How do we handle passwords in a secure way?
  • Limitations?

Handling empty fields

This is often not an issue as administrators may not have the need to empty properties very often but it does occur. Handling this in an Activity can however be a bit tricky as you need to consider what happens if you have a parameter coming in with and empty argument. In our Active Directory plugin we have an activity called Set-ZPADUser with a parameter called ClearEmptyValues which will enable this behaviour if set. This issue is very important if you have other automation systems placing orders in Zervicepoint.

How do we ensure that the admins only use the services as we intended

We know that admins sometimes try to bypass restrictions created by service developers. If you use client scripts (javascript) to determine the behavior of the workflow you open up for abuse. The admin can open the developer console in their browser and change values themselves.

It can sometimes be tempting to use data from the form to make decisions in the workflow but this is not a good practise. This kind of information should be fetched in the workflow even if you already fetched it in the form.

Unrestricted static drop downs is handy when you want to dynamically change the options with javascript but it is not secure as it can be changed by the user with javascript as well. If you still want to use this kind of drop down but make sure nothing unintended gets posted you need to validate this with an activity in the workflow.

Dynamic drop owns can not be tampered with as they are signed by Zervicepoint. The signature is verified when the form is posted. Same for standard Static drop downs.

In short, as long as you do not make workflow decisions based on anything from the form that is not a dynamic or restricted drop down you align with our recommendation.

How do we handle passwords in a secure way

Let's say you have a service that resets passwords for users.

Here is 3 ways to tackle this:

  1. Simply add a TextField bound to a string variable. The password that has been entered will then be visible in the requesters order history, in the Order Manager. So users with no admin access in Zervicepoint will not be able to see the password.

  2. Add a TextField bound to an obfuscated string variable: The password will be obfuscated in the order history and in the Order Manager but for someone with access to the Zervicepoint database it is possible to retrieve the password.

  3. Add a checkbox Reset password and then generate a new password in an activity.

There will be no traces of the password anywhere in Zervicepoint BUT the end-user needs to know the new password so if you pass the password out from an activity (let's say to email it to the end-user) it will appear in an encrypted form in the Workflow manager database. If you want to make it even safer you can make an activity that generates the password and then sends it to the end-user.

about passwords in forms

If you decide to let the admin chose the new password make sure you validate against the password policy using either a webservice or with RegEx. The example below checks for the standard Active Directory policy. If you do not check this in the form the workflow will fail when you try to set an unsupported password.

// RegEx that validates that the password follow the standard AD policy.
// Meaning that the password most contain 3 of the following 4 character types:
// 1. Uppercase—for example, A to Z
// 2. Lowercase—for example, a to z
// 3. Numeric—0 to 9
// 4. Nonalphanumeric—symbols such as !, #, %, or &
// Also, the password needs to be at least 8 characters long.

^(?:(?=.*[a-z])(?:(?=.*[A-Z])(?=.*[\d\W])|(?=.*\W)(?=.*\d))|(?=.*\W)(?=.*[A-Z])(?=.*\d)).{8,}$

Add this RegEx pattern to your Custom validation on your InputText field.

Limitations

We are only as good as the API we are depending on. If a system has an unstable API you need to mitigate that in your calls using retrys and error handling. In some cases it can be an option to save information from the target system in a database that can be queried instead of querying the target system directly. It depends on how static the data is and if the integration is mostly for displaying information.

CRUD

CRUD stands for Create Read Update Delete

The question of CRUD usually araise if you have been asked to add services to solve an issue manageing some entities like users or computers. We implemented Zervicepoint to let our administrators manage computers. In this case you typically need a service for creating computers, updating them and deleting them. Update can typically be used for reading as well.

The point is; if you are asked to develop a service for creating something then you should ask if there is a need for services for deleting and updating as well.

Consider developing a Table page for managing these kind of resources.

Shared process

There are two very common scenarios where you want to implement Shared Processes.

Software services being the first. Since the form and workflow really are parts of the Process and meta data such as service name, description, cost and icon is a part of the service there is not much of a difference between one software service and another.

Let's say you are building a shared software process for an organization that deploys their software through SCCM. In this case each software is identified with a CollectionId and in the workflow you can build your own activity that will add a computer to the selected collection or use our SCCM Plugin. The computer will be selected in the order form but the CollectionId must come from the service. We create a shared process and start with the Setup form and defining the configuration that we want to put there.

We then add the Add-ZPSCCMMembershipRule activity and bind it to the computer variable (from the form) and the CollectionId variable from the Setup form. After finishing the workflow and form you can save the process and start implementing your first service on this process.

After adding an name, icon and description you add the CollectionId at the end of the Add new service wizard your new software service is done and you can easily add thousands of more just by going through the wizard our using our API to do it programatically.

The second common scenario where you really want to implemented shared processes is for Hardware services which can be created in much the same way. The difference may be that instead of a CollectionId you may have an ArticleId.

All-in-one service or not

Let's illustrate this question with an example: You have been asked to create one ore more services to handle User security. You want to include many different options such as locking and unlocking accounts, reseting passwords, defining logon hours, block/unblock interactive login, set remoting rights etc. You now have the option to either split these options into a number of different services or create one big service that will contain all features.

Developing one service for all features will make development and testing a bit trickier but the end-user can place one order to make several security settings on a user. The workflow will be longer so if the provisioning server has a lot of work it can take a few minutes for the order to complete.

The other option is to create many services and put them on a page called User security. This will be easier to develop and test and often to manage as well. The workflows will run faster which may be importing when you just want to reset a password for example.

Out of an UX perspective it is usually be better as well since the end-user goes to Zervicepoint in order to do a task such as resetting a password. Finding a service called Reset password may be more intuitive than clicking on the service called User security.

Service icons

We recommend the PNG format with 720 x 480 dimension.

There are a number of sites where you can download free to use icons. Here are a few examples which will look good in Zervicepoint:

Create computer
Edit computer
Edit computer
Install computer
Remove computer
Create user
Edit user
Set user expiration date
Remove user
Set password