ICF 1.5.20.29

Configuring ldapGroups in the LDAP connector

The LDAP Connector includes a special virtual attribute, ldapGroups, which simplifies managing LDAP group memberships. This topic explains the functionality of ldapGroups, provides configuration instructions, details important considerations, and best practices.

LDAP group membership

In standard LDAP directories, such as PingDS or Active Directory (AD), directory servers typically store group membership information on the group entry, not the user entry. A group object contains a list of its members, often as distinguished names (DNs) pointing to user entries (for example, using the member or uniqueMember attribute).

By default, a user entry doesn’t list the groups to which it belongs, so a client application could need to search numerous group entries to determine a user’s group memberships. To simplify this process, most directory servers provide a computed attribute on the user entry that dynamically lists the groups where the user is a member.

  • In PingDS, this attribute is isMemberOf.

  • In AD, this attribute is memberOf.

These attributes are valuable for reading membership information but are read-only. You cannot directly modify a user’s memberOf or isMemberOf attribute to change group memberships; you must modify the actual group entry’s member list.

Example: memberOf in AD

A query for an AD user might return:

dn: CN=user five,OU=test1,DC=example,DC=com
...
memberOf: CN=testgroup,OU=test1,DC=example,DC=com
...

Example: isMemberOf in PingDS (DS)

A query for a DS user, requesting the isMemberOf attribute, might return:

dn: uid=user.3,ou=People,dc=example,dc=com
...
isMemberOf: cn=Test Group,ou=groups,dc=example,dc=com
...
Directory servers often do not return these calculated attributes by default because their computation incurs a performance cost. You typically need to request these attributes in LDAP searches.

ldapGroups: A connector-level solution

The ldapGroups attribute is a feature specific to the LDAP Connector. It functions as a writable proxy for managing group memberships directly using the user object within IDM.

When you map and use ldapGroups:

  • Reads (GET operations): The connector determines the user’s group memberships. By default, it does this by searching group entries on the target directory for the user’s DN (for example, searching for (member=<userDN>) or (uniqueMember=<userDN>)).

  • Writes (Update operations): When you add or remove group DNs from the ldapGroups attribute in IDM and save the user object, the connector translates these changes into the necessary LDAP modify operations against the group entries on the target directory (adding or removing the user’s DN from the group’s member list).

This mechanism lets you manage group assignments within IDM (for example, through role assignments) without directly interacting with group objects.

Configuration

To use ldapGroups, configure it in the LDAP connector’s provisioner file (provisioner.openicf-ldap.json or similar) and include it in the user object mapping.

1. Add ldapGroups to the connector schema

Add the following definition to the account object type within the connector configuration’s objectTypes section:

"ldapGroups" : {
  "type" : "array",
  "nativeType" : "string",
  "nativeName" : "ldapGroups",
  "required" : false,
  "items" : {
    "type" : "string",
    "nativeType" : "string"
  }
}

2. Update user mapping

The goal of this step is to produce a list of group DN values for ldapGroups during the synchronization process. There are a variety of methods which you can use, including:

  • Property mappings

  • An onUpdate script

  • Role assignment processing

Ensure the synchronization mapping (sync.json) for the user object includes a mapping for ldapGroups. For example:

{
    "source": "ldapGroups",
    "target": "ldapGroups"
}

If you manage assignments using roles, configure the role assignment to target the ldapGroups attribute. You can also grant roles to users directly. Learn more in Roles in the PingIDM documentation.

Example: Assigning AD groups using roles

  1. Configure the connector and mapping as described previously.

  2. Create an internal role (for example, "AD Finance Group Users").

  3. In the admin UI, navigate to the role’s Managed Assignments (or equivalent section).

  4. Create a new assignment targeting the appropriate AD connector or mapping.

  5. Select the ldapGroups attribute.

  6. Select the desired AD group (for example, CN=Finance Users,OU=Groups,DC=example,DC=com) from the provided list.

  7. Save the assignment and the role.

Assigning this IDM role to a user automatically adds that user to the specified AD group. Learn more in Working with role assignments in the PingIDM documentation.

Performance and functional considerations

Although ldapGroups offers convenience, it’s crucial to understand its implications.

Performance cost

  • Default read behavior: By default, ldapGroups requires the connector to search group entries on the target directory. This makes read operations (such as GET User or reconciliation) consume more resources. The connector performs an additional search for each user to identify the static groups they belong to. This slows performance when querying for many users with ldapGroups included or, to a lesser extent, users who are members of many groups.

  • Update behavior: Updates involving ldapGroups also add overhead. The connector must determine the user’s current group memberships (often involving another search), calculate the difference between the current state and the desired state, and then execute LDAP modify operations on the relevant group entries. This can slow performance when updating groups with many members.

