IDM 7.5.0

Provision users with roles

This sample demonstrates how attributes are provisioned to an external system (an LDAP directory), based on role membership. This sample uses ForgeRock Directory Services (DS) as the LDAP directory, but you can use any LDAP v3-compliant server.

Sample overview

IDM supports two types of roles:

  • Provisioning roles specify how objects are provisioned to an external system.

  • Authorization roles specify the authorization rights of a managed object internally, within IDM.

Both provisioning roles and authorization roles use relationships to link the role object, and the managed object to which the role applies. For information about managing roles, refer to Managed Roles.

Most of the commands in this sample can be run using the command-line, but it is generally easier to use the admin UI. In some cases, the command-line version makes it easier to explain what is happening in IDM. Therefore, in all steps, the sample first shows the command-line version, and then provides the equivalent method of running the command in the admin UI.

The main purpose of IDM roles is to provision a set of attributes, based on a managed user’s role membership.

The sample assumes a company, example.com. As an Employee of example.com, a user should be added to two groups in DS - the Employees group and the Chat Users group (presumably to access certain internal applications). As a Contractor, a user should be added only to the Contractors group in DS. A user’s employee type must also be set correctly in DS, based on the role that is granted to the user.

Prepare the sample

Configure the LDAP server as shown in LDAP Server Configuration. The LDAP user must have write access to create users from IDM on the LDAP server. When you set up the LDAP server, import the LDIF file for this sample (openidm/samples/provisioning-with-roles/data/Example.ldif).

This section sets up the scenario by performing the following tasks:

  1. Start IDM with the configuration for this sample.

  2. Create two managed roles, Employee and Contractor.

  3. Reconcile the managed user repository with the user entries in the LDAP server.

  1. Prepare IDM, and start the server using the sample configuration:

    cd /path/to/openidm/
    ./startup.sh -p samples/provisioning-with-roles
  2. Create two managed roles, Employee and Contractor, either by using the admin UI, or by running the following commands:

    curl \
    --header "Content-type: application/json" \
    --header "X-OpenIDM-Username: openidm-admin" \
    --header "X-OpenIDM-Password: openidm-admin" \
    --header "Accept-API-Version: resource=1.0" \
    --request POST \
    --data '{
      "name" : "Employee",
      "description": "Role granted to workers on the payroll."
    }' \
    "http://localhost:8080/openidm/managed/role?_action=create"
    {
      "_id": "d4f6b571-7e71-4901-8033-090a15098867",
      "_rev": "00000000ba0f5c8d",
      "name": "Employee",
      "description": "Role granted to workers on the payroll."
    }
    curl \
    --header "Content-type: application/json" \
    --header "X-OpenIDM-Username: openidm-admin" \
    --header "X-OpenIDM-Password: openidm-admin" \
    --header "Accept-API-Version: resource=1.0" \
    --request POST \
    --data '{
      "name": "Contractor",
      "description": "Role granted to contract workers."
    }' \
    "http://localhost:8080/openidm/managed/role?_action=create"
    {
      "_id": "95899c38-e483-4d89-8aec-a88baab0603a",
      "_rev": "00000000c7cb5c0f",
      "name": "Contractor",
      "description": "Role granted to contract workers."
    }
    Make sure to record these two role IDs, as they are required to complete the sample.
  3. Reconcile the repository.

    The sync.json configuration file for this sample includes two mappings:

    • systemLdapAccounts_managedUser, which synchronizes users from the source LDAP server with the target IDM repository.

    • managedUser_systemLdapAccounts, which synchronizes changes from the repository with the LDAP server.

    Run a reconciliation operation for the first mapping, either by using the admin UI, or over the REST interface:

    • To use the admin UI, select Configure > Mapping, click on the first mapping (System/Ldap/Account → Managed User), and click Reconcile.

    • To use the REST interface, run the following command:

      curl \
      --header "X-OpenIDM-Username: openidm-admin" \
      --header "X-OpenIDM-Password: openidm-admin" \
      --header "Accept-API-Version: resource=1.0" \
      --request POST \
      "http://localhost:8080/openidm/recon?_action=recon&mapping=systemLdapAccounts_managedUser&waitForCompletion=true"
      {
        "_id": "61abc9a3-a9cb-4d4b-b063-17891c3b355c-2541",
        "state": "SUCCESS"
      }

The sample is now ready to demonstrate provisioning roles.

Run the sample

This section assumes that you have reconciled the managed user repository to populate it with the users from the LDAP server, and that you have created the Employee and Contractor roles.

This part of the sample demonstrates the following features of the roles implementation:

