Skip to main content

LDAP User Store

ICP can authenticate users against an external LDAP directory instead of the built-in credentials database. The LDAP adapter supports standard LDAP servers (OpenLDAP, 389 Directory Server, etc.) and Active Directory.

Prerequisites
  • The LDAP server is reachable from the host running ICP.
  • A service account (bind DN + password) with read access to user and group entries exists, or your LDAP server allows anonymous bind.
  • You know the base DN under which users are stored (e.g. ou=Users,dc=wso2,dc=org).

Configuration​

All LDAP settings are top-level keys in conf/deployment.toml. Only ldapUserStoreEnabled = true is strictly required to activate the adapter; all other keys have defaults.

Step 1: Activate the adapter​

ldapUserStoreEnabled = true

Step 2: Configure the server connection​

ldapHostName = "ldap.example.com"   # default: localhost
ldapPort = 10389 # default: 10389; use 636 for LDAPS

# Service-account credentials used to search the directory.
# Omit (leave empty) for anonymous bind.
ldapConnectionName = "uid=admin,ou=system"
ldapConnectionPassword = "secret"
KeyDefaultDescription
ldapUserSearchBaseou=Users,dc=wso2,dc=orgBase DN for user searches
ldapUserNameAttributeuidAttribute that holds the login username
ldapUserSearchFilter(&(objectClass=person)(uid=?))Filter to locate a user; ? is replaced with the username
ldapUserDNPattern(empty)Optional shortcut to construct the DN directly without a search (see below)
ldapDisplayNameAttribute(empty)Attribute used as the display name in ICP; leave empty to use the username

ldapUserDNPattern avoids a search round-trip by constructing the DN from the username directly. Use {0} as the placeholder:

ldapUserDNPattern = "uid={0},ou=Users,dc=wso2,dc=org"

If the pattern is set, ldapUserSearchFilter and the admin bind are not used for authentication (though they are still used for group lookup if ldapMemberOfAttribute is not set).

Step 4: Configure group and role lookup​

ICP reads groups solely to determine whether a user should be granted super-admin access. All other access control is managed through ICP's own user management. Two strategies are supported.

Strategy A: memberOf (Active Directory and some standard LDAP servers)​

The user entry contains a memberOf attribute that lists the DNs of every group the user belongs to. This is the most efficient strategy.

ldapMemberOfAttribute = "memberOf"

When this is set, the group-search settings below are ignored.

Strategy B: Group membership search (standard LDAP)​

ICP searches the group subtree for entries whose membership attribute contains the user's DN.

ldapGroupSearchBase     = "ou=Groups,dc=wso2,dc=org"   # default
ldapGroupNameAttribute = "cn" # default
ldapGroupSearchFilter = "(objectClass=groupOfNames)" # default
ldapMembershipAttribute = "member" # default; or "uniqueMember"

For posixGroup schemas where membership is stored as plain usernames rather than full DNs, set:

ldapMembershipAttribute = "memberUid"

Set ldapReadGroups = false to skip group lookup entirely (no user will receive super-admin via LDAP roles).

Step 5: Configure admin role mapping​

List the LDAP group names (the value of ldapGroupNameAttribute, not the full DN) whose members should become ICP super-admins on first login:

ldapAdminRoles = ["icp-admins", "administrators"]

The comparison is case-sensitive. A user is placed in the ICP Super Admins group the first time they log in with a matching role. Subsequent role changes in LDAP are not reflected automatically.

TLS (LDAPS)​

For production deployments, enable TLS:

ldapSslEnabled = true

# Path to a JKS truststore containing the LDAP server's CA certificate.
# If omitted, certificate verification is disabled (not recommended for production).
ldapTrustStorePath = "../conf/security/ldap-truststore.jks"
ldapTrustStorePassword = "truststore-password"

To import a CA certificate into the truststore:

keytool -importcert -alias ldap-ca \
-file /path/to/ldap-ca.crt \
-keystore ../conf/security/ldap-truststore.jks \
-storepass truststore-password

