net-kingdom/sso-mfa/k8s/lldap/README.md
tegwick a9aec541ec
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 4s
Implement NK-WP-0021 activity-core ops SSO least-privilege.
Seed LLDAP activity-core-operators, add membership runbook and helper,
restrict Authelia access on activity/temporal.coulomb.social to that
group (member one_factor + domain deny fallback), apply live, and verify
via Authelia check-policy plus unauthenticated edge redirects.
2026-07-22 15:47:26 +02:00

104 lines
3.4 KiB
Markdown

# T05a — LLDAP (Lightweight LDAP Directory)
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
```bash
# 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, seed required groups (preferred — idempotent):
```bash
./bootstrap-users.sh
# 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](./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
```bash
# 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>
```