LDAP directories are the cockroaches of enterprise IT — they survive everything. Organizations that modernized their web apps to microservices and moved their databases to the cloud still have OpenLDAP or Active Directory at the center of their identity infrastructure, often running on hardware that should have been recycled years ago.
The pressure to modernize is mounting. Windows Server 2025 tightens LDAP signing requirements. OpenLDAP’s maintainer situation remains precarious. And every new SaaS app wants OIDC or SAML, not an LDAP bind.
What “LDAP Modernization” Actually Means
There’s a spectrum, from tactical fixes to full replacement:
Level 1 — Front the LDAP with a modern IdP: Keep the LDAP directory as the data store, add Keycloak/Okta/Entra ID in front of it. Applications talk to the modern IdP via OIDC/SAML, which then authenticates against LDAP behind the scenes.
Level 2 — Sync and shift: Synchronize LDAP identities to a cloud directory, migrate applications one by one, and eventually decommission the LDAP.
Level 3 — Full replacement: Export everything from LDAP, import into a cloud-native identity store, update all applications, and shut down LDAP entirely.
Most organizations end up at Level 2 — Level 3 is only practical for smaller deployments with modern application stacks.
The LDAP Dependency Audit
Before anything else, understand how LDAP is actually used in your environment. Run a packet capture or LDAP access log analysis:
# Enable OpenLDAP access logging
# Add to slapd.conf or cn=config:
# overlay accesslog
# logdb cn=accesslog
# logops reads writes
# Or capture LDAP traffic (non-SSL) for quick analysis
tcpdump -i eth0 port 389 -w ldap-traffic.pcap
# For LDAPS, enable LDAP server-side logging instead
Categorize LDAP operations by type:
| Operation Type | Example | Migration Impact |
|---|---|---|
| Bind (authentication) | User login via LDAP bind | Replace with OIDC/SAML auth |
| Search (user lookup) | App searches for user email or group membership | Replace with IdP API or SCIM |
| Search (service discovery) | App resolves service accounts or config | Migrate to config management |
| Modify (self-service) | Password changes, profile updates | Replace with IdP self-service portal |
| Modify (provisioning) | HR system creates/updates accounts | Replace with SCIM provisioning |
The bind operations are usually straightforward to replace. The search operations are the headache — every application has different search filters, base DNs, and attribute expectations.
Schema Mapping
LDAP schemas don’t map 1:1 to modern IdP attribute models. Build a mapping table:
| LDAP Attribute | OID | Mapping Target (Entra ID) | Mapping Target (Okta) | Mapping Target (Keycloak) |
|---|---|---|---|---|
uid | 0.9.2342.19200300.100.1.1 | onPremisesSamAccountName | login | username |
mail | 0.9.2342.19200300.100.1.3 | mail | email | email |
cn | 2.5.4.3 | displayName | displayName | firstName + lastName |
memberOf | 1.2.840.113556.1.2.102 | Group membership | Group membership | Group membership |
employeeNumber | 2.16.840.1.113730.3.1.3 | employeeId | employeeNumber (custom) | User attribute |
departmentNumber | 2.16.840.1.113730.3.1.2 | department | department (custom) | User attribute |
For custom schema attributes (OIDs unique to your organization), you’ll need to create custom attributes in the target IdP. Every modern IdP supports this, but the mechanisms differ.
Migration Approaches by Target
LDAP → Keycloak
Keycloak has the smoothest LDAP migration path because it can use LDAP as a User Federation backend:
- Configure LDAP User Federation pointing to your existing directory
- Set Import Users to ON — Keycloak copies user data to its own database
- Applications authenticate via Keycloak (OIDC/SAML)
- Once all apps are migrated off direct LDAP, disable the LDAP federation
- Users exist natively in Keycloak’s database
Password handling: Keycloak validates passwords against LDAP during the federation period. Once LDAP is removed, users need to reset their passwords (or you can force a password reset during the federation period to capture passwords in Keycloak’s format).
// Keycloak LDAP Federation config (REST API)
{
"name": "corp-ldap",
"providerId": "ldap",
"providerType": "org.keycloak.storage.UserStorageProvider",
"config": {
"vendor": ["other"],
"connectionUrl": ["ldaps://ldap.corp.local:636"],
"bindDn": ["cn=svc-keycloak,ou=services,dc=corp,dc=local"],
"bindCredential": ["password"],
"usersDn": ["ou=people,dc=corp,dc=local"],
"usernameLDAPAttribute": ["uid"],
"uuidLDAPAttribute": ["entryUUID"],
"importEnabled": ["true"],
"syncRegistrations": ["false"],
"fullSyncPeriod": ["3600"],
"changedSyncPeriod": ["60"]
}
}
LDAP → Entra ID
If you’re already in the Microsoft ecosystem:
- Deploy Entra Cloud Sync agent on a server with LDAP connectivity
- Configure attribute mapping in the Azure portal
- Cloud Sync creates Entra ID users from LDAP entries
- Use Password Hash Sync if the source is Active Directory
- For non-AD LDAP, users need password reset or staged rollout with federated auth
Gotcha: Entra Cloud Sync works best with Active Directory. For pure OpenLDAP sources, you may need a custom sync solution using Microsoft Graph API.
LDAP → Okta
- Deploy the Okta LDAP Agent on a server with network access to your LDAP
- Configure the LDAP integration in Okta admin console
- Map LDAP attributes to Okta profile attributes
- Enable JIT (Just-In-Time) provisioning or scheduled import
- Okta authenticates against LDAP during the transition period
Okta’s LDAP agent handles both authentication delegation and user import, making the coexistence period relatively smooth.
Handling Direct LDAP Dependencies
The hardest migration challenge: applications that make raw LDAP queries.
Identify Them
Look for:
- Application config files with
ldap://orldaps://URIs - Code that imports LDAP libraries (
ldap3in Python,javax.naming.ldapin Java,System.DirectoryServicesin .NET) - Connection strings containing port 389 or 636
Migration Options
Option 1: Modify the application — Replace LDAP bind/search with OIDC authentication and API-based user lookup. This is the right long-term answer but requires development work.
Option 2: LDAP proxy — Deploy a lightweight LDAP proxy that translates LDAP operations to the new IdP’s API:
- GLAuth — Minimal LDAP proxy that can be backed by various data sources
- Keycloak LDAP protocol — Keycloak can serve as an LDAP server to legacy apps (limited feature set)
- lldap — Lightweight LDAP server for simple authentication and basic operations
Option 3: Maintain a read-only LDAP replica — Sync data from the cloud IdP back to a minimal LDAP instance. Applications continue making LDAP queries, but the source of truth is the cloud IdP.
This isn’t elegant, but some legacy applications (especially commercial software with hardcoded LDAP dependencies) may never get updated. The LDAP replica approach keeps them running while everything else modernizes.
Data Quality Cleanup
LDAP directories that have been running for 10+ years inevitably have:
- Orphaned accounts: Employees who left but were never deprovisioned
- Duplicate entries: Same person with multiple
uidvalues - Inconsistent attributes: Some entries have
mail, others haveemail, some have both - Stale groups: Groups that no application references
- Oversized entries: Binary data (photos, certificates) stored as attributes
Clean this up before migration, not after. Import garbage into your shiny new cloud IdP and you’ll have garbage with a nicer UI.
# Find accounts with no login in 90+ days (OpenLDAP with ppolicy overlay)
ldapsearch -x -H ldaps://ldap.corp.local -D "cn=admin,dc=corp,dc=local" -W \
-b "ou=people,dc=corp,dc=local" \
"(&(objectClass=person)(pwdLastSuccess<=20251105000000Z))" \
uid mail pwdLastSuccess
Timeline Estimates
| Organization Size | LDAP Entries | Applications Using LDAP | Estimated Duration |
|---|---|---|---|
| Small | < 500 | < 10 | 2-4 months |
| Medium | 500-5,000 | 10-50 | 4-8 months |
| Large | 5,000-50,000 | 50-200 | 8-18 months |
| Enterprise | 50,000+ | 200+ | 12-24 months |
The limiting factor is almost always application migration, not user migration. Moving 50,000 users takes a few hours. Migrating 200 applications off direct LDAP queries takes months of development work, testing, and coordination.
