Authentication daemon for nginx-proxied or nginx-served applications.
- Create virtual environment for the daemon:
virtualenv env - Activate it:
. ./env/bin/activate - Install dependencies:
pip install -r requirements.txt -r requirements-run.txt - Create config file in TOML format, see Daemon Configuration. NB! You need to override default
SESSION_SALT,DES_KEY, andJWT_PRIVATE_KEYfor security. - Setup env variable
DAEMON_SETTINGSpointing to your.tomlconfig file. - Run daemon with your favorite WSGI server, e.g.
gunicorn nginxauthdaemon.wsgi:app. - Update nginx.conf. See NGINX Configuration.
- Reload nginx (
nginx -t reload). - Test your setup.
- Build:
docker build -t nginxauthdaemon . - Launch:
docker run -p 5000:5000 -v $(pwd)/example.toml:/app/config.toml -e DAEMON_SETTINGS=/app/config.toml -e WEB_CONCURRENCY=4 nginxauthdaemon - Compose file located in
docker-compose.yml.sample
virtualenv env && . ./env/bin/activate
pip install -r requirements.txt
pip install -r requirements-run.txtThis project uses SpecKit for AI-assisted specification, planning, and task management. To set up the development environment with SpecKit:
- Install the SpecKit CLI integration for your AI coding assistant (Claude Code, Copilot CLI, etc.).
- The
.specify/directory contains project templates and the constitution — these are not committed to the repository. - Run
/speckit-constitutionto initialize project principles on a fresh clone. - Use
/speckit-specify,/speckit-plan, and/speckit-tasksfor feature development workflows.
DAEMON_SETTINGS=/path/to/config.toml python -m nginxauthdaemon.nginxauthdaemon
# Or with gunicorn:
DAEMON_SETTINGS=/path/to/config.toml gunicorn -b 0.0.0.0:5000 -k gthread --threads 4 nginxauthdaemon.wsgi:appConfiguration uses TOML format. Point DAEMON_SETTINGS environment variable to your .toml config file.
Basic configuration properties (TOML field names are lowercase):
| Option | Description |
|---|---|
realm_name |
Realm name shown on login page |
session_cookie |
Session cookie name. Typically you do not need to change this. |
target_header |
Header used to pass protected URL from NGINX |
session_salt |
Long string used as salt for creation of session key. Must override. |
des_key |
8-byte DES encryption key. Must override. |
authenticator |
Authenticator type: "crowd" (default) or "dummy" (test only) |
jwt_private_key |
RSA private key in PEM format for access token signing. Must override. |
auth_url_prefix |
URL prefix for auth routes (default: /auth) |
testing |
Set to true to enable DummyAuthenticator (default: false) |
Available authenticators (set via authenticator config field):
| Value | Description |
|---|---|
"crowd" |
Atlassian Crowd based authenticator (default, production use) |
"dummy" |
Simplest authenticator checking username equals password (test only, requires testing = true) |
Crowd authenticator additional options (required when authenticator = "crowd"):
| Option | Description |
|---|---|
crowd_url |
Crowd server URL, e.g. https://localhost:8095/crowd/ |
crowd_app_name |
Crowd application name |
crowd_app_password |
Crowd application password |
| Option | Description |
|---|---|
jwt_private_key |
RS256 secret key for access token signing |
access_token_cookie |
Access token cookie name |
Your NGINX should be compiled with ngx_http_auth_request_module. Check using nginx -V.
Example configuration:
upstream auth-backend {
server 127.0.0.1:5000;
}
location = /auth/validate {
internal;
proxy_pass http://auth-backend;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
}
location = /auth/login {
proxy_pass http://auth-backend;
proxy_set_header X-Target $request_uri;
}
# Protected application
location / {
auth_request /auth/validate;
# redirect 401 and 403 to login form
error_page 401 403 =200 /auth/login;
}Install haproxy-auth-request script from https://github.com/TimWolla/haproxy-auth-request/
Sample HAProxy config (thanks to Dmitry Kamenskikh):
global
log /dev/log local0
log /dev/log local1 notice
chroot /var/lib/haproxy
stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners
stats timeout 30s
user haproxy
group haproxy
daemon
lua-load /usr/share/haproxy/auth-request.lua
defaults
log global
mode http
option httplog
option dontlognull
timeout connect 5000
timeout client 50000
timeout server 50000
frontend main
mode http
bind :80
acl management path_beg /management
acl login_page path -i /auth/login
http-request lua.auth-request auth_request /auth/validate if management
acl login_success var(txn.auth_response_successful) -m bool
http-request add-header X-target %[path] if management
http-request set-path /auth/login if management ! login_success
use_backend auth_request if login_page
default_backend just200
backend just200
server main 172.17.0.1:3000 check
backend auth_request
mode http
server main 172.17.0.1:5000 checkDaemon can be extended to support LDAP or any other auth method, but it supports only Atlassian Crowd for now. PRs with new auth methods are welcome.
The reference implementation is subject to MIT License.