LDAP Channel
Point your existing LDAP apps at Scribe. They’ll keep working — same protocol, same tools, same queries — but now they’re reading from PostgreSQL instead of hitting your directory server directly.
Quick start
Section titled “Quick start”Configure one or more listeners:
channels.ldap { listen = [ { port = 10389 } # Plain LDAP { port = 10636, ssl { # LDAPS ca = "certs/ca.pem" cert = "certs/server.pem" key = "certs/server-key.pem" }} ]}Test with any LDAP client:
ldapsearch -H ldap://localhost:10389 -x -D "u:alice" -W \ -b "ou=users,dc=example,dc=com" "(cn=john*)" cn mailFor all listener settings (host binding, client certificates, socket options, connection limits), see Configuration Reference.
Authentication
Section titled “Authentication”Scribe authenticates LDAP bind requests locally using the unified auth infrastructure. Several bind DN formats are supported:
| Bind DN format | Example | How it works |
|---|---|---|
bearer:<token> | bearer:eyJhbGci... | JWT or opaque token — password is ignored |
dn:<dn> | dn:uid=alice,ou=users,dc=example,dc=com | Explicit DN + password |
u:<username> | u:alice | Username + password, DN resolved via search |
| Plain value | alice or uid=alice,... | Smart detection — DN-like strings bind by DN, others resolve as username |
# Bind with bearer tokenldapsearch -H ldap://localhost:10389 -x \ -D "bearer:eyJhbGciOiJSUzI1NiJ9..." -w "ignored" \ -b "ou=users,dc=example,dc=com" "(cn=*)"
# Bind with usernameldapsearch -H ldap://localhost:10389 -x \ -D "u:alice" -W \ -b "ou=users,dc=example,dc=com" "(cn=*)"Authentication methods are tried in order (e.g., bearer, then ropc, then ldap). See Authentication for method configuration.
Proxy Authorization
Section titled “Proxy Authorization”The LDAP channel supports Proxy Authorization V2 (RFC 4370) for delegation — a service account binds, then acts on behalf of a user:
ldapsearch -H ldap://localhost:10389 -x \ -D "cn=service,dc=example,dc=com" -W \ -e "authzid=dn:uid=alice,ou=users,dc=example,dc=com" \ -b "ou=users,dc=example,dc=com" "(cn=*)"ProxyAuth accepts the same formats as bind: bearer:<token>, dn:<dn>, u:<username>, or plain values.
Delegation pattern
Section titled “Delegation pattern”Proxy authorization to backend LDAP
- Bind establishes the service identity (who’s calling)
- ProxyAuth establishes the subject identity (on whose behalf)
- The backend receives operations with a
ProxyAuthcontrol containing the resolved effective DN
All authentication happens locally within Scribe. The upstream LDAP server only sees the resolved DN.
Searching
Section titled “Searching”Standard LDAP search with filters, scopes, and attribute selection:
# Subtree search with filter and specific attributesldapsearch -H ldap://localhost:10389 -x -D "..." -W \ -b "ou=users,dc=example,dc=com" \ -s sub "(|(cn=john*)(mail=*@example.com))" cn mail uidPagination
Section titled “Pagination”Use Simple Paged Results for large result sets:
ldapsearch -H ldap://localhost:10389 -x -D "..." -W \ -b "ou=users,dc=example,dc=com" \ -E pr=100/noprompt "(objectClass=inetOrgPerson)"VLV (Virtual List View) is also supported.
Sorting
Section titled “Sorting”Server-Side Sorting works on indexed attributes:
ldapsearch -H ldap://localhost:10389 -x -D "..." -W \ -b "ou=users,dc=example,dc=com" \ -E sss=-sn "(objectClass=inetOrgPerson)"Search delegation
Section titled “Search delegation”Some requests can’t be answered from the local cache — schema queries, unsupported filters, directory browser operations. When that happens, Scribe forwards the request to the upstream LDAP server.
Set channels.ldap.prevent-delegation = true to fail these requests instead of forwarding them. See Configuration Reference for delegation reasons and telemetry.
Common issues
Section titled “Common issues”| Symptom | Check |
|---|---|
Can't contact LDAP server | Listener configured? Port not blocked? |
| ResultCode 49 (INVALID_CREDENTIALS) | Bind DN and password correct? For bearer tokens: token valid and not expired? |
| ResultCode 4 (SIZE_LIMIT_EXCEEDED) | Use pagination (-E pr=100/noprompt) or refine the filter |
See Signals for metrics, Logging and Traces for trace debugging, Error Handling for the complete ResultCode mapping.