LDAP and Active Directory
403), and the Directory choice is dimmed in the console.A directory authority takes the username and password from the ordinary sign-in form and asks the directory itself. No button appears on the sign-in page: there is nowhere to send the browser.
The order is: the local password first, and if that says no, each enabled directory in turn. Someone whose local and directory passwords happen to match comes in through the directory only once local accounts are disabled.
directory unavailable line in the log, and the person sees the ordinary "wrong username or password". If local accounts are disabled as well, the sign-in form is still drawn and nobody can get in at all.The fields
Infra > Authentication > New authority > Directory.
| Field | What to put in it |
|---|---|
| Dialect | Directory (OpenLDAP and friends) or Active Directory. It picks the defaults below |
| Server URL | the scheme is chosen, not typed: ldaps://dc1.acme.io:636 or ldap://... |
| Search base | where the search starts, dc=acme,dc=io |
| Service account | the DN that performs the search, never a sign-in: cn=meerkat,ou=services,dc=acme,dc=io. Leave it empty for an anonymous search |
| Service password | its password, or a vault reference |
| User filter | %s is replaced by what the person typed, escaped. Empty uses the dialect default |
| Follow nested groups | on by default: a group that contains a group counts |
| Skip the certificate check | for a self-signed directory only |
What a dialect decides, when you leave the matching field empty:
| Directory | Active Directory | |
|---|---|---|
| User filter | (&(objectClass=inetOrgPerson)(uid=%s)) |
(&(objectClass=user)(sAMAccountName=%s)) |
| Username attribute | uid |
sAMAccountName |
| Name attribute | cn |
displayName |
| E-mail attribute | mail |
mail |
| Groups read from | a search by member or uniqueMember |
the memberOf attribute, then a nested-membership search |
usernameAttr, emailAttr, nameAttr, groupBaseDn, groupFilter, groupIdAttr, memberOfAttr) but have no box in the console: they are set through the admin API or an imported configuration file. Everything else is on the screen.Search, then bind
That is the whole sequence, and it matters because the service account never sees anybody's password:
- an empty username or an empty password is refused immediately - an empty password is an anonymous bind, and an anonymous bind succeeds;
- connect;
- bind as the service account, if one is configured;
- search the subtree from the search base with the user filter, at most two entries. No entry means "wrong username or password". Two or more entries and the sign-in is refused, naming the ambiguity, rather than picking one;
- bind as the person, with the DN just found and the password they typed. That is the only use the password is put to;
- bind back as the service account before reading groups;
- read the identity: the entry's DN becomes the stable subject, plus username, full name, e-mail and groups.
An address that comes from a directory is treated as verified: a directory is authoritative about its own people. That is what lets a directory sign-in adopt an existing local account holding the same address.
Group names are the leaf of the DN, not the DN: cn=developer,ou=groups,dc=acme,dc=io is reported as developer. They become memberships and roles through a group rule on an organisation.
TLS
TLS happens when, and only when, the URL starts with ldaps://. The minimum version is TLS 1.2. There is no StartTLS on port 389, no client certificate and no custom certificate authority: for a directory with a self-signed certificate, the honest option on the screen is Skip the certificate check.
Test the connection
The button connects, binds the service account, and runs your user filter once against a name nobody has. It therefore proves the URL, the certificate, the service account and that the search base and filter parse - which is most of what a first setup gets wrong.
Two things a directory does that a redirect authority cannot
It re-validates. When someone signs in with a passkey, Meerkat asks the directory whether it still knows that person before letting them through. A clear "no such object" revokes the sign-in; any other error means "could not ask", and nobody is signed out because a server was briefly unreachable. Identity providers reached by redirect have no such question, so they never revoke a passkey sign-in.
It can be the only authority. With local accounts disabled and a directory enabled, the sign-in form is still the way in - it is the directory's form as much as the local one.