User registration with account claiming

Multi-step user registration with account claim support

IBM Security Verify enables users to self-register themselves, as typically seen in Consumer Identity and Access Management (CIAM) and Business-to-Business-to-Consumer (B2B2C) use cases.

Self-registration can be done by taking the user through a series of data collection and validation steps. Also, the user can create a digital account or profile based on an existing relationship the user has with an organization. This relationship can be in the form of a membership ID, a policy ID, or an account number.

The action of creating a digital account based on an existing relationship is known as "claiming an account". The information that is provided by the user in this flow is validated with a system of records, managed by the organization.

This blog helps you understand how to self-register by "claiming an account".

Overview of the flow

The flow for "claiming an account" goes as follows:

  1. Gather the Policy ID from the user.
  2. Retrieve the user object corresponding to this Policy ID from the third-party system.
  3. Show the retrieved details to the user for validation purposes.
  4. Gather any additional details needed for registration.
  5. Create a user profile.
  6. Show a confirmation page that they are registered.
  7. If the user creation fails for some reason, divert the flow to an error page.


Review and understand the hello world example, including how to obtain flow and page asset resources for configuring the example flows. See the parent page for details on the hello world example.

Here are the other prerequisites:

  1. Connect with the IBM Security Verify support team and get the user registration features enabled in your tenant:
    • CI-98615: Workflow User Registration.
  2. Create a set of user data collection forms that you can use to present relevant data and gather other data from the users.

Installation and configuration

Custom branding theme

This flow presents custom pages, therefore a theme needs to be created to prevent affecting the flows that use the default theme. There are two customized files:

  • custom_page4.html: This template is used to show an error in case the flow fails.
  • custom_page5.html: This template is used to show a confirmation to the user post registration.

Log in to the IBM Security Verify admin console and follow these steps:

  1. In the left side menu, select User experience and click Branding.

  2. Follow the steps mentioned here to create a theme for this flow. Name the theme appropriately. In context of this article, naming the theme User Registration.

  3. Click the theme tile to view the file tree.

  4. Expand workflow > pages and click the three vertical dots next to custom_page4.html. Click Upload.

  5. Choose $GIT_REPO/flows/user_registration_with_account_claiming/pages/templates/workflow/default/custom_page4.html from the local folder. Then click Upload.

  6. Similar to the earlier step, under workflow > pages, click the three vertical dots next to custom_page5.html. Click Upload.

  7. Choose $GIT_REPO/flows/user_registration_with_account_claiming/pages/templates/workflow/default/custom_page5.html from the local folder. Then click Upload.

Configuring the flow forms

Create the user forms that are to be used for orchestrating the user registration experience by claiming an existing account. In this case, three user forms must be created.



The current article provides the steps to create three forms with specific fields to demonstrate the basic registration flow. The flow can be expanded to include more attributes and forms, based on the individual needs of registration.

A. Form to collect the Policy ID (gatherPolicyId):

  1. When logged in as administrator in the IBM Security Verify, navigate to "User experience".

  2. Under "User experience", select "User forms" and "Create form".

  3. Enter a form name, say gatherpolicyid and a field to gather a Policy ID. Optionally other settings can be made, such as Primary language, Session management, Theme, and Human Verification:

  4. Click "Start building form".

  5. Remove the field "Email address" and click "Add form element":

  6. Add the relevant field to collect the Policy ID of the user:

  7. Click "Save changes" and "Publish".


This step completed the first of three forms needed. Note, other settings can be customized such as branding, displayed text for collecting Policy ID, other fields for validation and more.

B. Form to show details of the user, as collected from third-party (completeForm):

  1. Follow steps similar to Section A to show the data collected from third-party server:

  2. The fields of interest for this form are:

    1. Given name.
    2. Family name.
    3. Email.
    4. Username.
    5. Consent to persist the data collected from third-party.
  3. When the form is composed, click "Save changes" and "Publish".

    This step completed the second of three forms needed. Note, other settings can be customized such as branding, different set of fields and more.

C. Form to collect more details of the user (additionalDetails):

  1. Follow steps similar to Section A to gather more details from the user:

  2. The fields of interest for this form are the work-related details of the user:

    1. Current company name.
    2. Current company address.
    3. Work number.
  3. When the form is composed, click "Save changes" and "Publish".

This step completed the third of three forms needed. Note, other settings can be customized such as branding, different set of fields, and more.

When finished, you see the three forms under the User forms section within IBM Security Verify, in Published state.

Import the workflow

  1. To import the model, log in to your Verify Tenant as the administrator and switch to the admin interface.

  2. Navigate to the Flow designer:

  3. Click the Import icon next to the Create flow button:

  4. Complete the details and upload the file $GIT_REPO/flows/user_registration_with_account_claiming/user_registration_with_account_claiming.bpmn:

  5. When the model is imported, the flow is saved in Draft mode. It shows up as follows in the Flow designer:

  6. Select the Set Vars task to specify the connection details needed to connect to the third-party identity source, which hosts the account that is being claimed:

  7. Update the form tasks as outlined in the Unpacking the flow.

  8. After all changes are made, publish the workflow, by clicking on the Publish button.

Running the flow

After the flow is published, start the flow by using Execution URL:

  1. Open the Settings panel by clicking the information icon next to the Cancel button:


    From the Settings panel, copy the Execution URL:

  2. Open a browser window and go to this execution URL and complete the flow as directed.



Typically, the prescribed flow is triggered as part of the user registration. However, it is advisable to run the end-to-end flow before it is enabled for generic usage.

