---
title: Authentication Methods
description: Configure Authentication - Local, Basic, Forced, LDAP, OIDC, SAML
weight: 800
---

Cavaliba supports multiple authentication methods to accommodate different deployment scenarios, from small single-user environments to large enterprise deployments with federated identity management.

This page covers all available authentication modes and their configuration. Choose the method that best suits your security requirements and organizational structure.

---

## Overview and Selection Guide

| Method | Suitable For | External Auth | Features | Complexity |
|--------|-------------|--------------|----------|-----------|
| **Local** | Small deployments, testing | No | Manual user management, simple passwords | Low |
| **Basic** | Small teams, legacy systems | Yes (external) | HTTP Basic Auth, file-based users | Low |
| **Forced** | Development, isolated testing | No | Single auto-login user | Very Low |
| **LDAP** | Enterprise directories | Via Keycloak | Central directory auth | Medium |
| **OIDC/SAML** | Modern enterprise | Yes (OAuth2 Proxy) | MFA, federated identity, self-service | High |

---

## Local Authentication

### Overview

Local Authentication is the **default mode** after a fresh Cavaliba installation. User accounts (login/password) are managed directly inside Cavaliba by an administrator. Sign-in/Sign-out web forms are provided by the application.

**Best for:** Small deployments with limited users and no need for advanced features like MFA or self-service password management.

### Configuration

#### Step 1: Update Environment File

In your `.env` file, set:

```
CAVALIBA_AUTH_MODE=local
```

#### Step 2: Configure Docker

- Ensure OAUTH2 configuration blocks are commented out in `nginx.conf`
- Ensure oauth2_proxy container bloc is commented out in `docker-compose.yml`
- Ensure basic authentication blocks are commented out in `nginx.conf`

#### Step 3: Restart Containers

```bash
docker compose down
docker compose up -d
```

#### Step 4: Login

- Access Cavaliba with the default admin account (login: `admin`, password from `CAVALIBA_ADMIN_PASSWORD` in `.env`)

### User Management

#### Adding a New User

**Via Web Admin Interface:**

1. Open the **DB Admin Tool** from Cavaliba main menu (Admin section)
2. Select the Django user table (`auth_user`)
3. Click the "Add User" button and fill in the form:
   - **Username**: Login identifier (e.g., `john.smith`)
   - **Password**: Initial password (encrypted in database)
   - **Email**: User email address
4. Return to Cavaliba
5. Go to the **User module** in administration
6. Add the same user with extended information:
   - Full name
   - Group membership
   - Roles and permissions
   - Email preferences

**Via Django Shell (CLI):**

```bash
docker exec -it cavaliba_app python manage.py shell
```

In the Python shell:

```python
from django.contrib.auth.models import User
user = User.objects.create_user("john.smith", "john@company.com", "initialpassword")
```

**Via Django createsuperuser (admin only):**

```bash
docker exec -it cavaliba_app python manage.py createsuperuser
```

#### Suspending or Removing a User

1. Open the **DB Admin Tool** from Cavaliba main menu
2. Select the Django user table
3. Find the user and edit:
   - Set **Active** checkbox to unchecked to suspend
   - Click delete to remove entirely
4. Return to the **User module** in Cavaliba to update the Cavaliba user record

**Note:** Disabling in Django prevents login but the Cavaliba user record remains and can still receive notifications via Sirene.

#### Changing a User's Password

**Via Web Admin Interface:**

1. Open the **DB Admin Tool** from Cavaliba main menu
2. Select the Django user table
3. Click on the user to edit
4. Use the **Change Password** button/link to set a new password

**Via Django CLI:**

```bash
docker exec -it cavaliba_app python manage.py changepassword LOGIN
```

### Important Notes

- Local authentication requires users to exist in **both**:
  1. Django auth table (`auth_user`) - for login credentials
  2. Cavaliba user model (`SireneUser`) - for roles, groups, permissions, notifications
- Password changes made in the DB admin tool take effect immediately
- No password expiration or complexity rules are enforced by default

---

## Basic Authentication

### Overview

Basic Authentication is an **external** authentication mode. The web server (or upstream reverse proxy) handles authentication and passes the authenticated username to Cavaliba via HTTP headers.

**Best for:** Small teams with existing infrastructure (Apache, Nginx with auth modules, or external reverse proxies).