Add assignments to a role definition

An assignment is the logic that provisions a managed user to an external system, based on some criteria. The most common use case of an assignment is the provisioning of specific attributes to an external system, based on the role or roles that the managed user has been granted. Assignments are sometimes called entitlements.

In this section, you will create an assignment and add it to the Employee role that you created previously. This section assumes the following scenario:

example.com’s policy requires that every employee has the correct value for their employeeType in their corporate directory (DS).

  1. Display the roles that you created in the previous section:

    curl \
    --header "X-OpenIDM-Username: openidm-admin" \
    --header "X-OpenIDM-Password: openidm-admin" \
    --header "Accept-API-Version: resource=1.0" \
    --request GET \
    "http://localhost:8080/openidm/managed/role?_queryFilter=true"
    {
      "result": [
        {
          "_id": "d4f6b571-7e71-4901-8033-090a15098867",
          "_rev": "00000000ba0f5c8d",
          "name": "Employee",
          "description": "Role granted to workers on the payroll."
        },
        {
          "_id": "95899c38-e483-4d89-8aec-a88baab0603a",
          "_rev": "00000000c7cb5c0f",
          "name": "Contractor",
          "description": "Role granted to contract workers."
        }
      ],
      ...
    }
    Display the roles in the admin UI by selecting Manage > Role.
  2. Create a new managed assignment named Employee.

    The assignment is specifically for the mapping from the managed user repository to the LDAP server. The assignment sets the value of the employeeType attribute on the LDAP server to Employee:

    curl \
    --header "X-OpenIDM-Username: openidm-admin" \
    --header "X-OpenIDM-Password: openidm-admin" \
    --header "Accept-API-Version: resource=1.0" \
    --header "Content-type: application/json" \
    --request POST \
    --data '{
       "name" : "Employee",
       "description": "Assignment for employees.",
       "mapping" : "managedUser_systemLdapAccounts",
       "attributes": [
         {
           "name": "employeeType",
           "value": [
             "Employee"
           ],
           "assignmentOperation" : "mergeWithTarget",
           "unassignmentOperation" : "removeFromTarget"
         }
       ]
     }' \
    "http://localhost:8080/openidm/managed/assignment?_action=create"
    {
      "_id": "1bbda95c-2a89-4e09-9719-8957849febeb",
      "_rev": "00000000ca15975d",
      "name": "Employee",
      "description": "Assignment for employees.",
      "mapping": "managedUser_systemLdapAccounts",
      "attributes": [
        {
          "name": "employeeType",
          "value": [
            "Employee"
          ],
          "assignmentOperation": "mergeWithTarget",
          "unassignmentOperation": "removeFromTarget"
        }
      ]
    }

    Create the assignment using the admin UI:

    1. From the navigation bar, click Manage > Assignment.

    2. On the Assignment List page, click New Assignment.

    3. On the New Assignment page, do the following:

      1. Enter the Assignment Name.

      2. Enter the Description.

      3. From the Mapping drop-down list, select the mapping for which the assignment is applied (managedUser_systemLdapAccounts).

      4. Click Save.

    4. Select the Attributes tab, and click Add an Attribute.

    5. From the drop-down list, select employeeType.

    6. In the adjacent attribute value area, click item.

    7. From the item 1 drop-down list, select string, and enter the value Employee.

    8. Click Save.

  3. Add the assignment to the Employee role that you created previously.

    Assignments are implemented as relationship objects. This means that you add an assignment to a role by referencing the assignment in the role’s assignments field:

    This command patches the Employee role to update its assignments field:

    curl \
    --header "Content-type: application/json" \
    --header "X-OpenIDM-Username: openidm-admin" \
    --header "X-OpenIDM-Password: openidm-admin" \
    --header "Accept-API-Version: resource=1.0" \
    --request PATCH \
    --data '[
       {
         "operation" : "add",
         "field" : "/assignments/-",
         "value" : { "_ref": "managed/assignment/1bbda95c-2a89-4e09-9719-8957849febeb"}
       }
     ]' \
    "http://localhost:8080/openidm/managed/role/d4f6b571-7e71-4901-8033-090a15098867"
    {
      "_id": "d4f6b571-7e71-4901-8033-090a15098867",
      "_rev": "00000000ba0f5c8d",
      "name": "Employee",
      "description": "Role granted to workers on the payroll."
    }

    Add the assignment to the role in the admin UI:

    1. Select Manage > Role, and select the Employee role.

    2. On the Managed Assignments tab, click Add Managed Assignments.

    3. Select the Employee assignment and click Add.

