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
-
Configure the connector and mapping as described previously.
-
Create an internal role (for example, "AD Finance Group Users").
-
In the admin UI, navigate to the role’s Managed Assignments (or equivalent section).
-
Create a new assignment targeting the appropriate AD connector or mapping.
-
Select the
ldapGroups
attribute. -
Select the desired AD group (for example,
CN=Finance Users,OU=Groups,DC=example,DC=com
) from the provided list. -
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 withldapGroups
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 explicitmember
oruniqueMember
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 |
|
|
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’smemberOf
(AD) orisMemberOf
(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
ormemberOf
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
isfalse
(default), the connector’s search for static groups follows thebaseContexts
defined in the connector configuration. The connector considers only groups within these specified base contexts. -
When
ldapGroupsUseStaticGroups
istrue
, thememberOf
orisMemberOf
attribute returns all groups the user belongs to, regardless of the connector’sbaseContexts
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 ofmemberOf
(whenldapGroupsUseStaticGroups
is true) might or might not retrieve nested memberships, depending on internal implementation specifics.
Recommendations and best practices
-
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. -
Prefer
memberOf
orisMemberOf
for reading: To view a user’s complete group memberships, you should map the directory’s nativememberOf
orisMemberOf
attribute as read-only ("flags": ["NOT_CREATABLE", "NOT_UPDATEABLE"]
). This method is generally more efficient and comprehensive than readingldapGroups
. -
Use
ldapGroups
cautiously for writing: If IDM must manage group memberships:-
Keep the
ldapGroupsUseStaticGroups
setting asfalse
(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 readingldapGroups
. -
Consider adding the
"flags": ["NOT_RETURNED_BY_DEFAULT"]
to theldapGroups
definition within the provisioner file. This flag prevents the performance degradation that calculatingldapGroups
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" ] } }
-
-
Index directory attributes: Ensure the directory server indexes the
member
(AD) oruniqueMember
(DS) attributes on group objects. Indexing is critical to lessen the performance impact whenldapGroups
searches static groups (ldapGroupsUseStaticGroups: false
). Consult the directory server documentation for indexing best practices. -
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.