### Configuration

#### Option 1: Using Cavaliba's Internal Nginx

##### Step 1: Create htpasswd File

On your host machine, create a password file using the `htpasswd` utility:

```bash
# Install apache2-utils if needed (Ubuntu/Debian)
sudo apt-get install apache2-utils

# Create htpasswd file with first user
htpasswd -c ./htpasswd username1

# Add additional users (without -c flag)
htpasswd ./htpasswd username2
htpasswd ./htpasswd username3
```

Keep this file in your Cavaliba directory (e.g., `./config/htpasswd`).

##### Step 2: Update docker-compose.yml

Uncomment the volume section mounting the htpasswd file into the Nginx container:

```yaml
nginx:
  volumes:
    # ... existing volumes ...
    - ./config/htpasswd:/etc/nginx/conf.d/.htpasswd:ro
```

##### Step 3: Update nginx.conf

Uncomment the basic authentication configuration block:

```nginx
location / {
    auth_basic "Cavaliba";
    auth_basic_user_file /etc/nginx/conf.d/.htpasswd;
    # ... proxy settings ...
}
```

##### Step 4: Update .env File

```
CAVALIBA_AUTH_MODE=basic
```

Ensure OAUTH2 configuration is commented out.

##### Step 5: Restart Containers

```bash
docker compose down
docker compose up -d
```

#### Option 2: Using External Reverse Proxy

If you have an external reverse proxy or web server (Apache, HAProxy, cloud-based auth), configure it to:

1. Perform HTTP Basic Authentication
2. Set the HTTP `Authorization` header or `Remote-User` header with the authenticated username
3. Forward the request to Cavaliba

The reverse proxy **must** pass one of these headers:
- Standard HTTP `Authorization` header (Base64-encoded username:password)
- Custom header like `Remote-User` with the username
- Custom header configured in Cavaliba

### User Management

As with Local Authentication, users must exist in **both**:

1. **External** (htpasswd file, reverse proxy directory) - for login credentials
2. **Cavaliba user model** - for roles, groups, permissions, notifications

#### Maintaining htpasswd File

```bash
# List current users
htpasswd -l ./htpasswd

# Change user password
htpasswd ./htpasswd username

# Delete user
htpasswd -D ./htpasswd username
```

Changes to htpasswd take effect immediately without container restart.

### Important Notes

- Basic Authentication sends credentials in Base64 encoding (easily decoded) - **always use HTTPS in production**
- User management is split between external system and Cavaliba
- Password policies are controlled by the external auth system, not Cavaliba
- Cavaliba user records must be manually created and synchronized with external users

---

## Forced Authentication

### Overview

Forced Authentication means **no authentication**. All connections are automatically mapped to a single predefined Cavaliba user without any credential verification.

**Best for:** Development, testing, isolated single-user environments only.

### Configuration

#### Step 1: Update .env File

```
CAVALIBA_AUTH_MODE=forced
CAVALIBA_FORCE_LOGIN=admin
```

Replace `admin` with the username you want to auto-login.

#### Step 2: Comment Out Other Auth

- Ensure OAUTH2 configuration is commented out in `nginx.conf` and `docker-compose.yml`
- Ensure basic authentication is commented out in `nginx.conf`

#### Step 3: Restart Containers

```bash
docker compose down
docker compose up -d
```

### Behavior

- All requests are authenticated as the user specified in `CAVALIBA_FORCE_LOGIN`
- No login form is displayed
- No logout button is functional
- Direct access to the application without authentication

### Security Warning

⚠️ **DO NOT USE IN PRODUCTION**

Do not use Forced Authentication in:
- Shared networks
- QA/Test environments with sensitive data
- Production environments
- Any multi-user scenario

This mode is intended **only** for isolated development on a single machine.

---

## LDAP Authentication

### Direct LDAP Support

Cavaliba does **not** provide direct LDAP authentication out of the box.

### Indirect LDAP via Keycloak

LDAP authentication can be achieved indirectly by using the **OIDC/OAuth2 mode** (described below) with a local **Keycloak Identity Provider** that connects to your LDAP directory.

This approach provides:
- Central LDAP directory authentication
- Keycloak's additional features (MFA, user federation, etc.)
- Cavaliba's role and permission management

#### Quick Setup Path

