# LDAP

Server Pro provides LDAP server integration for user authentication and is compatible with Active Directory systems. For Toolkit deployments, the LDAP integration is configured via the `config/variables.env` file.

### Overview

Internally, the LDAP integration uses the [passport-ldapauth](https://github.com/vesse/passport-ldapauth) library. Most of these configuration options are passed through to the `server` config object which is used to configure `passport-ldapauth`. If you are having issues configuring LDAP, it is worth reading the [README](https://github.com/vesse/passport-ldapauth/blob/master/README.md) for `passport-ldapauth` to get a feel for the configuration it expects.

To enable LDAP authentication the `EXTERNAL_AUTH` variable **must** be set to `ldap`:

```
EXTERNAL_AUTH=ldap
```

After bootstrapping Server Pro for the first time with LDAP authentication, an existing LDAP user must be given admin permissions by visiting the `/launchpad` page (or via [CLI](/on-premises/user-and-project-management/user-management.md#via-the-command-line), but in this case ignoring password confirmation).

LDAP users will appear in Overleaf Admin Panel once they log in first time with their initial credentials.

{% hint style="info" %}
To preserve backward compatibility with older configuration files, if `EXTERNAL_AUTH` is not set, but `OVERLEAF_LDAP_URL` is set, then the LDAP module will be activated. We still recommend setting `EXTERNAL_AUTH` explicitly.
{% endhint %}

### Configuration

<table data-full-width="false"><thead><tr><th>Name</th><th>Description</th></tr></thead><tbody><tr><td><code>OVERLEAF_LDAP_URL</code></td><td><strong>Required</strong>, The URL of the LDAP server, E.g. <code>ldaps://ldap.example.com:636</code></td></tr><tr><td><code>OVERLEAF_LDAP_EMAIL_ATT</code></td><td>The email attribute the LDAP server will return, defaults to <code>mail</code></td></tr><tr><td><code>OVERLEAF_LDAP_NAME_ATT</code></td><td>The property name holding the name of the user which is used in the application</td></tr><tr><td><code>OVERLEAF_LDAP_LAST_NAME_ATT</code></td><td>If your LDAP server has a first and last name then this can be used in conjunction with <code>OVERLEAF_LDAP_NAME_ATT</code></td></tr><tr><td><code>OVERLEAF_LDAP_PLACEHOLDER</code></td><td>The placeholder for the login form, defaults to <strong>Username</strong></td></tr><tr><td><code>OVERLEAF_LDAP_UPDATE_USER_DETAILS_ON_LOGIN</code></td><td>If set to <code>true</code>, will update the user <strong>first_name</strong> and <strong>last_name</strong> field on each login, and turn off the user-details form on /user/settings page. Otherwise, details will be fetched only on first login.</td></tr><tr><td><code>OVERLEAF_LDAP_BIND_DN</code></td><td><strong>Optional</strong>, e.g. <code>uid=admin,ou=people,o=planetexpress.com</code>.</td></tr><tr><td><code>OVERLEAF_LDAP_BIND_CREDENTIALS</code></td><td>Password for <code>bindDn</code>.</td></tr><tr><td><code>OVERLEAF_LDAP_BIND_PROPERTY</code></td><td><strong>Optional</strong>, default <code>dn</code>. Property of user to bind against client e.g. <strong>name</strong>, <strong>email</strong></td></tr><tr><td><code>OVERLEAF_LDAP_SEARCH_BASE</code></td><td>The base DN from which to search for users by username. E.g. <code>ou=people,o=planetexpress.com</code></td></tr><tr><td><code>OVERLEAF_LDAP_SEARCH_FILTER</code></td><td>LDAP search filter with which to find a user by username, e.g. <code>(uid={{username}})</code>. Use the literal <code>{{username}}</code> to have the given username be interpolated in for the LDAP search. If you are using Active Directory then the search filter <code>(sAMAccountName={{username}})</code> may be more appropriate.</td></tr><tr><td><code>OVERLEAF_LDAP_SEARCH_SCOPE</code></td><td><strong>Optional</strong>, default <code>sub</code>. Scope of the search, one of <code>base</code>, <code>one</code>, or <code>sub</code>.</td></tr><tr><td><code>OVERLEAF_LDAP_SEARCH_ATTRIBUTES</code></td><td><strong>Optional</strong>, default all. Json array of attributes to fetch from LDAP server.</td></tr><tr><td><code>OVERLEAF_LDAP_GROUP_DN_PROPERTY</code></td><td><strong>Optional</strong>, default <code>dn</code>. The property of user object to use in <code>{{dn}}</code> interpolation of <code>groupSearchFilter</code>.</td></tr><tr><td><code>OVERLEAF_LDAP_GROUP_SEARCH_BASE</code></td><td><strong>Optional</strong>. The base DN from which to search for groups. If defined, also <code>groupSearchFilter</code> must be defined for the search to work.</td></tr><tr><td><code>OVERLEAF_LDAP_GROUP_SEARCH_SCOPE</code></td><td><strong>Optional</strong>, default <code>sub</code>.</td></tr><tr><td><code>OVERLEAF_LDAP_GROUP_SEARCH_FILTER</code></td><td><strong>Optional</strong>. LDAP search filter for groups. The following literals are interpolated from the found user object: <code>{{dn}}</code> the property configured with <code>groupDnProperty</code>. Optionally you can also assign a function instead, which passes a user object, from this a dynamic <code>groupSearchFilter</code> can be retrieved.</td></tr><tr><td><code>OVERLEAF_LDAP_GROUP_SEARCH_ATTRIBUTES</code></td><td><strong>Optional</strong>, default all. Json array of attributes to fetch from LDAP server.</td></tr><tr><td><code>OVERLEAF_LDAP_CACHE</code></td><td><strong>Optional</strong>, default <code>false</code>. If <code>true</code>, then up to 100 credentials at a time will be cached for 5 minutes.</td></tr><tr><td><code>OVERLEAF_LDAP_TIMEOUT</code></td><td><strong>Optional</strong>, default <strong>Infinity</strong>. How long the client should let operations live for in milliseconds before timing out.</td></tr><tr><td><code>OVERLEAF_LDAP_CONNECT_TIMEOUT</code></td><td><strong>Optional</strong>, default is up to the OS. How long the client should wait in milliseconds before timing out on TCP connections.</td></tr><tr><td><code>OVERLEAF_LDAP_TLS_OPTS_CA_PATH</code></td><td>A JSON array of paths to the CA file for TLS, must be accessible to the Docker container. E.g. <code>-env OVERLEAF_LDAP_TLS_OPTS_CA_PATH='["/var/one.pem", "/var/two.pem"]'</code></td></tr><tr><td><code>OVERLEAF_LDAP_TLS_OPTS_REJECT_UNAUTH</code></td><td>If <code>true</code>, the server certificate is verified against the list of supplied CAs.</td></tr><tr><td><code>OVERLEAF_LDAP_IS_ADMIN_ATT</code> and <code>OVERLEAF_LDAP_IS_ADMIN_ATT_VALUE</code></td><td>When <strong>both</strong> environment variables are set, the login process updates <code>user.isAdmin = true</code> when the profile returned by LDAP contains <code>OVERLEAF_LDAP_IS_ADMIN_ATT</code>, and its value is either equals to <code>OVERLEAF_LDAP_IS_ADMIN_ATT_VALUE</code>, or an array containing <code>OVERLEAF_LDAP_IS_ADMIN_ATT_VALUE</code>.<br><br><strong>Introduced:</strong> <code>5.2.0</code></td></tr></tbody></table>

### Example configuration

At Overleaf, we test the LDAP integration against a [test openldap server](https://github.com/rroemhild/docker-test-openldap). The following is an example of a working configuration:

```
# added to variables.env

EXTERNAL_AUTH=ldap
OVERLEAF_LDAP_URL=ldap://ldap:389
OVERLEAF_LDAP_SEARCH_BASE=ou=people,dc=planetexpress,dc=com
OVERLEAF_LDAP_SEARCH_FILTER=(uid={{username}})
OVERLEAF_LDAP_BIND_DN=cn=admin,dc=planetexpress,dc=com
OVERLEAF_LDAP_BIND_CREDENTIALS=GoodNewsEveryone
OVERLEAF_LDAP_EMAIL_ATT=mail
OVERLEAF_LDAP_NAME_ATT=cn
OVERLEAF_LDAP_LAST_NAME_ATT=sn
OVERLEAF_LDAP_UPDATE_USER_DETAILS_ON_LOGIN=true
```

The `openldap` needs to run in the same network as the `sharelatex` container (which by default would be `overleaf_default`), so we'll proceed with the following steps:

* Run `docker network create overleaf_default` (will possibly fail due to a `network with name overleaf_default already exists` error, that's OK).
* Start `openldap` container with `docker run --network=overleaf_default --name=ldap rroemhild/test-openldap:1.1`
* Edit `variables.env` to add the LDAP environment variables as listed above.
* Run `bin/up -d` and you should be able to login using `fry` as both username and password.

### Debugging

As LDAP is heavily configurable and flexible by nature it can be a good starting point to have a working example with `ldapsearch` or even used by another application.

The following command will connect to the LDAP server at `ldap` on port `389`. It will then bind to the server using the distinguished name (DN) `admin@planetexpress.com` and password `password123`. The base DN for the search will be `ou=people,dc=planetexpress,dc=com`. The search filter is set to return entries where the Common Name (CN) contains `fry`, and it will return the `mail` attribute of these entries.

When running this search command against your own service please ensure that you replace `fry`, `password123`, and `planetexpress.com` with your actual username, password, and domain. Also, make sure that the LDAP server is accessible and the provided details are correct:

{% code overflow="wrap" %}

```bash
ldapsearch -H ldap://ldap:389 -x -D admin@planetexpress.com -w password123 -b ou=people,dc=planetexpress,dc=com "CN=*fry*" mail
```

{% endcode %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.overleaf.com/on-premises/configuration/overleaf-toolkit/server-pro-only-configuration/ldap.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
