prepare-custody, plan, accounts and verify for ld-admin and the svc-* accounts; named rotations for the Authelia bind and LLDAP_LDAP_USER_PASS. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Assistant: claude-code Assistant-Model: opus Assistant-Process: 308701@bnt-lap001 Assistant-Session: 5548e447-444c-4dcc-bed1-05c16eebfe56 |
||
|---|---|---|
| .. | ||
| bind-split-rehearsal.py | ||
| bind-split.py | ||
| bootstrap-users.sh | ||
| break-glass.sh | ||
| create-secrets.sh | ||
| create-user.sh | ||
| deployment.yaml | ||
| dry-run-nonroot-user.sh | ||
| GROUP-MAINTENANCE.md | ||
| identity-provisioner-reconcile.py | ||
| ingress.yaml | ||
| lldap_admin.py | ||
| manage-group-members.sh | ||
| middleware.yaml | ||
| OPERATOR-GROUPS.md | ||
| pvc.yaml | ||
| README.md | ||
| test_bind_split.py | ||
| test_identity_provisioner_reconcile.py | ||
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.shrun andsecrets/lldap/secrets.envpopulated in KeePassXCkubectlconfigured 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>