Files
attune/work-summary/2026-03-19-ldap-authentication.md
David Culbreth 4df621c5c8
Some checks failed
CI / Rustfmt (push) Failing after 21s
CI / Cargo Audit & Deny (push) Failing after 33s
CI / Web Blocking Checks (push) Successful in 50s
CI / Security Blocking Checks (push) Successful in 7s
CI / Web Advisory Checks (push) Successful in 33s
CI / Security Advisory Checks (push) Successful in 34s
Publish Images And Chart / Resolve Publish Metadata (push) Successful in 1s
Publish Images And Chart / Publish init-packs (push) Failing after 11s
Publish Images And Chart / Publish init-user (push) Failing after 10s
Publish Images And Chart / Publish migrations (push) Failing after 11s
Publish Images And Chart / Publish sensor (push) Failing after 10s
Publish Images And Chart / Publish web (push) Failing after 10s
Publish Images And Chart / Publish worker (push) Failing after 10s
Publish Images And Chart / Publish api (push) Failing after 7s
Publish Images And Chart / Publish executor (push) Failing after 9s
Publish Images And Chart / Publish notifier (push) Failing after 10s
Publish Images And Chart / Publish Helm Chart (push) Has been skipped
CI / Clippy (push) Successful in 18m52s
CI / Tests (push) Has been cancelled
adding some initial SSO providers, updating publish workflow
2026-03-20 12:37:24 -05:00

3.7 KiB

LDAP Authentication Support

Date: 2026-03-19

Summary

Added LDAP as an authentication provider alongside the existing OIDC and local username/password login methods. LDAP authentication follows the same architectural patterns as OIDC — server-side credential verification, identity upsert with provider-specific claims stored in the attributes JSONB column, and JWT token issuance.

Changes

Backend (Rust)

New Files

  • crates/api/src/auth/ldap.rs — LDAP authentication module using the ldap3 crate (v0.12). Supports two authentication modes:
    • Direct bind: Constructs a DN from a configurable bind_dn_template (e.g., uid={login},ou=users,dc=example,dc=com) and binds directly as the user.
    • Search-and-bind: Binds as a service account (or anonymous), searches for the user entry using user_search_base + user_filter, then re-binds as the discovered DN with the user's password.
    • After successful authentication, fetches user attributes (login, email, display name, groups) and upserts an identity row with claims stored under attributes.ldap.

Modified Files

  • crates/common/src/config.rs:

    • Added LdapConfig struct with fields for server URL, bind DN template, search base/filter, service account credentials, attribute mapping, TLS settings, and UI metadata (provider name/label/icon).
    • Added ldap: Option<LdapConfig> to SecurityConfig.
    • Added show_ldap_login: bool to LoginPageConfig.
  • crates/common/src/repositories/identity.rs:

    • Added find_by_ldap_dn() method to IdentityRepository, querying attributes->'ldap'->>'server_url' and attributes->'ldap'->>'dn' (mirrors the existing find_by_oidc_subject pattern).
  • crates/api/Cargo.toml:

    • Added ldap3 = "0.12" dependency.
  • crates/api/src/auth/mod.rs:

    • Added pub mod ldap;.
  • crates/api/src/routes/auth.rs:

    • Added POST /auth/ldap/login route and ldap_login handler (validates LdapLoginRequest, delegates to ldap::authenticate, returns TokenResponse).
    • Updated auth_settings handler to populate LDAP fields in the response.
  • crates/api/src/dto/auth.rs:

    • Added ldap_enabled, ldap_visible_by_default, ldap_provider_name, ldap_provider_label, ldap_provider_icon_url fields to AuthSettingsResponse.

Frontend (React/TypeScript)

  • web/src/pages/auth/LoginPage.tsx:
    • Extended AuthSettingsResponse interface with LDAP fields.
    • Added LDAP login form (username/password) with emerald-colored submit button, error handling, and ?auth=ldap override support.
    • Added divider between sections when multiple login methods are visible.

Configuration

  • config.example.yaml: Added full LDAP configuration example with comments explaining direct-bind vs search-and-bind modes.
  • config.development.yaml: Added disabled LDAP section with direct-bind template.

Documentation

  • AGENTS.md: Updated Authentication & Security section to document both OIDC and LDAP providers, their config keys, routes, identity matching, and login page configuration.

Architecture Notes

  • LDAP authentication is a synchronous POST flow (no browser redirects), unlike OIDC which uses authorization code redirects. The user submits credentials to POST /auth/ldap/login and receives JWT tokens directly.
  • Identity deduplication uses server_url + dn as the composite key (stored in attributes.ldap), analogous to OIDC's issuer + sub.
  • Login name collision avoidance uses the same SHA-256 fallback pattern as OIDC (ldap:<24-hex-chars>).
  • The ldap3 crate connection is driven asynchronously on the Tokio runtime via ldap3::drive!(conn).
  • STARTTLS and TLS certificate verification skip are configurable per-deployment.