Synchronizing Active Directory group memberships into ForgeRock’s Identity Cloud

Dennis Andrade
7 min readOct 27, 2022

This is a common question I usually get from our customers so I’m writing about our approach to this use case and how to get the group memberships synchronized to ForgeRock’s Identity Cloud.

Introduction

The use case is the following: Company X has an Active Directory where all employees, contractors and customers are stored. Company X uses AD as the source of truth and they use AD groups to manage user’s access to their system.

Company X have decided to implement ForgeRock’s IdCloud and need to synchronize the user’s group membership from AD to IdCloud.

Overview

The biggest challenge most customers run into in this use case is how to map all the AD attributes and objects to Identity Cloud, so I will break it down piece by piece to get the mapping right. The steps are implemented in the Identity Cloud server.

Step 1: Create an LDAP Connector

Create a new LDAP connector and make sure you can see the AD users and groups when you click on the connector’s data tab.

AD Users:

AD Groups:

Step 2: ADConnector account to alpha_user mapping

Create a new mapping from the ADConnector account to the alpha_user managed object. Do not add any information about the group membership in this mapping because we will be handling it in the group mapping.

Note that in this lab I have set the password attribute to a static value to simplify the implementation. Password handling from AD to Identity Cloud is out of scope and it is a topic for another blog post.

Make sure you have all the required target (IdCloud) attributes configured: givenName, userName, mail and sn. You will get an error message running the reconciliation if the required attributes are not configured. Also, add any extra attributes you might need to synchronize.

Configure an association rule if needed and make sure that the current policy in the Behaviors tab is set to read-only.

Run reconciliation and make sure the result is what you would expect. For instance, the number of objects that succeeded in the reconciliation is the same number of users in your AD forest.

Change the current policy to Default Actions in the behaviors tab, save the changes and run reconciliation again. You should now see all the AD users represented as an alpha_user object in Identity Cloud.

Let's move on to the groups piece of this implementation.

Step 3: ADConnector group to alpha_role mapping

Create a new mapping from the ADConnector group to the alpha_role managed object. Do not add any information about the group membership right now. If you do, you will receive an error message trying to reconcile because the default types would not match. The value of the members attribute in the alpha_role managed object is a relationship to the alpha_user managed object, not a simple string. You will need to create a transformation script to create a reference value. We will be doing this in a later step. This is the error message you would get without the transformation script in the member (AD) -> members (Identity Cloud) mapping:

“WARNING: Unexpected failure during source reconciliation fef622cb-387d-4bf1–9925-a922b1e56553–2253271\n”
“org.forgerock.openidm.sync.SynchronizationException: Invalid value format for relationship collection: members\n\tat org.forgerock.openidm.sync.SyncOperation.lambda$updateTargetObject$2

For now let's simply configure the basics. Below is an example of a group mapping.

Just like in step 2, make sure the target required attribute is configured: name. And any extra attribute you might need. Also, configure an association rule if needed and make sure the current policy is set to read-only in the behavior’s tab.

Once you are satisfied with the reconciliation result, change the current policy to Default Actions in the behavior tab and run reconciliation again.

The AD groups should now exist in the Identity Cloud as a role. You can verify that all the groups are synchronized by going to the Manage -> Alpha_Role in the native IDM console. Notice that the group membership is not there just yet. We will add the mapping in the next step.

Step 4: Add the transformation script to the group mapping

It’s important to explain why we need a transformation script before we go through the implementation itself.

Most of the mappings configuration are mappings to the same attribute type, for instance, givenName, sn, cn, mail attributes are all String in AD and in alpha_user, so we can do a simple mapping and it works.

When we talk about the member attribute in AD, we are talking about an Array. This attribute will hold an array of user DNs

In Identity Cloud, we have an attribute called members in the alpha_role managed object. This attribute is a relationship between the alpha_role and the alpha_user.

The reason we cannot create a simple mapping from member -> members is because those two attributes are not the same attribute type. We need to “transform” the array into a relationship and this is where the transformation script comes into play.

All right! Let’s get into the implementation part of it.

Open the groups mapping you created in step three and add a new property mapping from member to members.

Then add a new transformation script to map each array item from the AD member attribute to an actual relationship in ID Cloud:

array_of_users = [];
for (let i = 0; i < source.length; i++) {
var parsedCN = source[i].split(‘,’);
var userCN = parsedCN[0].split(‘=’);
var memberQry = openidm.query(“managed/alpha_user”, {
“_queryFilter”: “cn eq ‘“ + userCN[1] + “‘“
});
if (memberQry.result.length === 1) {
alphaUserID = { _ref : “managed/alpha_user/” + memberQry.result[0]._id};
array_of_users.push(alphaUserID);
}
}
array_of_users;

Let’s breakdown the script so you understand what’s happening here:

  • On Line 1 we create an empty array to hold the list of user relationships with this particular role.
  • We then loop through each item in the AD member’s attribute array
  • As explained before, the member attribute holds an array of user DNs. Notice that alpha_user does not have the DN attribute so we won’t be able to just match that whole dn with a current alpha_user in Identity Cloud to create this relationship. We do however have the cn attribute, so we can parse the dn to get only the cn part of it. That’s what lines 3 and 4 do.
  • Next, the query function, provided in the openidm object, searches the repository for a managed alpha_user where the cn matches the group member.
  • The memberQry variable is set to the value of the openidm.query function return. Note that the value returned is an array since theoretically you could find multiple objects.
  • The if statement tests the query results and only outputs a value if there is only one value in the array.
  • The alphaUserID is set to the alpha_user reference _ref : “managed/alpha_user/”, where id is the id of the managed alpha_user found in the array.
  • Finally we push this relationship object to the array and once we are done iterating through the array, we return the array_of_users with the relationships in it.

Run reconciliation one more time and you should see the role members match exactly what you have in AD:

LiveSync

There are cases where we do not only want to migrate the group membership from AD to ID Cloud but also keep it in sync. In case we still need to change group membership information in AD, we will configure LiveSync in ID Cloud to keep this information always synchronized.

Open the IDM native console and go to Configure -> Schedule and click on the “ New Schedule” button. Configure the LiveSync as follow:

In my lab I configured LiveSync to run every 10 seconds. It will run and synchronize the delta between last time the LiveSync executed and the current one.

You are done.

--

--