Directory-specific examples​

OpenLDAP (inetOrgPerson + groupOfNames)​

ldapUserStoreEnabled   = true

ldapHostName = "ldap.example.com"
ldapPort = 389
ldapConnectionName = "cn=admin,dc=example,dc=com"
ldapConnectionPassword = "admin-password"

ldapUserSearchBase = "ou=people,dc=example,dc=com"
ldapUserNameAttribute = "uid"
ldapUserSearchFilter = "(&(objectClass=inetOrgPerson)(uid=?))"
ldapDisplayNameAttribute = "cn"

ldapGroupSearchBase = "ou=groups,dc=example,dc=com"
ldapGroupNameAttribute = "cn"
ldapGroupSearchFilter = "(objectClass=groupOfNames)"
ldapMembershipAttribute = "member"

ldapAdminRoles = ["icp-admins"]

OpenLDAP (posixAccount + posixGroup)​

ldapUserSearchBase       = "ou=people,dc=example,dc=com"
ldapUserNameAttribute = "uid"
ldapUserSearchFilter = "(&(objectClass=posixAccount)(uid=?))"
ldapDisplayNameAttribute = "cn"

ldapGroupSearchBase = "ou=groups,dc=example,dc=com"
ldapGroupNameAttribute = "cn"
ldapGroupSearchFilter = "(objectClass=posixGroup)"
ldapMembershipAttribute = "memberUid"

ldapAdminRoles = ["icp-admins"]

Active Directory​

ldapHostName           = "dc01.corp.example.com"
ldapPort = 389
ldapConnectionName = "CN=svc-icp,OU=Service Accounts,DC=corp,DC=example,DC=com"
ldapConnectionPassword = "service-account-password"

ldapUserSearchBase = "OU=Users,DC=corp,DC=example,DC=com"
ldapUserNameAttribute = "sAMAccountName"
ldapUserSearchFilter = "(&(objectClass=user)(sAMAccountName=?))"
ldapDisplayNameAttribute = "displayName"

# AD populates memberOf on the user entry — no separate group search needed
ldapMemberOfAttribute = "memberOf"
ldapGroupNameAttribute = "cn"

ldapAdminRoles = ["ICP Admins"]

For AD over LDAPS (port 636):

ldapPort               = 636
ldapSslEnabled = true
ldapTrustStorePath = "../conf/security/ad-truststore.jks"
ldapTrustStorePassword = "truststore-password"

How it works​

On login the adapter:

  1. Resolves the user's LDAP Distinguished Name (DN) — either directly from a pattern or via a directory search.
  2. Authenticates the user by attempting an LDAP bind with their DN and password.
  3. Reads the user's group memberships from the directory.
  4. If any group matches a configured admin role, the user is granted ICP super-admin (by adding them to the built-in Super Admins group). This happens only on the user's first login and is not re-evaluated on subsequent logins.
  5. Returns a stable, deterministic user ID (UUID v5 derived from the username and search base) so the same LDAP user always maps to the same ICP user record.

Troubleshooting​

SymptomCauseFix
Login returns 401 with no error in logsUser not found in directoryCheck ldapUserSearchBase and ldapUserSearchFilter; verify the username attribute matches the login name
Login returns 500 "Authentication service unavailable"Cannot reach LDAP serverCheck ldapHostName, ldapPort, firewall rules
Users can log in but are never super-adminGroup names don't matchldapAdminRoles values must match the ldapGroupNameAttribute value exactly (case-sensitive)
TLS handshake failureCA certificate not trustedImport the LDAP server's CA cert into the truststore
Users get super-admin on first login but lose it after re-deployExpected behaviourSuper-admin is set once at first login; subsequent changes must be managed via the ICP user management UI
Display name shows as usernameldapDisplayNameAttribute missing on entryVerify the attribute name or set ldapDisplayNameAttribute = "" to always use the username