Unpacking the flow

This optional section describes the purpose of each step in the workflow.

Registration form (gather policy ID)

This is the first one that is presented to the user to specify their policyId from the third-party site. Edit the form configuration to link to the form (gatherPolicyId) that you created as part of the Configuring the flow forms section under Installation and Configuration:


The flow is paused till the user finishes entering the data:


In this specific case, the flow is paused till the signal step1 is received.

When the data is submitted by the user, it is persisted in the userData property of userFormData, under the workflow context.

Fetch user owning the policy

This task is primarily used for connecting with the third-party system to fetch the user details, corresponding to the policyId that is provided during the flow. In the sample model, the Function task to fetch the user. The script can be modified to reflect the preferred rules, for example if you want to use a different attribute to fetch the user details.

The response is being stored in the existingUser object.

- return: >
        "existingUser": hc.GetAsJson('https://' + ctx.thirdPartyIdentitySource + '/v2.0/Users?filter=%28urn%3Aietf%3Aparams%3Ascim%3Aschemas%3Aextension%3Aibm%3A2.0%3AUser%3AcustomAttributes.policyid%20eq%20%22'+ ctx.userFormData.userData.policyId +'%22%29', {'Authorization': 'Bearer ' + hc.Post("https://" + ctx.thirdPartyIdentitySource + "/v1.0/endpoint/default/token", {"Content-Type": "application/x-www-form-urlencoded"}, "client_id=" +  ctx.client_id + "&client_secret=" + ctx.client_secret + "&grant_type=client_credentials").responseBody.access_token, 'Accept': 'application/scim+json'})

The connection details mentioned in the Set Vars task are used in this specific statement.



This construct is just an example of how you can fetch the user details, by connecting to the third party.
One can use a different combination of HTTP Call-outs with relevant parameters to complete the call.
Refer here for further details on the usage of http call-outs.

Map user details to context

In the flow, the existingUser is presented to the user by using a User form. This approach allows the user to review the details fetched from the third party, and validate them before they are used for registration purposes. Since the schema of the user object (from third party) is unknown to the engine, a data transformation is needed from the third-party schema to the local schema.

This data transformation is achieved by using a Function task. The script can be modified to reflect the required set of rules:

# Extract the attributes that are to be shown to the user for review, from existingUser object. In this case, name & email are main attributes. 
  - context: userName := ctx.existingUser.Resources[0].userName
  - context: givenName := ctx.existingUser.Resources[0].name.givenName
  - context: familyName := ctx.existingUser.Resources[0].name.familyName
  - context: updateddata := ctx.existingUser.Resources[0]['urn:ietf:params:scim:schemas:extension:ibm:2.0:User'].remove("pwdReset").remove("twoFactorAuthentication").remove("customAttributes")
  - context: updateddataname := ctx.existingUser.Resources[0]['name']
  - context: updatedEmail := ctx.existingUser.Resources[0].emails[0].value

  # The data in the user forms is typically stored in the workflow context against userFormData.userData. Check if we already have a userFormData.userData object available in the context at this point of time.
  - if:
      match: has(ctx.userFormData.userData)
        - context: updatedData :=  ctx.userFormData.userData.putAll(context.updateddata)
        # Update the relevant attributes in userFormData.userData
        - context: updatedDataWithUserName := ctx.userFormData.userData.put("32", context.userName)
        - context: updatedDataWithEmail := ctx.userFormData.userData.put("3", context.updatedEmail)
        - context: updatedDataWithGivenName := ctx.userFormData.userData.put("6", context.givenName)
        - context: updatedDataWithFamilyName := ctx.userFormData.userData.put("7", context.familyName)
        - context: updatedDataWithName :=  ctx.userFormData.userData.putAll(context.updateddataname)
        - statement: ctx.put('userFormData.userData',context.updatedDataWithName)
        - context: payload := {}.put('userFormData',ctx.userFormData)
        - return: context.payload

User registration form

This form is presented to the user to view the details gathered from the third party.

Edit the form configuration to link to the form (completeForm):


User registration form - Additional

This form is presented to the user to gather more details for registration. Edit the form configuration to link to the form (additionalDetails). The process is similar to the one for completeForm.

Create user

This task uses the data in the userFormData.userData property under the workflow context to register the user. If the registration is successful, the corresponding SCIM object is generated as a response and stored against the user object, in the workflow context.


Account creation confirmation

This task presents a custom page with a confirmation that the account was successfully created. The page contains a link to go to the Login page and logs in by using the credentials that were sent to the registered user by email.

Read more about the Page task here.

In the model referred to in this article, the workflow context is checked for the existence of the user object. This model can be fine-tuned for a more complex set of conditions, by using the Condition Builder.

To launch the Condition builder click the Arrow from Exclusive Gateway to Account creation confirmation. Click on the highlighted link to launch the Condition builder.


In the Condition builder that shows up, add your own conditions to decide whether to show the Confirmation Page:


Error handling

If the user create operation fails, the flow uses a conditional gateway to direct the user to a custom error page.


Follow steps similar to Account creation confirmation Section, to put down your own set of conditions on when to show the Error Page.

If a system error occurs, the flow is directed to the default error page. This page can be customized in the User Registration theme.


The wrap

This flow introduces a method to register a user, based on the existing details retrieved from a third party. The integration with third-party demonstrated here can be customized to point to any given third party that supports REST end-points.

The flow also talks about the specific user forms, which can be customized to suit individual needs.


Ramakrishna J Gorthi and πŸ’Ž Mansi Arora, IBM Security