Skip to main content

lldap

A lightweight LDAP server for centralized user account management.

lldap is a simplified LDAP server designed for self-hosting that provides a clean web UI for managing users and groups. It supports a minimal but sufficient LDAP subset for use with compatible apps (Gitea, Nextcloud, Keycloak user federation, etc.). Self-hosting gives you a single source of truth for user identities without paying for a directory service.

Alternatives considered​

Cloud Hosted

ToolOpen SourceFree TierMonthly Cost
Azure Entra IDNoLimitedFrom $6/user

Self Hosted

ToolOpen SourceFull FeaturesNotes
OpenLDAPYesYesMore complete but much harder to configure
FreeIPAYesYesFull identity stack; heavy for homelab
Active DirectoryNoNoWindows-only; enterprise-grade complexity

Installation​

Architecture​

  • Deployment: Single lldap deployment in the lldap namespace
  • Image: nitnelave/lldap (alpine variant), digest-pinned via Renovate
  • Storage: Longhorn PVC (lldap-data, annotated k8up.io/backup: "true") for SQLite database and config
  • Networking: ClusterIP service with separate ports for LDAP and web UI; HTTPRoute via public gateway

Security​

  • No runAsUser is set, so the container starts as the image's default user, which is root; privilege escalation is blocked and all capabilities are dropped
  • Longhorn PVC encrypted at rest via SOPS-managed keys

Updates​

Managed by Renovate. Image is digest-pinned.

Data Management​

  • Database: SQLite stored on lldap-data Longhorn PVC (annotated k8up.io/backup: "true")
  • Backups: k8up Schedules to Hetzner and Backblaze via restic, covering the Longhorn PVC.

User Management​

lldap is an LDAP provider — it does not consume OIDC. Provides the user directory for Keycloak federation and other LDAP-compatible services. Users and groups managed via the lldap web UI.

Configuration Management​

  • Bind DN and password, JWT secret from SOPS-encrypted secret
  • LDAP base DN and other settings configured in the Deployment env vars

Usage​

Manage users and groups through the web UI. Connect applications via LDAP bind using the configured service account. lldap can feed into Keycloak's user federation to provide SSO backed by a central directory.

Cluster-specific deviations from the above live in the per-cluster README — see k8s/apps/lldap/talos/README.md.

Cluster Deployment​

lldap — Talos cluster

Kubernetes Metadata
  • Image: nitnelave/lldap:v0.6.3-alpine@sha256:2a8454b668c1aba7157e832eab0e242e1e7eb5fb7591d7e7774ba05286511ca8
Rendered manifests (kustomize build)
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
kustomize.toolkit.fluxcd.io/force: enabled
labels:
app.kubernetes.io/name: lldap
name: lldap
namespace: lldap
spec:
replicas: 1
revisionHistoryLimit: 2
selector:
matchLabels:
app.kubernetes.io/name: lldap
strategy:
rollingUpdate: null
type: Recreate
template:
metadata:
labels:
app.kubernetes.io/name: lldap
spec:
automountServiceAccountToken: false
containers:
- env:
- name: LLDAP_SMTP_OPTIONS__ENABLE_PASSWORD_RESET
value: 'true'
- name: LLDAP_HTTP_URL
value: https://account.web.kueber.eu
- name: LLDAP_SMTP_OPTIONS__SERVER
valueFrom:
secretKeyRef:
key: host
name: allinkl-smtp-credentials
- name: LLDAP_SMTP_OPTIONS__PORT
valueFrom:
secretKeyRef:
key: port
name: allinkl-smtp-credentials
- name: LLDAP_SMTP_OPTIONS__SMTP_ENCRYPTION
value: STARTTLS
- name: LLDAP_SMTP_OPTIONS__USER
valueFrom:
secretKeyRef:
key: username
name: allinkl-smtp-credentials
- name: LLDAP_SMTP_OPTIONS__PASSWORD
valueFrom:
secretKeyRef:
key: password
name: allinkl-smtp-credentials
- name: LLDAP_SMTP_OPTIONS__FROM
valueFrom:
secretKeyRef:
key: from
name: allinkl-smtp-credentials
envFrom:
- secretRef:
name: lldap
image: nitnelave/lldap:v0.6.3-alpine@sha256:2a8454b668c1aba7157e832eab0e242e1e7eb5fb7591d7e7774ba05286511ca8
name: lldap
ports:
- containerPort: 3890
- containerPort: 17170
resources:
limits:
memory: 128Mi
requests:
cpu: 25m
memory: 64Mi
volumeMounts:
- mountPath: /data
name: lldap-data
priorityClassName: tier-3
restartPolicy: Always
securityContext:
seccompProfile:
type: RuntimeDefault
volumes:
- name: lldap-data
persistentVolumeClaim:
claimName: lldap-data