LDAP and Active Directory sign-in
Delegate password verification to your LDAP or Active Directory server, per organization, with an escaped search filter, fail-closed semantics and just-in-time provisioning. No agent to install.
With an LDAP connection configured, users sign in to Obexal with their directory credentials: Obexal verifies the password against your LDAP or Active Directory server instead of a local password hash. There is no agent to install in your network: Obexal connects directly to the directory over LDAPS or StartTLS, so the server must be reachable from your Obexal deployment. One connection exists per organization.
How delegated authentication works
When a user submits the password form, and the tenant has an enabled LDAP connection, Obexal performs three steps against the directory:
- Service-account bind: Obexal binds with the configured
bindDnand its password. - Search: the user is looked up under
baseDn(whole subtree) with youruserFilter, where%sis replaced by the email typed at sign-in, escaped per RFC 4515 (no filter injection). Only the DN and the email attribute are requested. An ambiguous result (more than one entry) is refused. Each operation has a 10 second timeout. - User bind: Obexal binds as the found DN with the password the user typed. The successful bind is the proof of identity; the directory password is never stored, hashed or cached by Obexal.
An empty password is refused before the directory is even contacted: on many servers (Active Directory included) an empty bind succeeds as an anonymous bind, which would otherwise be an authentication bypass.
Configure the connection
Configuration requires the tenant:manage permission (console session or an obx_ admin API token):
curl -sS -X PUT https://accounts.obexal.com/v1/admin/ldap \
-H "Authorization: Bearer $OBEXAL_API_TOKEN" -H 'Content-Type: application/json' \
-d '{
"enabled": true,
"serverUrl": "ldaps://dc1.example.eu:636",
"bindDn": "CN=svc-obexal,OU=Service Accounts,DC=example,DC=eu",
"bindPassword": "'$LDAP_BIND_PASSWORD'",
"baseDn": "DC=example,DC=eu",
"userFilter": "(mail=%s)",
"emailAttribute": "mail"
}'
# 204| Field | Meaning |
|---|---|
serverUrl | ldaps://host:636 or ldap://host:389 (required) |
startTls | Upgrade a plain ldap:// connection with StartTLS |
insecureSkipVerify | Skip TLS certificate verification. Development only |
bindDn | Service account used for the search (required) |
bindPassword | Service-account password. Encrypted at rest. Empty on update keeps the current one; required at creation |
baseDn | Search base (required) |
userFilter | Search filter; must contain %s, the placeholder for the escaped email (required) |
emailAttribute | Directory attribute holding the email (default mail) |
For Active Directory, a filter such as (|(mail=%s)(userPrincipalName=%s)) matches users by mailbox address or UPN; every %s receives the escaped email. GET /v1/admin/ldap returns the configuration without the bind password, and DELETE /v1/admin/ldap removes the connection.
Fallback and fail-closed behavior
The outcome of the directory check drives the rest of the sign-in strictly:
- The directory authenticates the user: sign-in continues (MFA, conditional access).
- The user is absent from the directory: Obexal falls back to the local password flow. This is the only fallback, and it exists so purely local accounts (the organization owner, break-glass admins) keep working.
- Anything else fails closed: wrong directory password, unreachable server, TLS failure, ambiguous search result, or a bind password that can no longer be decrypted all produce a firm refusal, with no fallback to a local password. An account disabled in your directory can therefore not sneak in through an old local password. Each refusal counts toward the account lockout counter, like any failed password attempt.
If your LDAP server is down, directory-managed users cannot sign in at all. This is deliberate: availability is never traded against the authority of your directory.
Just-in-time provisioning
After a successful bind, Obexal resolves the account by email (taken from the directory's emailAttribute, or the typed email if that attribute is empty):
- A local account with that email exists: it is used, and its email is marked verified (the directory vouches for it).
- No account exists: one is provisioned just in time, with the email already verified.
Successful sign-ins, provisioning events and refusals are written to the audit log.
MFA and policies still apply
The directory only replaces the primary factor. If the resolved account has an active MFA factor, the challenge happens after the bind, exactly as after a local password: see the MFA checkpoint. Conditional access rules apply as well. Obexal's password policy does not govern directory passwords; those rules live in your directory.
Honest limits
- Authentication only: there is no directory synchronization. Groups, attributes and account states are not imported, and there is no scheduled sync; a directory user exists in Obexal only after their first successful sign-in. For profile synchronization, use inbound SCIM.
- One LDAP connection per organization.
- The lookup key is the email address typed at sign-in; there is no sign-in by sAMAccountName-style short login.
- No password writeback: password changes happen in your directory, not in Obexal.
- Deactivating a user in the directory blocks their directory sign-in, but does not delete their Obexal account or revoke existing sessions.