Grant a role to a user and observe that user’s role assignments

When a role is granted to a user (by updating the users roles property), any assignments that are referenced by the role are automatically referenced in the user’s assignments property.

In this section, we will grant the Employee role we created previously to the user Barbara Jensen, who was created in the managed/user repository during the reconciliation from DS.

  1. Before you can update Barbara Jensen’s entry, determine the identifier of her entry by querying her username, bjensen, and requesting only her _id field:

    curl \
    --header "X-OpenIDM-Username: openidm-admin" \
    --header "X-OpenIDM-Password: openidm-admin" \
    --header "Accept-API-Version: resource=1.0" \
    --request GET \
    "http://localhost:8080/openidm/managed/user?_queryFilter=/userName+eq+'bjensen'&_fields=_id"
    {
      "result": [
        {
          "_id": "57356103-a1d5-4aaa-bcc5-a640147704e0",
          "_rev": "000000006688d203"
        }
      ],
      ...
    }

    From the output, observe that bjensen’s _id is 57356103-a1d5-4aaa-bcc5-a640147704e0.

  2. Update bjensen’s entry by adding a reference to the ID of the Employee role as a value of her roles attribute. Make sure to use the unique ID from your command output.

    curl \
    --header "X-OpenIDM-Username: openidm-admin" \
    --header "X-OpenIDM-Password: openidm-admin" \
    --header "Accept-API-Version: resource=1.0" \
    --header "Content-type: application/json" \
    --request PATCH \
    --data '[
      {
        "operation": "add",
        "field": "/roles/-",
        "value": { "_ref": "managed/role/d4f6b571-7e71-4901-8033-090a15098867" }
      }
    ]' \
    "http://localhost:8080/openidm/managed/user/57356103-a1d5-4aaa-bcc5-a640147704e0"
    {
      "_id": "57356103-a1d5-4aaa-bcc5-a640147704e0",
      "_rev": "000000005498d7b5",
      "displayName": "Barbara Jensen",
      "description": "Created for OpenIDM",
      "givenName": "Barbara",
      "mail": "bjensen@example.com",
      "telephoneNumber": "1-360-229-7105",
      "sn": "Jensen",
      "userName": "bjensen",
      "accountStatus": "active",
      "effectiveAssignments": [
        {
          "_rev": "00000000ca15975d",
          "_id": "1bbda95c-2a89-4e09-9719-8957849febeb",
          "_refResourceCollection": "managed/assignment",
          "_refResourceId": "1bbda95c-2a89-4e09-9719-8957849febeb",
          "_ref": "managed/assignment/1bbda95c-2a89-4e09-9719-8957849febeb"
          "name": "Employee",
          "description": "Assignment for employees.",
          "mapping": "managedUser_systemLdapAccounts",
          "attributes": [
            {
              "name": "employeeType",
              "value": [
                "Employee"
              ],
              "assignmentOperation": "mergeWithTarget",
              "unassignmentOperation": "removeFromTarget"
            }
          ]
        }
      ],
      "effectiveRoles": [
        {
          "_refResourceCollection": "managed/role",
          "_refResourceId": "d4f6b571-7e71-4901-8033-090a15098867",
          "_ref": "managed/role/d4f6b571-7e71-4901-8033-090a15098867"
        }
      ]
    }

    Assign the role to bjensen by using the admin UI:

    1. Select Manage > User, and click bjensen’s entry.

    2. On the Provisioning Roles tab, click Add Provisioning Roles.

    3. Select the Employee role, and click Add.

  3. Take a closer look at bjensen’s entry, specifically at her roles, effective roles and effective assignments:

    curl \
    --header "X-OpenIDM-Username: openidm-admin" \
    --header "X-OpenIDM-Password: openidm-admin" \
    --header "Accept-API-Version: resource=1.0" \
    --request GET \
    "http://localhost:8080/openidm/managed/user?_queryFilter=/userName+eq+'bjensen'&_fields=_id,userName,roles,effectiveRoles,effectiveAssignments"
    {
      "result": [
        {
          "_id": "57356103-a1d5-4aaa-bcc5-a640147704e0",
          "_rev": "000000005498d7b5",
          "userName": "bjensen",
          "effectiveAssignments": [
            {
              "_rev": "00000000ca15975d",
              "_id": "1bbda95c-2a89-4e09-9719-8957849febeb",
              "name": "Employee",
              "description": "Assignment for employees.",
              "mapping": "managedUser_systemLdapAccounts",
              "attributes": [
                {
                  "name": "employeeType",
                  "value": [
                    "Employee"
                  ],
                  "assignmentOperation": "mergeWithTarget",
                  "unassignmentOperation": "removeFromTarget"
                }
              ],
              "_refResourceCollection": "managed/assignment",
              "_refResourceId": "1bbda95c-2a89-4e09-9719-8957849febeb",
              "_ref": "managed/assignment1bbda95c-2a89-4e09-9719-8957849febeb"
            }
          ],
          "effectiveRoles": [
            {
              "_refResourceCollection": "managed/role",
              "_refResourceId": "d4f6b571-7e71-4901-8033-090a15098867",
              "_ref": "managed/role/d4f6b571-7e71-4901-8033-090a15098867"
            }
          ],
          "roles": [
            {
              "_ref": "managed/role/d4f6b571-7e71-4901-8033-090a15098867",
              "_refResourceCollection": "managed/role",
              "_refResourceId": "d4f6b571-7e71-4901-8033-090a15098867",
              "_refProperties": {
                "_id": "75441276-4ede-4655-855c-e13ed4b47e8e",
                "_rev": "00000000ccc59e6c"
              }
            }
          ]
        }
      ],
      ...
    }

    bjensen now has the calculated property effectiveAssignments, which includes the set of assignments that pertains to any user with the Employee role. Currently, the assignment lists the employeeType attribute.

    In the next section, you will see how the assignment is used to set the value of the employeeType attribute in the LDAP server.

