Skip to content

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.

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:

Terminal window
ldapsearch -H ldap://localhost:10389 -x -D "u:alice" -W \
-b "ou=users,dc=example,dc=com" "(cn=john*)" cn mail

For all listener settings (host binding, client certificates, socket options, connection limits), see Configuration Reference.

Scribe authenticates LDAP bind requests locally using the unified auth infrastructure. Several bind DN formats are supported:

Bind DN formatExampleHow it works
bearer:<token>bearer:eyJhbGci...JWT or opaque token — password is ignored
dn:<dn>dn:uid=alice,ou=users,dc=example,dc=comExplicit DN + password
u:<username>u:aliceUsername + password, DN resolved via search
Plain valuealice or uid=alice,...Smart detection — DN-like strings bind by DN, others resolve as username
Terminal window
# Bind with bearer token
ldapsearch -H ldap://localhost:10389 -x \
-D "bearer:eyJhbGciOiJSUzI1NiJ9..." -w "ignored" \
-b "ou=users,dc=example,dc=com" "(cn=*)"
# Bind with username
ldapsearch -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.

The LDAP channel supports Proxy Authorization V2 (RFC 4370) for delegation — a service account binds, then acts on behalf of a user:

Terminal window
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

Proxy authorization to backend LDAP

Client
Scribe
Backend LDAP
1
BIND dn=service
2
BIND success
3
SEARCH (proxyAuth: dn=user)
4
BIND dn=service
5
BIND success
6
SEARCH (proxyAuth: dn=user)
7
Results (ACL enforced)
8
Results
  1. Bind establishes the service identity (who’s calling)
  2. ProxyAuth establishes the subject identity (on whose behalf)
  3. The backend receives operations with a ProxyAuth control containing the resolved effective DN

All authentication happens locally within Scribe. The upstream LDAP server only sees the resolved DN.

Standard LDAP search with filters, scopes, and attribute selection:

Terminal window
# Subtree search with filter and specific attributes
ldapsearch -H ldap://localhost:10389 -x -D "..." -W \
-b "ou=users,dc=example,dc=com" \
-s sub "(|(cn=john*)(mail=*@example.com))" cn mail uid

Use Simple Paged Results for large result sets:

Terminal window
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.

Server-Side Sorting works on indexed attributes:

Terminal window
ldapsearch -H ldap://localhost:10389 -x -D "..." -W \
-b "ou=users,dc=example,dc=com" \
-E sss=-sn "(objectClass=inetOrgPerson)"

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.

SymptomCheck
Can't contact LDAP serverListener 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.