Functional limitations (default behavior)

  • Static groups only: By default, ldapGroups discovers and manages only memberships in static groups (those that have explicit member or uniqueMember attributes). It does not recognize or manage memberships from:

  • Dynamic groups: Groups where rules or LDAP URLs determine membership (common in DS).

  • Nested groups: Groups that contain other groups as members.

  • Incomplete view: Relying only on ldapGroups (using default settings) to ascertain a user’s effective group memberships might give an incomplete picture if your environment uses dynamic or nested groups.

ldapGroups compared to memberOf and isMemberOf

Feature

ldapGroups

memberOf and isMemberOf

Purpose

Read/write proxy for group membership

Read-only view of group membership

Scope

Static groups only

All group types (static, dynamic, nested)

Writable?

Yes (using connector logic)

No (read-only virtual attribute)

Read cost

Higher (connector searches groups)

Lower (directory calculates; often faster)

Managed by

LDAP Connector

Target directory server

The ldapGroupsUseStaticGroups parameter

To address performance and functional limitations, the LDAP connector includes the ldapGroupsUseStaticGroups configuration parameter (located in the main connector configuration file, provisioner.openicf-ldap.json).

  • false (default): ldapGroups operates as described previously, searching static group entries. This approach is safer for updates involving mixed group types but has performance drawbacks and limits visibility to static groups.

  • true: ldapGroups uses the directory’s memberOf (AD) or isMemberOf (DS) virtual attribute for reading group memberships.

  • Pros: Improves read and query performance; includes dynamic and nested groups in the results that ldapGroups returns.

  • Cons: Presents high risk for updates. If IDM tries to modify memberships derived from dynamic or nested groups (which isMemberOf or memberOf might return), the connector could attempt inappropriate LDAP operations (such as modifying a dynamic group as if it were static). This can lead to errors (for example, DS schema violation code 65) and failed updates. Use this setting only if the environment exclusively uses static groups and you have thoroughly tested it.

Base context filtering

  • When ldapGroupsUseStaticGroups is false (default), the connector’s search for static groups follows the baseContexts defined in the connector configuration. The connector considers only groups within these specified base contexts.

  • When ldapGroupsUseStaticGroups is true, the memberOf or isMemberOf attribute returns all groups the user belongs to, regardless of the connector’s baseContexts setting. This happens because the directory server typically does not filter the virtual attribute itself by base context.

AD considerations

  • AD primarily uses static groups, which makes the default ldapGroups behavior suitable.

  • AD’s memberOf attribute does not natively display nested memberships unless the query includes a specific LDAP control (LDAP_SERVER_CHAINING_OID: 1.2.840.113556.1.4.1941). The connector’s use of memberOf (when ldapGroupsUseStaticGroups is true) might or might not retrieve nested memberships, depending on internal implementation specifics.

Recommendations and best practices

  1. Understand the trade-offs: Recognize that ldapGroups offers convenience but affects performance and potentially adds complexity, particularly when different group types exist in the environment.

  2. Prefer memberOf or isMemberOf for reading: To view a user’s complete group memberships, you should map the directory’s native memberOf or isMemberOf attribute as read-only ("flags": ["NOT_CREATABLE", "NOT_UPDATEABLE"]). This method is generally more efficient and comprehensive than reading ldapGroups.

  3. Use ldapGroups cautiously for writing: If IDM must manage group memberships:

    • Keep the ldapGroupsUseStaticGroups setting as false (the default) unless you confirm the environment uses only static groups and you’ve performed comprehensive testing.

      If you can’t guarantee that only static groups are used and want to update the static groups, use a transform script. Create logic which filters all of the non-static groups from the isMemberOf group DN list. This allows you make reasonable updates to static groups without the high performance cost of reading ldapGroups.
    • Consider adding the "flags": ["NOT_RETURNED_BY_DEFAULT"] to the ldapGroups definition within the provisioner file. This flag prevents the performance degradation that calculating ldapGroups causes during default read operations, such as reconciliation synchronization checks, while still allowing you to use it explicitly in updates or specific requests.

    • Add the NOT_RETURNED_BY_DEFAULT flag to optimize read performance:

      {
        "ldapGroups": {
          "type": "array",
          "nativeType": "string",
          "nativeName": "ldapGroups",
          "required": false,
          "items": {
            "type": "string",
            "nativeType": "string"
          },
          "flags": [
            "NOT_RETURNED_BY_DEFAULT"
          ]
        }
      }
  4. Index directory attributes: Ensure the directory server indexes the member (AD) or uniqueMember (DS) attributes on group objects. Indexing is critical to lessen the performance impact when ldapGroups searches static groups (ldapGroupsUseStaticGroups: false). Consult the directory server documentation for indexing best practices.

  5. Alternative: Manage group objects: The most technically direct LDAP approach involves managing memberships by modifying the group objects directly within IDM (assuming you synchronize group objects). However, this method often requires more complex configuration and scripting compared to using ldapGroups through role assignments.

By understanding how ldapGroups operates and its associated trade-offs, you can configure it effectively to meet group management requirements while minimizing performance impacts and avoiding potential issues.