Propagate assignments to an external system

This section provides a number of steps that show how effective assignments propagate to the external systems associated with their mappings.

  1. Verify that bjensen’s employeeType has been set correctly in DS.

    Because implicit synchronization is enabled by default, any changes made to a managed user object are pushed out to all the external systems for which mappings are configured.

    Because bjensen has an effective assignment that sets an attribute in her LDAP entry, you should immediately see the resulting change in her LDAP entry.

    To verify that her entry has changed, run an ldapsearch on her entry and check the value of her employeeType attribute:

    /path/to/opendj/bin/ldapsearch \
    --port 1636 \
    --useSSL \
    --usePkcs12TrustStore /path/to/opendj/config/keystore \
    --trustStorePassword:file /path/to/opendj/config/keystore.pin \
    --hostname localhost \
    --baseDN "dc=example,dc=com" \
    --bindDN uid=admin \
    --bindPassword password \
    --searchScope sub \
    "(uid=bjensen)" dn uid employeeType isMemberOf
    dn: uid=bjensen,ou=People,dc=example,dc=com
    employeeType: Employee
    uid: bjensen
    isMemberOf: cn=openidm2,ou=Groups,dc=example,dc=com

    bjensen’s employeeType attribute is correctly set to Employee.

  2. To observe how a managed user’s roles can be used to provision group membership in an external directory, we add the groups that an Employee and a Contractor should have in the corporate directory (DS) as assignment attributes of the respective roles.

    First, look at the current assignments of the Employee role again:

    curl \
    --header "X-OpenIDM-Username: openidm-admin" \
    --header "X-OpenIDM-Password: openidm-admin" \
    --header "Accept-API-Version: resource=1.0" \
    --request GET \
    "http://localhost:8080/openidm/managed/role/d4f6b571-7e71-4901-8033-090a15098867?_fields=assignments,name"
    {
      "_id": "d4f6b571-7e71-4901-8033-090a15098867",
      "_rev": "00000000ba0f5c8d",
      "name": "Employee",
      "assignments": [
        {
          "_ref": "managed/assignment/1bbda95c-2a89-4e09-9719-8957849febeb",
          "_refResourceCollection": "managed/assignment",
          "_refResourceId": "1bbda95c-2a89-4e09-9719-8957849febeb",
          "_refProperties": {
            "_id": "94cb5abd-5358-42d7-ab96-0e6808a157aa",
            "_rev": "00000000cf18a2b6"
          }
        }
      ]
    }

    To update the groups attribute in bjensen’s LDAP entry, you do not need to create a new assignment. You simply need to add the attribute for LDAP groups to the Employee assignment (1bbda95c-2a89-4e09-9719-8957849febeb):

    curl \
    --header "Content-type: application/json" \
    --header "X-OpenIDM-Username: openidm-admin" \
    --header "X-OpenIDM-Password: openidm-admin" \
    --header "Accept-API-Version: resource=1.0" \
    --request PATCH \
    --data '[
      {
        "operation": "add",
        "field": "/attributes/-",
        "value": {
          "name": "ldapGroups",
          "value": [
            "cn=Employees,ou=Groups,dc=example,dc=com",
            "cn=Chat Users,ou=Groups,dc=example,dc=com"
          ],
          "assignmentOperation": "mergeWithTarget",
          "unassignmentOperation": "removeFromTarget"
        }
      }
    ]' \
    "http://localhost:8080/openidm/managed/assignment/1bbda95c-2a89-4e09-9719-8957849febeb"
    {
      "_id": "1bbda95c-2a89-4e09-9719-8957849febeb",
      "_rev": "000000007248f2bc",
      "name": "Employee",
      "description": "Assignment for employees.",
      "mapping": "managedUser_systemLdapAccounts",
      "attributes": [
        {
          "name": "employeeType",
          "value": [
            "Employee"
          ],
          "assignmentOperation": "mergeWithTarget",
          "unassignmentOperation": "removeFromTarget"
        },
        {
          "name": "ldapGroups",
          "value": [
            "cn=Employees,ou=Groups,dc=example,dc=com",
            "cn=Chat Users,ou=Groups,dc=example,dc=com"
          ],
          "assignmentOperation": "mergeWithTarget",
          "unassignmentOperation": "removeFromTarget"
        }
      ]
    }

    So, the Employee assignment now sets two attributes on the LDAP system - the employeeType attribute, and the ldapGroups attribute.

    To add more attributes to the Employee assignment in the admin UI:

    1. Select Manage > Assignment, and click the Employee assignment.

    2. On the Attributes tab, select Add an attribute, and select the ldapGroups attribute.

    3. Enter the following values, and click Save:

      cn=Employees,ou=Groups,dc=example,dc=com
      cn=Chat Users,ou=Groups,dc=example,dc=com
  3. With the implicit synchronization between the managed user repository and DS, bjensen should now be a member of the cn=Employees and cn=Chat Users groups in LDAP.

    You can verify this with the following ldapsearch command. This command returns bjensen’s group membership, in her isMemberOf attribute:

    /path/to/opendj/bin/ldapsearch \
    --port 1636 \
    --useSSL \
    --usePkcs12TrustStore /path/to/opendj/config/keystore \
    --trustStorePassword:file /path/to/opendj/config/keystore.pin \
    --hostname localhost \
    --baseDN "dc=example,dc=com" \
    --bindDN uid=admin \
    --bindPassword password \
    --searchScope sub \
    "(uid=bjensen)" dn uid employeeType isMemberOf
    dn: uid=bjensen,ou=People,dc=example,dc=com
    employeeType: Employee
    uid: bjensen
    isMemberOf: cn=Employees,ou=Groups,dc=example,dc=com
    isMemberOf: cn=openidm2,ou=Groups,dc=example,dc=com
    isMemberOf: cn=Chat Users,ou=Groups,dc=example,dc=com

    You can also check bjensen’s group membership by querying her object in the LDAP system, using the REST interface:

    curl \
    --header "X-OpenIDM-Username: openidm-admin" \
    --header "X-OpenIDM-Password: openidm-admin" \
    --header "Accept-API-Version: resource=1.0" \
    --request GET \
    "http://localhost:8080/openidm/system/ldap/account?_queryFilter=/uid+sw+'bjensen'&_fields=dn,uid,employeeType,ldapGroups"
    {
      "result": [
        {
          "_id": "887732e8-3db2-31bb-b329-20cd6fcecc05",
          "dn": "uid=bjensen,ou=People,dc=example,dc=com",
          "uid": "bjensen",
          "employeeType": [
            "Employee"
          ],
          "ldapGroups": [
            "cn=Chat Users,ou=Groups,dc=example,dc=com",
            "cn=openidm2,ou=Groups,dc=example,dc=com",
            "cn=Employees,ou=Groups,dc=example,dc=com"
          ]
        }
      ],
      ...
    }

    In the original LDIF file, bjensen was already a member of the openidm2 group. You can ignore this group for the purposes of this sample.

    Use the admin UI to view bjensen’s LDAP groups as follows:

    1. Select Manage > User, and select bjensen.

    2. On the Linked Systems tab, scroll down to the ldapGroups item.

  4. Now, create a new assignment that will apply to Contract employees, and add that assignment to the Contractor role.

    Create the Contractor assignment with the following command. This assignment sets the value of the employeeType attribute to Contractor, and updates the user’s ldapGroups attribute to include the cn=Contractors group:

    curl \
    --header "Content-type: application/json" \
    --header "X-OpenIDM-Username: openidm-admin" \
    --header "X-OpenIDM-Password: openidm-admin" \
    --header "Accept-API-Version: resource=1.0" \
    --request POST \
    --data '{
      "name": "Contractor",
      "description": "Contractor assignment for contract workers.",
      "mapping": "managedUser_systemLdapAccounts",
      "attributes": [
        {
          "name": "ldapGroups",
          "value": [
            "cn=Contractors,ou=Groups,dc=example,dc=com"
          ],
          "assignmentOperation": "mergeWithTarget",
          "unassignmentOperation": "removeFromTarget"
        },
        {
          "name": "employeeType",
          "value": [
            "Contractor"
          ],
          "assignmentOperation": "mergeWithTarget",
          "unassignmentOperation": "removeFromTarget"
        }
      ]
    }' \
    "http://localhost:8080/openidm/managed/assignment?_action=create"
    {
      "_id": "30323ed3-d885-4d09-94ca-c8f3b3408296",
      "_rev": "00000000db43da70",
      "name": "Contractor",
      "description": "Contractor assignment for contract workers.",
      "mapping": "managedUser_systemLdapAccounts",
      "attributes": [
        {
          "name": "ldapGroups",
          "value": [
            "cn=Contractors,ou=Groups,dc=example,dc=com"
          ],
          "assignmentOperation": "mergeWithTarget",
          "unassignmentOperation": "removeFromTarget"
        },
        {
          "name": "employeeType",
          "value": [
            "Contractor"
          ],
          "assignmentOperation": "mergeWithTarget",
          "unassignmentOperation": "removeFromTarget"
        }
      ]
    }

    Note the ID of the Contractor assignment (30323ed3-d885-4d09-94ca-c8f3b3408296 in this example).

    To create the assignment using the admin UI, refer to Add Assignments to a Role Definition.
  5. Add the Contractor assignment to the Contractor role:

    curl \
    --header "Content-type: application/json" \
    --header "X-OpenIDM-Username: openidm-admin" \
    --header "X-OpenIDM-Password: openidm-admin" \
    --header "Accept-API-Version: resource=1.0" \
    --request PATCH \
    --data '[
      {
        "operation": "add",
        "field": "/assignments/-",
        "value": {
          "_ref": "managed/assignment/30323ed3-d885-4d09-94ca-c8f3b3408296"
        }
      }
    ]' \
    "http://localhost:8080/openidm/managed/role/95899c38-e483-4d89-8aec-a88baab0603a"
    {
      "_id": "95899c38-e483-4d89-8aec-a88baab0603a",
      "_rev": "00000000c7cb5c0f",
      "name": "Contractor",
      "description": "Role granted to contract workers."
    }

    Add the Contractor assignment to the Contractor role in the admin UI, as follows:

    1. Select Manage > Role, and select the Contractor role.

    2. On the Managed Assignments tab, click Add Managed Assignment.

    3. Select the Contractor assignment from the dropdown list, and click Add.

  6. Next, we need to grant the Contractor role to user jdoe. Before we can patch jdoe’s entry, we need to know their system-generated ID. To obtain the ID, query jdoe’s entry as follows:

    curl \
    --header "X-OpenIDM-Username: openidm-admin" \
    --header "X-OpenIDM-Password: openidm-admin" \
    --header "Accept-API-Version: resource=1.0" \
    --request GET \
    "http://localhost:8080/openidm/managed/user?_queryFilter=/userName+eq+'jdoe'&_fields=_id"
    {
      "result": [
        {
          "_id": "0d8a1d10-62e0-43aa-9892-ec51258771d0",
          "_rev": "000000005daacae0"
        }
      ],
      ...
    }

    For this example, you can see that jdoe’s _id is 0d8a1d10-62e0-43aa-9892-ec51258771d0.

  7. Update jdoe’s entry by adding a reference to the ID of the Contractor role as a value of their roles attribute:

    curl \
    --header "Content-type: application/json" \
    --header "X-OpenIDM-Username: openidm-admin" \
    --header "X-OpenIDM-Password: openidm-admin" \
    --header "Accept-API-Version: resource=1.0" \
    --request PATCH \
    --data '[
      {
        "operation": "add",
        "field": "/roles/-",
        "value": {
          "_ref": "managed/role/95899c38-e483-4d89-8aec-a88baab0603a"
        }
      }
    ]' \
    "http://localhost:8080/openidm/managed/user/0d8a1d10-62e0-43aa-9892-ec51258771d0"
    {
      "_id": "0d8a1d10-62e0-43aa-9892-ec51258771d0",
      "_rev": "00000000aa64591e",
      "displayName": "John Doe",
      "description": "Created for OpenIDM",
      "givenName": "John",
      "mail": "jdoe@example.com",
      "telephoneNumber": "1-415-599-1100",
      "sn": "Doe",
      "userName": "jdoe",
      "accountStatus": "active",
      "effectiveAssignments": [
        {
          "_rev": "00000000db43da70",
          "_id": "30323ed3-d885-4d09-94ca-c8f3b3408296",
          "_refResourceCollection": "managed/assignment",
          "_refResourceId": "30323ed3-d885-4d09-94ca-c8f3b3408296",
          "_ref": "managed/assignment/30323ed3-d885-4d09-94ca-c8f3b3408296"
          "name": "Contractor",
          "description": "Contractor assignment for contract workers.",
          "mapping": "managedUser_systemLdapAccounts",
          "attributes": [
            {
              "name": "ldapGroups",
              "value": [
                "cn=Contractors,ou=Groups,dc=example,dc=com"
              ],
              "assignmentOperation": "mergeWithTarget",
              "unassignmentOperation": "removeFromTarget"
            },
            {
              "name": "employeeType",
              "value": [
                "Contractor"
              ],
              "assignmentOperation": "mergeWithTarget",
              "unassignmentOperation": "removeFromTarget"
            }
          ]
        }
      ],
      "effectiveRoles": [
        {
          "_refResourceCollection": "managed/role",
          "_refResourceId": "95899c38-e483-4d89-8aec-a88baab0603a",
          "_ref": "managed/role/95899c38-e483-4d89-8aec-a88baab0603a"
        }
      ]
    }

    Grant the Contractor role to jdoe by using the admin UI, as follows:

    1. Select Manage > User, and click jdoe.

    2. On the Provisioning Roles tab, click Add Provisioning Roles.

    3. Select the Contractor role, and click Add.

  8. Check jdoe’s entry on the LDAP system.

    With the implicit synchronization between the managed user repository and DS, jdoe should now be a member of the cn=Contractors group in LDAP. In addition, his employeeType should have been set to Contractor.

    You can verify this with the following REST query. This command returns jdoes’s group membership, in his isMemberOf attribute, and his employeeType:

    curl \
    --header "X-OpenIDM-Username: openidm-admin" \
    --header "X-OpenIDM-Password: openidm-admin" \
    --header "Accept-API-Version: resource=1.0" \
    --request GET \
    "http://localhost:8080/openidm/system/ldap/account?_queryFilter=/uid+sw+'jdoe'&_fields=dn,uid,employeeType,ldapGroups"
    {
      "result": [
        {
          "_id": "0da50512-79bb-3461-bd04-241ee4c785bf",
          "dn": "uid=jdoe,ou=People,dc=example,dc=com",
          "uid": "jdoe",
          "employeeType": [
            "Contractor"
          ],
          "ldapGroups": [
            "cn=openidm,ou=Groups,dc=example,dc=com",
            "cn=Contractors,ou=Groups,dc=example,dc=com"
          ]
        }
      ],
      ...
    }

    Use the admin UI to view jdoe’s LDAP groups as follows:

    1. Select Manage > User, and select jdoe.

    2. On the Linked Systems tab, scroll down to the ldapGroups item.

