net-kingdom/sso-mfa/k8s/lldap/README.md
tegwick ab25dde80d
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
security: repair LDAP group callers and fail incomplete T07 acceptance
Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a1346b-72a4-7d40-b8bd-8b8ca346cfa2
2026-10-14 01:17:35 +02:00

3.9 KiB

T05a — LLDAP (Lightweight LDAP Directory)

Exercise status: unknown for the procedures in this runbook; no per-procedure successful-run receipt with operator attribution was established in the 2026-09-05 review. See procedure inventory.

LLDAP is the user and group directory for the net-kingdom SSO stack. It provides LDAP access to Authelia (credential validation) and KeyCape (user attribute lookup). The admin web UI is IP-restricted and never exposed publicly.

Prerequisites

  • T02 complete (namespaces and NetworkPolicies applied)
  • bootstrap/gen-secrets.sh run and secrets/lldap/secrets.env populated in KeePassXC
  • kubectl configured with cluster access

Apply order

# 1. Generate secrets (if not already done)
cd ../../bootstrap && ./gen-secrets.sh

# 2. Create K8s Secret
cd ../k8s/lldap
chmod +x create-secrets.sh
./create-secrets.sh

# 3. Apply manifests (order matters)
kubectl apply -f pvc.yaml
kubectl apply -f middleware.yaml
kubectl apply -f deployment.yaml
kubectl apply -f ingress.yaml

# 4. Wait for pod to be ready
kubectl rollout status deployment/lldap -n sso --timeout=120s

Post-deploy bootstrap

After the pod is Running, preview the fixed group bootstrap under the IAM owner's authority. See group maintenance for private input, reviewed apply, preservation, interruption and native acceptance limits:

./bootstrap-users.sh --root /absolute/private/custody
# Preview only. Apply requires --apply --expected-digest from the reviewed preview.
# Groups: net-kingdom-users, net-kingdom-admins, activity-core-operators

Or create them via the web UI:

https://lldap.coulomb.social
Username: admin
Password: LLDAP_LDAP_USER_PASS (from KeePassXC → net-kingdom/LLDAP/admin)
Group Purpose
net-kingdom-users Standard users (all human accounts)
net-kingdom-admins Privileged users (KeyCape MFA step-up / extra scopes)
activity-core-operators App-scoped: browser SSO to activity-core ops + Temporal UI (Authelia domain rules). Not platform admin — grant consciously.

Operator membership (add/remove humans): see OPERATOR-GROUPS.md.

Ports

Port Protocol Access Purpose
3890 TCP (LDAP) Cluster-internal only Authelia + KeyCape LDAP bind
17170 TCP (HTTP) Traefik (IP-restricted) Admin web UI

The LDAP port is never exposed via Ingress. Only pods in the sso namespace with app.kubernetes.io/name=authelia or app.kubernetes.io/name=keycape labels are allowed to reach port 3890 (enforced by NetworkPolicy).

Secrets managed

Secret name Keys Purpose
lldap-secrets LLDAP_JWT_SECRET, LLDAP_LDAP_USER_PASS Pod environment variables

LLDAP_LDAP_USER_PASS is the admin bind password shared by Authelia and KeyCape. It must match the value used in authelia/create-secrets.sh and keycape/create-secrets.sh. All three read it from secrets/lldap/secrets.env.

Storage

lldap-data PVC (1 Gi, ReadWriteOnce) holds LLDAP's SQLite database.

Back this PVC up regularly — it contains all users and groups. If it is lost without a backup, all user accounts must be re-created and all applications must be re-enrolled in privacyIDEA.

Optional: switch to PostgreSQL by setting LLDAP_DATABASE_URL=postgresql://... env var in deployment.yaml and removing the PVC.

Verify

# Check pod status
kubectl get pod -n sso -l app.kubernetes.io/name=lldap

# Check LLDAP health via cluster-internal curl
kubectl run -n sso --rm -it ldap-test --image=busybox --restart=Never \
  -- wget -qO- http://lldap.sso.svc.cluster.local:17170/health

# Test LDAP bind (from another pod in the sso namespace)
# ldapwhoami -H ldap://lldap.sso.svc.cluster.local:3890 \
#   -D "uid=admin,ou=people,dc=netkingdom,dc=local" -w <LLDAP_LDAP_USER_PASS>