1. Deploy a Keycloak instance (Docker container or separate service)
2. Configure Keycloak to use your LDAP directory as a User Federation
3. Create a Cavaliba client/application in Keycloak
4. Configure Cavaliba to use OAuth2 mode with Keycloak as the IdP
5. See **OIDC/SAML** section below for detailed OAuth2 configuration

### Benefits of This Approach

- **Centralized authentication**: Users authenticate against existing LDAP directory (Active Directory, OpenLDAP, etc.)
- **No duplicate password management**: Single source of truth for user credentials
- **Enhanced security**: Keycloak can add MFA and other advanced features
- **User federation**: Keycloak can sync user attributes from LDAP
- **Flexible authorization**: Cavaliba handles role-based access control

---

## OIDC/SAML Authentication (OAuth2)

### Overview

OIDC (OpenID Connect) and SAML are **external** authentication modes. Authentication is performed by an external Identity Provider (IdP) such as Keycloak, Okta, Microsoft Azure AD, Google, etc.

Cavaliba uses the **oauth2_proxy** companion container to handle the authentication protocol negotiation. The proxy authenticates the user with the IdP and then forwards the authenticated request to Cavaliba.

**Best for:** Large enterprise deployments, modern security practices, multi-factor authentication, federated identity management.

### Supported Identity Providers

- **Keycloak** - Open-source, self-hosted identity platform
- **Okta** - Commercial cloud-based IdP
- **Microsoft Azure AD / Entra ID** - Microsoft's identity service
- **Google** - Gmail/Google Workspace accounts
- **Auth0** - Commercial identity platform
- **Other OIDC/SAML providers** - Any provider supporting standard protocols

### Architecture

```
User Browser
    ↓
Nginx (Reverse Proxy)
    ↓
oauth2_proxy Container
    ↓
External Identity Provider (IdP)
    ↓ (authenticated, returns user info)
Cavaliba Application
```

The oauth2_proxy container sits between the user and Cavaliba, handling all OAuth2/SAML protocol details.

### Configuration Steps

#### Step 1: Register Cavaliba with Your Identity Provider

Each IdP has a different process for registering applications. General steps:

1. Log in to your IdP admin console
2. Create a new application or service provider
3. Set **Redirect URI** to: `https://cavaliba.your-domain.com/oauth2/callback`
4. Configure which user attributes are shared with Cavaliba
5. Note the **Client ID** and **Client Secret** (or equivalent)

#### Step 2: Update .env File

Create or update the OAuth2 configuration in `.env`:

```
# Authentication mode
CAVALIBA_AUTH_MODE=oauth2

# Identity Provider selection
OAUTH2_PROXY_PROVIDER="oidc"
OAUTH2_PROXY_PROVIDER_DISPLAY_NAME="Your IdP Name"
OAUTH2_PROXY_OIDC_ISSUER_URL="https://your-idp.com/path/to/realm"

# Application credentials from IdP
OAUTH2_PROXY_CLIENT_ID="your-client-id"
OAUTH2_PROXY_CLIENT_SECRET="your-client-secret"

# Session security
OAUTH2_PROXY_COOKIE_SECRET="your-cookie-secret-min-24-chars"
OAUTH2_PROXY_REDIRECT_URL="https://cavaliba.your-domain.com/oauth2/callback"

# Cookie settings
OAUTH2_PROXY_COOKIE_SECURE="true"
OAUTH2_PROXY_COOKIE_HTTPONLY="true"
OAUTH2_PROXY_COOKIE_SAMESITE="lax"
OAUTH2_PROXY_COOKIE_EXPIRE="0h45m0s"

# Session storage
OAUTH2_PROXY_SESSION_STORE_TYPE="redis"
OAUTH2_PROXY_REDIS_CONNECTION_URL="redis://cavaliba_redis:6379"

# Email domain restriction (optional)
OAUTH2_PROXY_EMAIL_DOMAINS="company.com"
```

**See Docker Env Configuration page for complete OAuth2 options and details.**

#### Step 3: Update docker-compose.yml

Uncomment the oauth2_proxy container block:

