Who this is for
You want only people in your directory (OpenLDAP, Active Directory, Samba AD or Authentik’s LDAP outpost) to start meetings on your Jitsi server. Guests should still be able to join once a host is in. You want hosts to use their normal directory password.
How it works
The chain. Jitsi Meet shows a login dialog. Prosody receives the username and password with SASL PLAIN and hands them to Cyrus SASL through mod_auth_cyrus. Cyrus SASL sends them to the saslauthd daemon over a local socket. saslauthd searches the directory with ldap_filter, then binds as the user to check the password. Prosody never talks to LDAP itself.
Docker specifics. With AUTH_TYPE=ldap, the prosody container renders /run/saslauthd.conf from the LDAP_* variables. If you mount your own /etc/saslauthd.conf, that file is copied instead. It starts saslauthd -a ldap -O /run/saslauthd.conf -c -m /var/run/saslauthd -n 5 -d. -c caches credentials and -d logs to the container output. Prosody uses authentication = "cyrus" with cyrus_application_name = "xmpp" and allow_unencrypted_plain_auth = true. The image ships /etc/sasl/xmpp.conf with pwcheck_method: saslauthd and mech_list: PLAIN.
What changed with rootless containers. Since stable-11146, Prosody and saslauthd run as user s6 (uid 1000) on a read-only root filesystem. Config is rendered into /run. Mounting your own /etc/saslauthd.conf still works, because the script only reads it. On stable-11146 to 11146-2, saslauthd could fail with could not open pid lock file: /var/run/saslauthd/saslauthd.pid.lock because that folder was owned by root. This was reported on Podman and fixed in stable-11248 by PR #2312.
Who becomes moderator. Jicofo auth follows ENABLE_AUTH in Docker, and an authenticated Jicofo makes every logged-in user a moderator. So to limit who can host, restrict the LDAP filter, for example to a group.
Future note. A Jitsi maintainer wrote in June 2026 that “native LDAP will be going away at some point” and suggested OIDC for new setups.
Before you start
- Jitsi with HTTPS at
https://meet.example.com: docker-jitsi-meet stable-11248, or packages 2.0.11248 with secure domain set up. - A service account that can search the directory, and its DN.
- The base DN where users live, and the attribute users will type as their login:
uid(OpenLDAP),sAMAccountName(AD), orcn(Authentik, whereuidis a generated identifier). - Network access from the prosody container or host to the directory: usually 389 (LDAP or StartTLS) or 636 (LDAPS).
- For TLS with a private CA: the root CA certificate in PEM format.
Steps
Docker (docker-jitsi-meet stable-11248)
-
Choose your directory settings in
.env. Common to all:ConfigENABLE_AUTH=1 ENABLE_GUESTS=1 AUTH_TYPE=ldap LDAP_AUTH_METHOD=bind LDAP_VERSION=3OpenLDAP:
ConfigLDAP_URL=ldaps://ldap.example.com/ LDAP_BASE=ou=people,dc=example,dc=com LDAP_BINDDN=cn=jitsi,ou=services,dc=example,dc=com LDAP_BINDPW=REPLACE_WITH_BIND_PASSWORD LDAP_FILTER=(uid=%u)Active Directory (handbook example filter). The group clause uses AD’s
memberOfattribute:ConfigLDAP_URL=ldaps://dc1.example.com/ LDAP_BASE=DC=example,DC=com LDAP_BINDDN=CN=jitsi,OU=Service Accounts,DC=example,DC=com LDAP_BINDPW=REPLACE_WITH_BIND_PASSWORD LDAP_FILTER=(&(sAMAccountName=%u)(memberOf=CN=Jitsi Hosts,OU=Groups,DC=example,DC=com))Authentik LDAP outpost. The bind DN form comes from Authentik’s docs, and the working filter and port come from issue #2259:
ConfigLDAP_URL=ldap://203.0.113.10:3389/ LDAP_BASE=dc=ldap,dc=goauthentik,dc=io LDAP_BINDDN=cn=jitsi-service,ou=users,dc=ldap,dc=goauthentik,dc=io LDAP_BINDPW=REPLACE_WITH_APP_PASSWORD LDAP_FILTER=(cn=%u)If users type
alice@example.com, use%U(the user part) instead of%u. -
Turn on certificate checks. The image sets
TLS_REQCERT allowin/etc/ldap/ldap.conf. Withallow, a bad certificate “will be ignored and the session proceeds normally”. saslauthd only enforces checks whenldap_tls_check_peeris set, and the template only writes it when both of these are on:ConfigLDAP_USE_TLS=1 LDAP_TLS_CHECK_PEER=1For a private CA on stable-11248, put the PEM file in
~/.jitsi-meet-cfg/prosody/config/. That folder is mounted at/config. Then point to it:ConfigLDAP_TLS_CACERT_FILE=/config/ldap-ca.crtFor StartTLS, use an
ldap://URL and setLDAP_START_TLS=1. Newer images add a${CONFIG}/prosody/custom-cafolder (PR #2334), but it is not in a stable release yet. -
Recreate Prosody so the new environment is rendered:
Terminaldocker compose up -d --force-recreate prosody -
Test the password check inside the container with the service name Prosody uses (
xmpp):Terminaldocker compose exec prosody testsaslauthd -u alice -p 'REPLACE_WITH_PASSWORD' -s xmpp -f /var/run/saslauthd/mux -
Test the bind and lookup with ldapsearch. The prosody image has no
ldap-utils, and its root filesystem is read-only. Run a throwaway Debian container on the same network instead:TerminalNET=$(docker network ls --format '{{.Name}}' | grep 'meet.jitsi$') docker run --rm -it --network "$NET" debian:trixie-slim sh -c ' apt-get update -qq && apt-get install -y -qq ldap-utils >/dev/null && ldapsearch -x -H ldaps://ldap.example.com -D "cn=jitsi,ou=services,dc=example,dc=com" -W \ -b "ou=people,dc=example,dc=com" "(uid=alice)" dn uid cn sAMAccountName'For a private CA, add
-v ~/.jitsi-meet-cfg/prosody/config/ldap-ca.crt:/ca.crt:ro -e LDAPTLS_CACERT=/ca.crttodocker run.
Debian/Ubuntu packages (2.0.11248)
-
Install the SASL pieces:
Terminalsudo apt-get install sasl2-bin libsasl2-modules-ldap lua-cyrussasl prosody-modules sudo prosodyctl install --server=https://modules.prosody.im/rocks/ mod_auth_cyrus -
Create
/etc/saslauthd.confusing the same keys the Docker template writes:Configldap_servers: ldaps://ldap.example.com ldap_bind_dn: cn=jitsi,ou=services,dc=example,dc=com ldap_bind_pw: REPLACE_WITH_BIND_PASSWORD ldap_auth_method: bind ldap_search_base: ou=people,dc=example,dc=com ldap_filter: (uid=%u) ldap_tls_check_peer: yes ldap_tls_cacert_file: /etc/ssl/certs/ca-certificates.crt -
Test, then enable the service:
Terminalsudo saslauthd -d -a ldap sudo testsaslauthd -u alice -p 'REPLACE_WITH_PASSWORD' sudo sed -i -e "s/START=.*/START=yes/" -e "s/MECHANISMS=.*/MECHANISMS=\"ldap\"/" /etc/default/saslauthd sudo service saslauthd restartRun the first command in one terminal, the test in a second, then stop the first with Ctrl+C before enabling the service.
-
Create the Cyrus config for Prosody in
/etc/sasl/prosody.conf(the name matches the defaultcyrus_application_name):Terminalsudo mkdir -p /etc/sasl printf 'pwcheck_method: saslauthd\nmech_list: PLAIN\n' | sudo tee /etc/sasl/prosody.conf -
Switch Prosody to Cyrus and give it socket access:
Terminalsudo sed -i -E -e "/^ *VirtualHost \"$(hostname -f)\"/,/^ *VirtualHost/ {s/authentication ?=.*$/authentication = \"cyrus\"/}" /etc/prosody/conf.avail/$(hostname -f).cfg.lua sudo adduser prosody sasl sudo service prosody restart
Configuration reference
| Name | Where | Default | What it does |
|---|---|---|---|
AUTH_TYPE |
Docker .env |
internal |
ldap renders /run/saslauthd.conf and loads auth_cyrus |
LDAP_URL |
Docker .env |
none | ldap_servers |
LDAP_BASE |
Docker .env |
none | ldap_search_base |
LDAP_BINDDN / LDAP_BINDPW |
Docker .env |
unset (anonymous) | ldap_bind_dn / ldap_bind_pw |
LDAP_FILTER |
Docker .env |
uid=%u |
ldap_filter |
LDAP_AUTH_METHOD |
Docker .env |
bind |
ldap_auth_method |
LDAP_VERSION |
Docker .env |
3 |
ldap_version |
LDAP_USE_TLS |
Docker .env |
0 |
Enables the TLS block below |
LDAP_TLS_CHECK_PEER |
Docker .env |
0 |
ldap_tls_check_peer: yes, only with LDAP_USE_TLS=1 |
LDAP_TLS_CACERT_FILE / LDAP_TLS_CACERT_DIR |
Docker .env |
/etc/ssl/certs/ca-certificates.crt / /etc/ssl/certs |
CA trust for peer checks |
LDAP_TLS_CIPHERS |
Docker .env |
unset | ldap_tls_ciphers |
LDAP_START_TLS |
Docker .env |
0 |
ldap_start_tls: yes, needs ldap:// |
ENABLE_GUESTS |
Docker .env |
0 |
Guests join on the anonymous domain once a host is in |
cyrus_application_name |
Prosody VirtualHost | prosody (Docker sets xmpp) |
Name of /etc/sasl/<name>.conf |
allow_unencrypted_plain_auth |
Prosody VirtualHost | unset (Docker sets true) |
Allows PLAIN without TLS |
TLS_REQCERT |
/etc/ldap/ldap.conf |
allow in the Docker image |
libldap certificate policy |
Filter tokens: %u is the user, %U the user part before @, %d the domain part, %r the realm.
Common mistakes
auth failure: [user=alice] [service=xmpp] [realm=meet.jitsi] [mech=ldap] [reason=Unknown]. In issue #2259 the service bind worked but the filter matched nobody. Thenot found, update pendingline just before it is the credential cache missing, not the directory. Check the attribute with ldapsearch. In Authentik,uidis a hash, so usecn=%uorsAMAccountName=%u. Also check that the user is underLDAP_BASE.No available SASL mechanisms, verify that the configured authentication module 'cyrus' is loaded and configured correctly. The auth module did not load. On Ubuntu 24.04 and newer packages, installprosody-modulesandmod_auth_cyrus. On Docker it came from broken builds: 7210-1 (fixed in 7210-2) and an early hardened image (fixed by PR #2269 before stable-11146).No Cyrus SASL mechanisms availableat Prosody startup. The Cyrus config file is missing or has the wrong name forcyrus_application_name.- Login rejected with
not-authorized. Cyrus returned an authentication failure (SASL_BADAUTH): wrong password, or the user’s bind was refused. Test withtestsaslauthd. could not open pid lock file: /var/run/saslauthd/saslauthd.pid.lock. Upgrade to stable-11248 (PR #2312).- StartTLS with an
ldaps://URL. StartTLS needsldap://. LDAP_TLS_CHECK_PEER=1withoutLDAP_USE_TLS=1. The check is never written, so certificates are not verified.- Packages: Prosody cannot reach the socket.
/var/run/saslauthd/is limited torootand groupsasl, so runadduser prosody sasl. - Setting only
PROSODY_AUTH_TYPE=ldap. The Docker config script checksAUTH_TYPEwhen it renderssaslauthd.conf.
Verify
docker compose exec prosody testsaslauthd -u alice -p 'REPLACE_WITH_PASSWORD' -s xmpp -f /var/run/saslauthd/muxExpect 0: OK "Success.". A wrong password gives 0: NO "authentication failed".
Then log in as host from the browser and watch the logs:
docker compose logs -f prosody | grep -E 'saslauthd|Authenticated as'A working login shows auth success: [user=alice] [service=xmpp] (or auth success (cached) on a repeat), then Authenticated as alice@meet.jitsi (your XMPP_DOMAIN).
Check the rendered config without printing the password:
docker compose exec prosody grep -v bind_pw /run/saslauthd.confIf it still fails
docker compose logs prosody | grep saslauthd. saslauthd runs with-d, so each attempt shows[login=...],[realm=...]and areason.- Bind errors with the right password: check
LDAP_BINDDNwith ldapsearch-Dand-W. - TLS errors after enabling peer checks: the server certificate must chain to
LDAP_TLS_CACERT_FILE, and the URL host must match the certificate name. - Packages: read
/var/log/auth.logforsaslauthdlines. - Everyone in LDAP can host: that is expected. Narrow
LDAP_FILTERto a group.
What we have not confirmed yet
We checked everything above against the docker-jitsi-meet templates and image, the handbook, the cyrus-sasl source and maintainer comments on 2026-10-05. We have not yet tested every directory type against stable-11248. These points are still open:
- Whether the saslauthd lock file error also hit Docker (not only Podman) on stable-11146 to 11146-2.
- How long
saslauthd -ccaches credentials in the container, and whether a password change needs a Prosody restart. - The Docker template writes
ldap_tls_keyandldap_tls_cert(Prosody’s own certificate) whenLDAP_USE_TLS=1. Whether that client certificate causes problems with directories that request one. - Whether
LDAP_TLS_CACERT_FILE=/config/ldap-ca.crtworks as described on stable-11248. Not tested on a real server. - Authentik’s outpost port (3389 in issue #2259) depends on how the outpost container is published. Authentik’s docs only mention 636 for LDAPS.
- Whether Debian 13 (Prosody 13) needs anything beyond the handbook’s Ubuntu 24.04 package list.
- Maintainers have not given a timeline for removing native LDAP.
Sources
- Jitsi handbook, LDAP Authentication, last changed 2025-06-22, official doc
- Jitsi handbook, Self-Hosting Guide: Docker (Authentication using LDAP, Trusting custom CA certificates), source last changed 2026-10-02, official doc
- docker-jitsi-meet prosody/rootfs/defaults/saslauthd.conf at stable-11248, source code
- docker-jitsi-meet prosody s6 scripts config and saslauthd at stable-11248, source code
- docker-jitsi-meet prosody/rootfs/defaults/conf.d/jitsi-meet.cfg.lua at stable-11248, source code
- docker-jitsi-meet prosody/Dockerfile and prosody/rootfs/etc/sasl/xmpp.conf at stable-11248, source code
- mod_auth_cyrus.lua and sasl_cyrus.lua shipped in the prosody image, source code
- docker-jitsi-meet issue #2259 Authentik LDAP: Prosody binds successfully but returns “Unknown” user, 2026-06-19 to 2026-06-20, maintainer comments (saghul, emrahcom) and community solution
- docker-jitsi-meet release stable-11248, PR #2312 and issue #2311, 2026-09-14, release note and community report
- docker-jitsi-meet issue #2267 and PR #2269 fix(prosody): replace the failing mv with cp, merged 2026-06-22, maintainer PR
- docker-jitsi-meet issue #1272 LDAP auth not working with v7210-1, 2022-04-25, maintainer comment (saghul)
- jitsi/handbook PR #544 Update ldap-authentication.md (prosody-modules on Ubuntu 24.04), 2024-12-06, official doc change
- docker-jitsi-meet issue #1358, maintainer comment on “No available SASL mechanisms”, 2022-08-08, maintainer comment (damencho)
- docker-jitsi-meet PR #2334 feat: Add support for custom CA, merged 2026-10-01, maintainer PR (not in a stable release on 2026-10-05)
- docker-jitsi-meet PR #2258 feat: Rootless containers, merged 2026-06-19, maintainer PR
- cyrus-sasl saslauthd/lak.c (config keys, ldap_tls_check_peer, filter tokens), cache.c and saslauthd-main.c (log lines), checked 2026-10-05, source code
- Debian man pages testsaslauthd(8) and saslauthd(8), sasl2-bin 2.1.28, official doc (Debian)
- Debian man pages ldapsearch(1) and ldap.conf(5), official doc (Debian/OpenLDAP)
- Authentik docs, LDAP provider (bind DN, attributes, LDAPS), checked 2026-10-05, official doc (Authentik)
- Microsoft, Member-Of attribute (Active Directory schema), official doc (Microsoft)
- docker-jitsi-meet jicofo.conf template at stable-11248 and jicofo ChatRoomRoleManager.kt, checked 2026-10-05, source code
- docker-jitsi-meet docker-compose.yml at stable-11248 (prosody volumes and LDAP_* environment), 2026-09-14, source code
Need a hand?
Directory logins fail in quiet ways. Contact our engineers with the saslauthd lines from docker compose logs prosody (remove passwords first), or see our support plans.