> ## Documentation Index
> Fetch the complete documentation index at: https://docs.lighton.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Configure LDAP Authentication

> LDAP authentication lets users log in to Paradigm using their corporate directory credentials, without needing a separate Paradigm password.

LDAP (Lightweight Directory Access Protocol) authentication lets users log in to Paradigm using their corporate directory credentials. Unlike SAML and OIDC, Paradigm connects directly to your LDAP server to verify credentials.

## Step 1: Enable LDAP instance-wide

Go to **Paradigm administration > Settings > Config Key Values** and set:

* **`IS_LDAP_ON`**: `True`

<Warning>
  The application must be restarted after enabling LDAP. Authentication will not work until the restart is complete.
</Warning>

## Step 2: Configure LDAP for a company

Go to **Paradigm administration > Authentication > Social Applications** and click **Add**.

### Basic information

* **Provider**: `ldap`
* **Name**: A descriptive name for the admin (e.g., `Acme Corp LDAP`)
* **Company**: Select the company this configuration applies to

### Login URL configuration

Choose one of the following options, or configure both for redundancy:

**Option A — Custom domain**

* **Custom domain**: `login.yourcompany.com`
* Login URL: `https://login.yourcompany.com/login`
* **Required Environment Variable:**

The `DOMAIN` environment variable must be set for constructing LDAP authentication URLs:

```bash theme={null}
# For production (set in .env or deployment config)
DOMAIN=login.yourcompany.com

# For local development (default)
DOMAIN=localhost:8000
```

* Requires DNS configuration (see [DNS setup](#dns-setup) below)

**Option B — Client ID fallback**

* **Client ID**: A lowercase slug with no spaces (e.g., `yourcompany`)
* Login URL: `https://<paradigm_domain>/login/ldap/yourcompany`
* No DNS configuration required

### LDAP settings

In the **Settings** field, enter a JSON object with your LDAP server configuration:

```json theme={null}
{
  "server_uri": "ldaps://ldap.company.com:636",
  "bind_dn": "CN=ldap-service,OU=ServiceAccounts,DC=company,DC=com",
  "bind_password": "your-secure-password",
  "user_search_base": "OU=Users,DC=company,DC=com",
  "user_search_filter": "(mail=%(user)s)",
  "attr_email": "mail",
  "attr_first_name": "givenName",
  "attr_last_name": "sn",
  "use_tls": true,
  "connection_timeout": 5
}
```

| Field                | Description                                                            |
| -------------------- | ---------------------------------------------------------------------- |
| `server_uri`         | LDAP server URL. Use `ldaps://` (port 636) for encrypted connections.  |
| `bind_dn`            | Distinguished Name of the service account used to query the directory. |
| `bind_password`      | Password for the service account.                                      |
| `user_search_base`   | Base DN where user accounts are located.                               |
| `user_search_filter` | Filter to find users. `%(user)s` is replaced with the login username.  |
| `attr_email`         | LDAP attribute containing the user's email address.                    |
| `attr_first_name`    | LDAP attribute for the user's first name.                              |
| `attr_last_name`     | LDAP attribute for the user's last name.                               |
| `use_tls`            | Whether to use TLS. Recommended: `true`.                               |
| `connection_timeout` | Connection timeout in seconds.                                         |

## Step 3: Update Company Login Method

**Django Admin → Authentication → Companies → Select Company**

* Set **Login method** to:
  * `LDAP` (LDAP only)

## Step 4: Verify CNAME Configuration (For Custom Domains)

After the having configured the DNS:

1. **Wait 5-30 minutes** for DNS propagation
2. **In Django Admin** → Social Applications → Open the Social Application
3. **View detailed diagnostics**:
   * Scroll to "CNAME Test Results" section
   * See detailed DNS, HTTP, and middleware checks
4. **Bulk test**: Select multiple apps → Actions → "Test CNAME Configuration"

## DNS setup

If you chose the custom domain option, your client must create a DNS CNAME record pointing their login subdomain to the Paradigm application domain:

```
login.yourcompany.com  →  CNAME  →  app.<paradigm_domain>
```

DNS propagation may take up to 48 hours. Users will not be able to log in via the custom domain until propagation is complete.

## Security recommendations

* Use a **dedicated read-only service account** for LDAP queries. Do not use an admin account.
* Always use **LDAPS** (`ldaps://`, port 636) rather than plain LDAP (port 389) to encrypt credentials in transit.
* Ensure **TLS/SSL** is enabled (`"use_tls": true`).

## Testing the LDAP Configuration

### 1. Test Company Detection

```bash theme={null}
# Test custom domain
curl -H "Host: login.yourcompany.com" https://app.paradigm.com/api/v3/auth/check-company

# Test client_id fallback (from URL path)
curl https://app.paradigm.com/api/v3/auth/check-company
```

**Expected Response**:

```json theme={null}
{
  "company": {
    "id": 123,
    "name": "Your Company"
  },
  "auth_method": "ldap",
  "custom_domain": "login.yourcompany.com",
  "slug": "yourcompany"
}
```

### 2. Test LDAP Connection

Use `ldapsearch` command to verify connectivity:

```bash theme={null}
ldapsearch -H ldaps://ldap.company.com:636 \
  -D "CN=service,DC=company,DC=com" \
  -w "password" \
  -b "OU=users,DC=company,DC=com" \
  "(mail=user@company.com)"
```

**Check**:

* Connection succeeds
* User is found
* Attributes (mail, givenName, sn) are returned

### 3. Test Login Flow

1. Visit login URL (custom domain or slug)
2. Enter LDAP username/email
3. Enter LDAP password
4. Verify:
   * User is authenticated
   * User is auto-provisioned (if new)
   * User lands on the chat interface or the policy acceptance

### 4. Check Audit Logs

**Django Admin → Audit Log**

* Filter by user
* Look for:
  * "User logged in" with method="ldap"
  * "User created" with method="ldap\_auto\_provision" (for new users)