```yaml
oauth2_proxy:
  image: quay.io/oauth2-proxy/oauth2-proxy:latest
  container_name: ${CAVALIBA_TENANT}_oauth2
  networks:
    - cavaliba_network
  ports:
    - "4180:4180"
  environment:
    OAUTH2_PROXY_PROVIDER: ${OAUTH2_PROXY_PROVIDER}
    OAUTH2_PROXY_CLIENT_ID: ${OAUTH2_PROXY_CLIENT_ID}
    OAUTH2_PROXY_CLIENT_SECRET: ${OAUTH2_PROXY_CLIENT_SECRET}
    # ... other settings from .env ...
  depends_on:
    - redis
```

#### Step 4: Update nginx.conf

Comment out Basic Auth configuration and uncomment OAuth2 Proxy configuration:

```nginx
location / {
    # Comment out basic auth:
    # auth_basic "Cavaliba";
    # auth_basic_user_file ...

    # Uncomment OAuth2 proxy:
    auth_request /oauth2/auth;
    error_page 401 =302 /oauth2/sign_in;

    # Pass OAuth2 headers to backend:
    auth_request_set $user   $upstream_http_x_auth_request_preferred_username;
    auth_request_set $email  $upstream_http_x_auth_request_mail;

    proxy_set_header X-User $user;
    proxy_set_header X-Email $email;

    proxy_pass http://cavaliba_app:8001;
    # ... other proxy settings ...
}

location /oauth2/ {
    proxy_pass http://oauth2_proxy:4180;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
}
```

#### Step 5: Ensure Users Exist in Cavaliba

Before login attempts, provision users in Cavaliba:

```bash
docker exec -it cavaliba_app python manage.py shell
```

```python
from app_user.models import SireneUser

user = SireneUser.objects.create_user(
    username="john.smith",
    email="john.smith@company.com"
)
user.save()
```

Or create users manually in Cavaliba admin after first OAuth2 login (if auto-provisioning is enabled).

#### Step 6: Restart Containers

```bash
docker compose down
docker compose up -d
```

### Example Configurations

#### Keycloak (Self-Hosted)

```bash
# .env
OAUTH2_PROXY_PROVIDER="keycloak-oidc"
OAUTH2_PROXY_PROVIDER_DISPLAY_NAME="Keycloak"
OAUTH2_PROXY_OIDC_ISSUER_URL="https://keycloak.example.com/realms/cavaliba"
OAUTH2_PROXY_CLIENT_ID="cavaliba-client"
OAUTH2_PROXY_CLIENT_SECRET="your-client-secret-from-keycloak"
OAUTH2_PROXY_COOKIE_SECRET="generate-with-python-secrets"
OAUTH2_PROXY_REDIRECT_URL="https://cavaliba.example.com/oauth2/callback"
```

#### Okta

```bash
# .env
OAUTH2_PROXY_PROVIDER="oidc"
OAUTH2_PROXY_PROVIDER_DISPLAY_NAME="Okta"
OAUTH2_PROXY_OIDC_ISSUER_URL="https://your-okta-domain.okta.com"
OAUTH2_PROXY_CLIENT_ID="okta-app-client-id"
OAUTH2_PROXY_CLIENT_SECRET="okta-app-secret"
OAUTH2_PROXY_COOKIE_SECRET="generate-with-python-secrets"
OAUTH2_PROXY_REDIRECT_URL="https://cavaliba.example.com/oauth2/callback"
OAUTH2_PROXY_EMAIL_DOMAINS="company.com"
```

#### Azure AD

```bash
# .env
OAUTH2_PROXY_PROVIDER="azure"
OAUTH2_PROXY_PROVIDER_DISPLAY_NAME="Azure AD"
OAUTH2_PROXY_OIDC_ISSUER_URL="https://login.microsoftonline.com/your-tenant-id/v2.0"
OAUTH2_PROXY_CLIENT_ID="azure-app-id"
OAUTH2_PROXY_CLIENT_SECRET="azure-app-secret"
OAUTH2_PROXY_COOKIE_SECRET="generate-with-python-secrets"
OAUTH2_PROXY_REDIRECT_URL="https://cavaliba.example.com/oauth2/callback"
```

### User Provisioning

#### Just-In-Time Provisioning (Recommended)

Enable automatic user creation on first login:

In Cavaliba configuration (application settings):

```
USER / AUTH_PROVISIONING = "create"  (or "update" or "sync")
```

