# Deploy Caddy configuration

Caddy is a modern web server written in Go with automatic HTTPS capabilities. It supports integration with authentication services via its `forward_auth` directive, which works similarly to Traefik’s `forwardAuth`.

Added in version 2.19.0.

Since Caddy’s `forward_auth` behavior is identical to Traefik’s `forwardAuth`, LemonLDAP::NG uses the same handler for both servers: `SOURCE_SERVER=traefik`.

## PSGI server

Caddy does not support FastCGI for authentication (it doesn’t implement `FCGI_ROLE=AUTHORIZER`), so it must work with a PSGI server exposing an HTTP socket. See Advanced PSGI usage.

For example, to use the handler with uWSGI, exposing an HTTP socket binding on 127.0.0.1:8183:

    cd /usr/share/lemonldap-ng/llng-server && SOURCE_SERVER=traefik /sbin/uwsgi \
      --plugin psgi \
      --psgi llng-server.psgi \
      --master \
      --workers 2 \
      --max-worker-lifetime 86400 \
      --max-requests 10000 \
      --disable-logging \
      --harakiri 30 \
      --buffer-size 65535 \
      --limit-post 0 \
      --die-on-term \
      --http-socket 127.0.0.1:8183

Note

Use `SOURCE_SERVER=traefik` - this handler works for both Traefik and Caddy since they have identical `forward_auth` / `forwardAuth` behavior.

## Handler behavior

The Traefik handler (used for both Traefik and Caddy):

- Reads `X-Forwarded-*` headers sent by Caddy

- Returns 302/303 redirects directly (unlike Nginx which requires conversion to 401)

- Passes headers through directly using Caddy’s `copy_headers` directive

## Caddy configuration

### Basic Caddyfile

Here is a basic configuration example:

    # Portal LemonLDAP::NG
    auth.example.com {
        reverse_proxy llng-portal:9090
    }

    # Manager LemonLDAP::NG
    manager.example.com {
        reverse_proxy llng-manager:9090
    }

    # Protected application
    app.example.com {
        # Security: remove headers that could be forged by malicious users
        request_header -Auth-User
        request_header -Auth-Mail
        request_header -Auth-Groups
        request_header -Lm-Remote-User

        forward_auth llng-handler:8184 {
            uri /
            copy_headers {
                Auth-User
                Auth-Mail
                Auth-Groups
                Lm-Remote-User
            }
        }

        reverse_proxy backend:8080
    }

The `forward_auth` directive:

- Sends the original request information via `X-Forwarded-*` headers

- On 2xx response: copies specified headers to the original request

- On non-2xx response: returns the response to the client (including redirects to the login portal)

### Headers configuration

Use `copy_headers` to specify which headers should be copied from the authentication response to the original request:

    forward_auth llng-handler:8184 {
        uri /
        copy_headers {
            Auth-User
            Auth-Mail
            Auth-Groups
            Lm-Remote-User
            Lm-Remote-Custom
        }
    }

Warning

It is highly recommended to prefix your exported headers with `Auth-` to make it easier to prevent header injection attacks. Always remove these headers before the `forward_auth` directive using `request_header -HeaderName`.

### Passing headers to backend

After authentication, you can pass headers to the backend using `header_up` in the `reverse_proxy` directive:

    reverse_proxy backend:8080 {
        header_up X-Remote-User {http.request.header.Auth-User}
        header_up X-Remote-Mail {http.request.header.Auth-Mail}
    }

### Docker/Kubernetes example

In a containerized environment, your Caddyfile might look like:

    :80 {
        handle /health {
            respond "OK" 200
        }

        handle {
            request_header -Auth-User
            request_header -Auth-Mail

            forward_auth llng-handler:8184 {
                uri /
                copy_headers Auth-User Auth-Mail Lm-Remote-User
            }

            reverse_proxy {$BACKEND_URL}
        }
    }

## Security considerations

### Header injection prevention

Always remove headers that could be forged by malicious users before authentication:

    # Remove all headers that LLNG might set
    request_header -Auth-*
    request_header -Lm-Remote-User
    request_header -Lm-Remote-Custom

    forward_auth llng-handler:8184 {
        # ...
    }

## See also

- Deploy Traefik configuration

- Deploy Nginx configuration

- Advanced PSGI usage

- Handler architecture