When working with large groups in LDAP services such as DS, you should use dynamic groups instead of static groups. The steps laid out above for setting assignments and roles work with the exception of how you add a user to a group: in dynamic groups, membership is determined by whether a user has an attribute the group is configured to search for.

For example, if the Employees group was a dynamic group, membership might be set based on the employeeType attribute directly, by setting the memberURL in the group to ldap:///ou=People,dc=example,dc=com??sub?(employeeType=Employee). You would then remove the ldapGroups attribute from the Employee assignment, since group membership is handled by employeeType.

This membership won’t be listed in the ldapGroups attribute in IDM (since it is no longer set there), but can be verified by querying DS directly:

/path/to/opendj/bin/ldapsearch \
--port 1636 \
--useSSL \
--usePkcs12TrustStore /path/to/opendj/config/keystore \
--trustStorePassword:file /path/to/opendj/config/keystore.pin \
--hostname localhost \
--baseDN "dc=example,dc=com" \
--bindDN uid=admin \
--bindPassword password \
--searchScope sub \
"(uid=bjensen)" dn uid employeeType isMemberOf
dn: uid=bjensen,ou=People,dc=example,dc=com
employeeType: Employee
uid: bjensen
isMemberOf: cn=Employees,ou=Groups,dc=example,dc=com
isMemberOf: cn=openidm2,ou=Groups,dc=example,dc=com
isMemberOf: cn=Chat Users,ou=Groups,dc=example,dc=com