Options:
- **manual**: No auto-creation, users must pre-exist in Cavaliba
- **visitor**: Temporary access without permanent account
- **create**: Create new account on first login with basic role
- **update**: Update existing account attributes from IdP
- **sync**: Full synchronization of user attributes and groups

#### Pre-Provisioning

Manually create all users before they first log in:

```bash
docker exec -it cavaliba_app python manage.py shell
```

```python
from app_user.models import SireneUser
from app_user.models import SireneRole

# Create user
user = SireneUser.objects.create_user(
    username="john.smith",
    email="john.smith@company.com"
)

# Assign roles/groups (example)
user.save()
```

### Troubleshooting

#### Users can't log in after OAuth2 setup

1. **Check IdP registration**: Ensure Redirect URI exactly matches `OAUTH2_PROXY_REDIRECT_URL`
2. **Verify HTTPS**: IdP may reject non-HTTPS redirect URIs
3. **Check nginx logs**: `docker logs cavaliba_nginx`
4. **Check oauth2_proxy logs**: `docker logs cavaliba_oauth2`
5. **Verify user exists**: Check Cavaliba User module for the user account

#### "email mismatch" or similar errors

- Check that IdP is configured to return email address
- Check `OAUTH2_PROXY_EMAIL_DOMAINS` setting matches user email domains
- Review oauth2_proxy logs for detailed error messages

#### Session issues after IdP changes

- Clear browser cookies
- Restart oauth2_proxy container: `docker restart cavaliba_oauth2`

### Security Considerations

- **Always use HTTPS** in production - OAuth2 credentials travel in headers
- **Keep Client Secret secure** - Never commit to version control, use environment files
- **Set COOKIE_SECURE to true** - Prevents cookies over HTTP
- **Set COOKIE_HTTPONLY to true** - Prevents JavaScript access to cookies
- **Use COOKIE_SAMESITE="lax"** - Prevents CSRF attacks
- **Regularly rotate secrets** - Keycloak, Okta, etc. provide secret rotation
- **Monitor logs** - Review authentication failures regularly

---

## Comparing Authentication Methods

### Feature Comparison

| Feature | Local | Basic | Forced | LDAP | OIDC/SAML |
|---------|-------|-------|--------|------|-----------|
| Password Management | Manual in Cavaliba | External file/system | No | Via IdP/Keycloak | Via IdP |
| User Synchronization | Manual | Manual | N/A | Automatic | Automatic |
| Multi-Factor Auth (MFA) | No | No | No | Via Keycloak | Yes |
| Central Directory Support | No | No | No | Yes (via Keycloak) | Yes |
| Scalable for Many Users | No | No | No | Yes | Yes |
| Self-Service Password Reset | No | No | No | Via Keycloak | Via IdP |
| User Provisioning | Manual | Manual | Fixed | Automatic | Automatic |
| Setup Complexity | Very Low | Low | Very Low | Medium | High |
| Production Recommended | Small only | Small only | Never | Yes | Yes |
| HTTPS Required | Optional | Recommended | Optional | Recommended | Required |

### Decision Tree

```
How many users?
├─ < 10: Local or Basic
└─ ≥ 10:
   ├─ Existing LDAP/AD directory?
   │  └─ Yes: OIDC/SAML with Keycloak → LDAP
   └─ No:
      ├─ Need MFA or Single Sign-On?
      │  └─ Yes: OIDC/SAML with your IdP
      └─ No: Local or Basic
```

### Migration Path

1. **Start with Local** - Easy to configure and test
2. **Move to Basic** - When you have external auth system
3. **Upgrade to OIDC/SAML** - When you need enterprise features
4. **LDAP via Keycloak** - When you have existing directory service

User data migration between modes requires:
- Creating new user accounts in the target system
- Updating the `CAVALIBA_AUTH_MODE` setting
- Testing login before going to production
- Optionally keeping old accounts for notification purposes

---

## Authentication Configuration Reference

For detailed environment variable documentation, see:

- **Docker Env Configuration** - All CAVALIBA_AUTH_MODE and OAUTH2_PROXY_* settings
- **Application Configuration** - USER/AUTH_* settings for provisioning and federated auth

---

## Related Documentation

- **Authorization and Permissions** - How to control what authenticated users can do
- **User Management** - Managing users, groups, roles within Cavaliba
- **Docker Environment** - Complete reference for all .env variables
