Lightweight LDAP/AD authentication proxy and FastAPI middleware
Project description
LDAPGate
Lightweight LDAP/AD authentication gateway for Python web apps. Install it, configure it, done.
Features
- Two deployment modes — standalone reverse proxy or drop-in FastAPI middleware
- Pure Python LDAP — no OS-level libs required, uses
ldap3 - Signed cookie sessions — stateless, no server-side session storage
- OpenLDAP and Active Directory —
uid=andsAMAccountName=out of the box - Optional group gating — restrict access to members of a specific LDAP group
- Header injection — injects
X-Forwarded-Userfor apps that support it - Bundled login form — responsive, dark/light mode, works air-gapped
Install
pip install ldapgate
Config file
Both modes share the same ldapgate.yaml:
ldap:
url: ldaps://dc.example.com:636
bind_dn: CN=svc,CN=Users,DC=example,DC=com
bind_password: secret
base_dn: DC=example,DC=com
user_filter: "(sAMAccountName={username})" # AD; OpenLDAP: (uid={username})
group_dn: CN=app-users,CN=Users,DC=example,DC=com # optional
proxy:
listen_host: 0.0.0.0
listen_port: 9000
backend_url: http://localhost:8080
secret_key: change-me-to-something-random
session_ttl: 3600
user_header: X-Forwarded-User
login_path: /_auth/login
app_name: MyApp
All settings can also be provided via environment variables with __ separators (e.g. LDAP__URL, PROXY__SECRET_KEY).
Corporate / Active Directory setup
For corp AD environments with mutual TLS or custom CA certificates (e.g. NiFi, internal PKI), see docs/nifi-ldap-integration.md for a step-by-step guide covering cert extraction, bind DN formats, and common error codes.
Pre-flight check: before configuring LDAPGate, fill in the variables at the top of ldap_check.py and run it to verify connectivity end-to-end:
python ldap_check.py
# All checks passed. LDAPGate should work with this config.
It confirms your bind credentials work, the user search returns results, and TLS validates correctly. If cert validation against an internal CA isn't feasible, set tls_validate: NONE in the ldap: section.
Restricting access to specific users: use allowed_users as a simple local allowlist (no AD group required):
ldap:
# ... other settings ...
allowed_users:
- alice
- bob
Mode 1 — Standalone Reverse Proxy
Run ldapgate as a standalone process in front of any app. Only authenticated requests are forwarded to the backend.
Browser → ldapgate :9000 → backend app :8080
ldapgate serve --config ldapgate.yaml
Example: copyparty
Start copyparty with IDP header auth and point its logout at ldapgate:
copyparty -p 8080 --idp-h-usr X-Forwarded-User --idp-logout /_auth/logout -v ~/Documents:/:rw
copyparty trusts the X-Forwarded-User header injected by ldapgate, and its logout button redirects to /_auth/logout which clears the ldapgate session before sending the user back to the login page.
WebDAV mounting (Windows & Mac)
LDAPGate supports HTTP Basic auth for WebDAV clients — they authenticate directly without going through the browser login flow. Any client that sends an Authorization: Basic header (Windows WebDAV, macOS Finder, curl) is verified against LDAP on each request.
Windows — mount as a drive letter (Windows will prompt for credentials if omitted):
net use w: http://host:port /user:username password
macOS Finder — Go → Connect to Server → enter http://host:port
macOS Terminal:
osascript -e 'mount volume "http://host:port"'
# or with credentials embedded:
osascript -e 'mount volume "http://user:pass@host:port"'
For copyparty specifically, launch it with --rproxy 1 and --xff-src set to LDAPGate's address so it trusts the injected header:
copyparty -p 8989 --rproxy 1 --xf-proto-fb http --xff-src=10.52.0.0/16 \
--idp-h-usr X-Forwarded-User --idp-logout /_auth/logout \
-v /path/to/share:/:rw
Mode 2 — FastAPI Middleware
Drop ldapgate auth directly into an existing FastAPI app — no separate process needed.
from fastapi import FastAPI
from ldapgate.config import load_config
from ldapgate.middleware import add_ldap_auth
app = FastAPI()
config = load_config("ldapgate.yaml")
add_ldap_auth(app, config)
@app.get("/api/data")
async def data(request):
return {"user": request.state.user} # authenticated username
Example: lagun — see lagun and torrus for real-world integrations.
CLI Options
ldapgate serve --config PATH Path to ldapgate.yaml [default: ldapgate.yaml]
--host TEXT Override listen host
--port INTEGER Override listen port
--backend TEXT Override backend URL
--reload Enable auto-reload (dev)
Development
Requires uv.
git clone https://github.com/anudeepd/ldapgate
cd ldapgate
uv sync
pytest tests/
License
MIT
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ldapgate-0.1.3.tar.gz.
File metadata
- Download URL: ldapgate-0.1.3.tar.gz
- Upload date:
- Size: 288.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.10.12 {"installer":{"name":"uv","version":"0.10.12","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"CachyOS Linux","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e279316261c1405d702dd35702d37d7a194afa2021318025af91afae4e74c4cb
|
|
| MD5 |
2b7d7042aae1583f5c5e522ae0b9dfe2
|
|
| BLAKE2b-256 |
3796c0dde379181cb549d3fa097ebf6a75da6abd5daadafa6ffad6297edf6ed4
|
File details
Details for the file ldapgate-0.1.3-py3-none-any.whl.
File metadata
- Download URL: ldapgate-0.1.3-py3-none-any.whl
- Upload date:
- Size: 112.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.10.12 {"installer":{"name":"uv","version":"0.10.12","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"CachyOS Linux","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1578db2e2ec23ba4350ee04c5d99814356d82e5af751c7d540d4e0c58fb64dd7
|
|
| MD5 |
99dadce4731ece5bcba63bf269b6962a
|
|
| BLAKE2b-256 |
1f6ea2db40e132d79cb3fb920460c64dbad5cf79fcdeb3eb5525ad39930150b4
|