Connecting Keycloak to external user stores: the concepts of user federation and just-in-time provisioning, LDAP and Active Directory integration, Read Only versus Write-through modes, user and group synchronization, custom user storage with the SPI, and bulk user import strategies.

In episode 14 you connected an application as a SAML service provider and made sure the login flow runs smoothly. Episode 15 turns backstage: where does user identity actually come from? You'll learn user federation — how Keycloak reads users from external stores such as LDAP and Active Directory without duplicating data in every system. This is where Keycloak changes from a mere login portal into the heart of the company's identity management.
User federation is Keycloak's ability to use an external identity source as the basis for its users. Four core ideas you need to hold on to:
The key distinction: federation means Keycloak itself reads users from the external directory; brokering means authentication is directed to another system that holds the credentials.
LDAP is the most common directory protocol in the enterprise, and the LDAP provider is the most frequently used federation in Keycloak. You add it via User Federation in the admin console, choosing the ldap provider. A typical configuration looks like this:
enabled: true
provider_id: ldap
vendor: other
connection_url: ldap://openldap:389
bind_dn: cn=admin,dc=example,dc=com
bind_credential: admin-password
users_dn: ou=users,dc=example,dc=com
edit_mode: READ_ONLY
username_ldap_attribute: uid
rdn_ldap_attribute: uid
uuid_ldap_attribute: entryUUID
user_object_classes: inetOrgPerson, organizationalPerson, person
import_enabled: true
sync_registrations: trueldap://openldap:389 is the connection URL to the LDAP server; port 389 for plain LDAP, 636 for encrypted LDAPS. bind_dn is the account Keycloak uses to read the directory — preferably a dedicated read-only account, not the directory admin.
ou=users.inetOrgPerson is the most common.username_ldap_attribute, rdn_ldap_attribute, and uuid_ldap_attribute connect the LDAP entry to the Keycloak user model.The LDAP provider has a write mode that determines what happens when a user is changed through Keycloak:
| Mode | Behavior | When to use |
|---|---|---|
| Read Only | Keycloak only reads; user changes are rejected or only apply in Keycloak | Directory held by another system |
| Write-through | User changes are written straight back to LDAP | Keycloak becomes the primary management point |
| Unsynced | LDAP data is fully copied and held by Keycloak | Full migration to Keycloak |
Read Only is the safest choice: you never risk damaging a directory maintained by another system. Write-through only makes sense when your team has full control over the directory.
With import_enabled, users who successfully log in automatically get a copy in the Keycloak database. Keycloak also runs periodic (scheduled) synchronization to align the data, and allows manual synchronization at any time. User attributes in Keycloak can be set to be read from LDAP at login, so changes in the directory are immediately visible.
Warning
Read Only mode combined with user import can create confusion: passwords are still validated in LDAP, but the user profile is stored in Keycloak. Document clearly where profile changes should be written so teams don't overwrite each other's data.
Active Directory is essentially LDAP with a Microsoft schema. For AD integration, the vendor is selected as Active Directory so the attribute mappings (such as sAMAccountName and objectGUID) adjust automatically. Group synchronization also works: AD groups can be mapped to Keycloak groups, then inherited by imported users.
For environments already based on Kerberos, Keycloak provides a Kerberos provider that enables passwordless login on registered hosts — similar to the cross-realm concept you learned in the Kerberos series. It's used for integration with Active Directory connected to the Keycloak realm, and is generally paired with a protocol mapper that reads the principal from the token.
Not all user stores take the form of LDAP. Keycloak provides the User Storage SPI (Service Provider Interface) that lets you write your own provider for any data source:
Custom providers implement interfaces such as UserLookupProvider, UserQueryProvider, and CredentialInputValidator. Because this is Java code deployed as a module, writing it requires framework understanding and thorough testing before production use.
For stores that are fully moved into Keycloak, you import users at scale:
TOKEN=$(curl -s -d "client_id=admin-cli&username=admin&password=admin&grant_type=password" \
http://localhost:8080/realms/master/protocol/openid-connect/token | jq -r .access_token)
while IFS="," read -r user email; do
curl -s -X POST http://localhost:8080/admin/realms/demo/users \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d "{\"username\":\"$user\",\"email\":\"$email\",\"enabled\":true}"
done < users.csvgrant_type=password with the admin-cli client is a compact way to obtain an admin token. Also note: never write plaintext passwords in a CSV file; set a temporary password and require a reset on first login.
In this episode 15, you connected Keycloak to external user stores: the federation concept, just-in-time provisioning and synchronization; LDAP configuration with connection URL, bind DN, and object classes; the difference between Read Only and Write-through; Active Directory and Kerberos integration; custom user storage through the SPI; and bulk user import strategies.
Key takeaways:
In the next episode (episode 16), we add another entrance: social login and identity brokering — letting users sign in with Google, GitHub, or Facebook accounts, and linking them to internal identities through first broker login.