For more information about dynamic groups in DS, refer to Dynamic Groups in the Configuration Guide for ForgeRock Directory Services.

Remove a role grant from a user and observe that user’s role assignments

In this section, you will remove the Contractor role from jdoe’s managed user entry and observe the subsequent change to jdoe’s managed assignments, and to the corresponding attributes in DS.

  1. Before you change jdoe’s roles, view his entry again to examine his current roles:

    curl \
    --header "X-OpenIDM-Username: openidm-admin" \
    --header "X-OpenIDM-Password: openidm-admin" \
    --header "Accept-API-Version: resource=1.0" \
    --request GET \
    "http://localhost:8080/openidm/managed/user?_queryFilter=/userName+eq+'jdoe'&_fields=_id,roles"
    {
      "result": [
        {
          "_id": "0d8a1d10-62e0-43aa-9892-ec51258771d0",
          "_rev": "00000000aa64591e",
          "roles": [
            {
              "_ref": "managed/role/95899c38-e483-4d89-8aec-a88baab0603a",
              "_refResourceCollection": "managed/role",
              "_refResourceId": "95899c38-e483-4d89-8aec-a88baab0603a",
              "_refProperties": {
                "_id": "de68f5d9-baf9-49ca-8db5-96f0a382946d",
                "_rev": "00000000e299a021"
              }
            }
          ]
        }
      ],
      ...
    }

    Note the following IDs in this example output, you need them in the next step:

    • The ID of jdoe’s user object is 0d8a1d10-62e0-43aa-9892-ec51258771d0.

    • The ID of the contractor role (_refResourceId) is 95899c38-e483-4d89-8aec-a88baab0603a.

    • The ID of the relationship that expresses the role grant is de68f5d9-baf9-49ca-8db5-96f0a382946d.

    View jdoe’s current roles in the admin UI:

    1. Select Manage > User, and select jdoe.

    2. The Provisioning Roles tab lists the current roles.

  2. Remove the Contractor role from jdoe’s entry by sending a DELETE request to his user entry, specifying the relationship ID:

    curl \
    --header "X-OpenIDM-Username: openidm-admin" \
    --header "X-OpenIDM-Password: openidm-admin" \
    --header "Accept-API-Version: resource=1.0" \
    --request DELETE \
    "http://localhost:8080/openidm/managed/user/0d8a1d10-62e0-43aa-9892-ec51258771d0/roles/de68f5d9-baf9-49ca-8db5-96f0a382946d"
    {
      "_id": "de68f5d9-baf9-49ca-8db5-96f0a382946d",
      "_rev": "00000000e299a021",
      "_ref": "managed/role/95899c38-e483-4d89-8aec-a88baab0603a",
      "_refResourceCollection": "managed/role",
      "_refResourceId": "95899c38-e483-4d89-8aec-a88baab0603a",
      "_refProperties": {
        "_id": "de68f5d9-baf9-49ca-8db5-96f0a382946d",
        "_rev": "00000000e299a021"
      }
    }

    The output shows that the relationship between the user and the role was deleted.

    Use the admin UI to remove the Contractor role from jdoe’s entry as follows:

    1. Select Manage > User, and select jdoe.

    2. On the Provisioning Roles tab, check the box next to the Contractor role and click Remove Selected Provisioning Roles.

  3. Verify jdoe’s employeeType and ldapGroups.

    The removal of the Contractor role causes a synchronization operation to be run on jdoe’s entry. His employeeType and ldapGroups attributes in DS should be reset to what they were before he was granted the Contractor role.

    Check jdoe’s attributes by querying his object in the LDAP directory, over the REST interface:

    curl \
    --header "X-OpenIDM-Username: openidm-admin" \
    --header "X-OpenIDM-Password: openidm-admin" \
    --header "Accept-API-Version: resource=1.0" \
    --request GET \
    "http://localhost:8080/openidm/system/ldap/account?_queryFilter=/uid+sw+'jdoe'&_fields=dn,uid,employeeType,ldapGroups"
    {
      "result": [
        {
          "_id": "0da50512-79bb-3461-bd04-241ee4c785bf",
          "dn": "uid=jdoe,ou=People,dc=example,dc=com",
          "uid": "jdoe",
          "employeeType": [],
          "ldapGroups": [
            "cn=openidm,ou=Groups,dc=example,dc=com"
          ]
        }
      ],
      ...
    }

    Use the admin UI to view jdoe’s LDAP groups as follows:

    1. Select Manage > User, and select jdoe’s entry.

    2. On the Linked Systems tab, scroll down to the ldapGroups item.

For more information about roles, assignments, and how to manipulate them, refer to Managed Roles.