Skip to content

How OpenEMR authenticates against AD

The application plane closes the loop back to identity. A clinician does not get a second password for the chart: they log into OpenEMR with the same Active Directory credentials they use everywhere else. This page explains the model, because it is subtler than “OpenEMR talks to LDAP.”

OpenEMR’s LDAP integration is bind-as-user. At login it takes the entered username, substitutes it into a DN pattern, and binds to AD as that user with that password. If the bind succeeds, the login is accepted.

login: gregory.house / <AD password>
└─▶ bind gregory.house@ad.supported.systems to ldap://dc1.ad.supported.systems
└─▶ Samba AD validates → bind OK → OpenEMR session granted

The DN pattern is the global gbl_ldap_dn, set to {login}@ad.supported.systems — a userPrincipalName (UPN) bind, which AD accepts directly. There is no service bind account in this flow; each user authenticates as themselves.

LDAP only validates the password. It does not create accounts. So a clinician needs an OpenEMR user whose username equals their AD sAMAccountName, complete with the users + users_secure rows, a UUID, and an ACL role. The lab provisions this with a script that reuses OpenEMR’s own APIs (the same calls the Admin → Users form makes), so the account is whole, not a half-built set of raw rows:

Terminal window
make provision-user U=gregory.house F=Gregory L=House

The break-glass admin account is listed in gbl_ldap_exclusions, so it always uses local auth — your way back in if the DC is unreachable.

Samba’s ldap server require strong auth governs whether a cleartext simple bind is even allowed. Regardless, the lab uses STARTTLS: dropping the DC’s CA certificate at sites/default/documents/certificates/ldap-ca makes OpenEMR negotiate TLS on the connection. With only the CA present (no client cert), OpenEMR uses TLS_TRY mode — encrypted and CA-validated, but lenient about the DC’s autogenerated, CN-only certificate, which strict verification would reject.

Terminal window
make fetch-ca # pull the DC's CA cert into certs/
make ldap-setup # set the gbl_ldap_* globals + install the CA cert

The audit log settles any doubt that the round-trip actually reaches AD:

SELECT date, user, event, success FROM log WHERE event LIKE 'login%' ORDER BY date DESC;
-- gregory.house | login | 1

That password was set only on the domain controller — OpenEMR never held it. A successful login therefore had to bind through STARTTLS to Samba AD. The identity plane authenticated the application plane.

This is one edge of the four-plane architecture: the application plane consuming the identity plane. The runbook for standing it up is in Run the clinical ecosystem.