Assistant: codex Assistant-Model: gpt-6-astra Assistant-Session: 01a1346b-72a4-7d40-b8bd-8b8ca346cfa2
9.3 KiB
SSO-MFA Platform — Stack Migration Workplan
Lifecycle update, 2026-10-14: the lifecycle tooling descriptions below are a historical snapshot, not current execution instructions. Account creation, pattern deletion and inferred-claims verification in the old 0019 helpers are retired. Their secret handling and success assertions are not accepted evidence of current safety or readiness. Use the current owner routes and actual native receipts. Ordinary lifecycle delivery has since advanced in NK-WP-0025/NK-WP-0038; independent recovery and other IAM callers remain open.
NK-WP-0001 — Keycloak → Authelia + LLDAP + KeyCape
Updated: 2026-03-20 (T04 BLOCKED — ImagePullBackOff; T05–T08 pending T04) Workstream: sso-mfa-platform (39263c4b-ef70-4053-b782-350834b7e1be)
Stack Decision
Keycloak + privacyIDEA replaced by:
- LLDAP — lightweight LDAP directory (user store)
- Authelia — authentication frontend (password auth + OIDC upstream)
- KeyCape — OIDC orchestration layer (auth code flow + MFA via privacyIDEA adapter)
- privacyIDEA — MFA engine (unchanged, still in
mfanamespace)
Hostnames: kc.coulomb.social (KeyCape), auth.coulomb.social (Authelia), lldap.coulomb.social (LLDAP admin)
Task Status
| Task | ID (hub) | Status | Notes |
|---|---|---|---|
| T01 — Vault & secret bootstrap | 7992528c | done | |
| T02 — K8s foundations | 721ca6b2 | done | Manifests authored; pending live cluster |
| T03 — PostgreSQL | 7fa60004 | done | Manifests authored; pending live cluster |
| T04 — privacyIDEA | 6ad1296a | BLOCKED | Pod deployed, ImagePullBackOff — image privacyidea/privacyidea:3.12 does not exist; fix image ref first |
| T05 — SSO core (new stack) | b9f73aa6 | done | commit 0754dc3 |
| T06 — Realm config & MFA flow | 3b6379a4 | in-progress | See below |
| T07 — User mgmt & self-service | c7cf902a | in-progress | See below |
| T08 — Backups, DR, break-glass | 9cbd1d89 | in-progress | See below |
T04 — privacyIDEA
Deliverables (already authored)
k8s/privacyidea/pvc.yaml— privacyidea-data and privacyidea-logs PVCsk8s/privacyidea/configmap.yaml— pi.cfg template (secrets injected at runtime)k8s/privacyidea/create-secrets.sh— privacyidea-config Secretk8s/privacyidea/deployment.yaml— Deployment + Service (port 8080)k8s/privacyidea/middleware.yaml— rate-limit + admin IP allowlist (ipWhiteList, Traefik v2)k8s/privacyidea/ingress.yaml— pink.coulomb.social + pink-account.coulomb.socialk8s/privacyidea/enckey-bootstrap.sh— extract enckey + audit keys post-startk8s/privacyidea/bootstrap-admin.sh— create/verify pi-admin (current KeyCape profile)k8s/verify-t04.sh— verify pod, service, middlewares, ingresses, TLS, secrets, PVCs
BLOCKER — wrong image (2026-03-20)
- Pod
privacyidea-8b4b5f567-wf858is deployed inmfanamespace but stuck inImagePullBackOff - Image
privacyidea/privacyidea:3.12does not exist on Docker Hub - Intermediate step needed: identify correct image reference, then patch
deployment.yaml - Candidates:
ghcr.io/privacyidea/privacyidea-apache2:<tag>or similar - Port may differ (manifest assumes 8080 — verify against actual image)
Pending (needs live cluster)
- Fix image in
deployment.yaml— confirm correct registry/tag ./create-secrets.sh— create privacyidea-config Secret in mfa namespace (may already exist; check first)kubectl apply -f pvc.yaml configmap.yaml middleware.yaml deployment.yaml ingress.yaml- Wait for pod Running/Ready (up to 3 min — DB migrations run on first boot)
bash ./enckey-bootstrap.sh /absolute/private/custody— extract enckey+auditkeys, store in KeePassXC, create DR Secrets./bootstrap-admin.sh— create/verify pi-admin (current KeyCape profile)- Log in to pink.coulomb.social, enroll TOTP for pi-admin, verify MFA challenge
- Run
../verify-t04.sh— 0 FAILs - Commit and mark T04 done
Done-criteria for T04
- privacyIDEA pod Running+Ready in mfa namespace
- pink.coulomb.social and pink-account.coulomb.social reachable with valid TLS
- pi-admin exists and attended MFA acceptance is recorded; no legacy trigger account is required
- pi-admin has enrolled a TOTP token and MFA challenge fires on login
- privacyidea-enckey and privacyidea-auditkeys Secrets exist (DR copies)
- verify-t04.sh: 0 FAILs
T05 — SSO Core (new stack: LLDAP + Authelia + KeyCape)
Done
- LLDAP manifests: pvc.yaml, deployment.yaml, middleware.yaml, ingress.yaml, create-secrets.sh
- Authelia manifests: pvc.yaml, configmap.yaml, deployment.yaml, ingress.yaml, create-secrets.sh
- KeyCape manifests: deployment.yaml, middleware.yaml, ingress.yaml, create-secrets.sh
- NetworkPolicy: netpol-sso.yaml updated for new components
- Keycloak manifests staged for deletion
In Progress (this session)
- keycape/create-pi-token.sh
- lldap/README.md
- authelia/README.md
- keycape/README.md
- Update CONFIG.md (fixed CP-NK-004, removed old CP-NK-005, added CP-NK-005 auth., CP-NK-006 lldap.)
- Update bootstrap/gen-secrets.sh (removed Keycloak, added LLDAP/Authelia/KeyCape sections)
- Update k8s/README.md (network policy table)
- Replace verify-t05.sh (Keycloak → LLDAP+Authelia+KeyCape checks)
- Commit all changes — commit
0754dc3 - Update state hub tasks — T05 marked done, milestone event logged
Done-criteria for T05
- All manifests present and consistent
- gen-secrets.sh generates correct secrets for new stack
- verify-t05.sh checks all three components
- Committed to main
T06 — Realm config & MFA flow (KeyCape → privacyIDEA)
Deliverables
k8s/privacyidea/bootstrap-realm.sh— current source repairs missingcoulombrealm/LLDAP configuration; the historical enrollment/passthrough replay is withdrawn. See the privacyIDEA README for preview/apply and owner-managed onboarding policy.k8s/verify-t06.sh— verifies realm, resolver, KeyCape→PI token, connectivity
In Progress (this session)
- Run the reviewed configuration-preserving realm repair and functional proof (requires T04 and current owner admission; source tests are not live acceptance).
- Establish RPF-WP-0040 scoped factor delivery, then first-bootstrap
keycape/create-secrets.shonly if config is absent (old admin-token helpers retired). - Restart KeyCape with updated keycape-config
- Enroll a TOTP token for pi-admin via pink-account.coulomb.social
- Test end-to-end login via kc.coulomb.social
- Run
verify-t06.sh— all checks pass - Commit and mark T06 done
Done-criteria for T06
- privacyIDEA "netkingdom" realm exists with LLDAP resolver
- LDAP resolver resolves users from LLDAP
- keycape-pi-token contains a real (non-placeholder) JWT
- KeyCape→privacyIDEA token list API returns status=True
- At least one user has enrolled a TOTP token
- verify-t06.sh: 0 FAILs
T07 — User mgmt & self-service
Deliverables
k8s/lldap/bootstrap-users.sh— creates net-kingdom-users and net-kingdom-admins groups in LLDAP via GraphQL APIk8s/lldap/break-glass.sh— creates the break-glass bypass account and assigns to net-kingdom-adminsk8s/verify-t07.sh— verifies groups, break-glass user, self-service portal, OIDC client registrations
Pending (needs live cluster)
- Run
lldap/bootstrap-users.shto create groups - Retired 2026-10-14: do not run the old break-glass creator. Preserve existing custody; NK-WP-0049-T03 tracks owner recovery verification.
- Add first real user via LLDAP WebUI (lldap.coulomb.social)
- Register first OIDC client in
keycape/create-secrets.sh(clients: block) - User self-enrolls TOTP at pink-account.coulomb.social
- Run
verify-t07.sh— 0 FAILs
Done-criteria for T07
- Groups net-kingdom-users and net-kingdom-admins exist in LLDAP
- break-glass user exists and is in net-kingdom-admins
- At least one regular user exists
- At least one OIDC client registered in KeyCape
- verify-t07.sh: 0 FAILs
T08 — Backups, DR, break-glass
Deliverables
k8s/backup/cronjob-sqlite-backups.yaml— daily SQLite backup CronJobs for LLDAP, Authelia, privacyIDEA; RBAC for Authelia scale-down/upk8s/backup/DR-RUNBOOK.md— full restore runbook: scenarios, restore order, node rebuild procedure, offsite exportk8s/verify-t08.sh— verifies CronJobs, RBAC, backup files on PVCs, DR runbook presence
Pending (needs live cluster)
- Apply
backup/cronjob-sqlite-backups.yaml - Trigger each CronJob manually once to verify they run clean:
kubectl create job -n sso --from=cronjob/lldap-backup lldap-backup-testkubectl create job -n sso --from=cronjob/authelia-backup authelia-backup-testkubectl create job -n mfa --from=cronjob/privacyidea-backup pi-backup-test - Confirm backup files appear on PVCs
- Run offsite export: pull backup files, encrypt with age, store offsite
- Run
verify-t08.sh— 0 FAILs
Done-criteria for T08
- All three backup CronJobs deployed and have ≥1 successful run
- Backup files confirmed on PVCs
- DR-RUNBOOK.md reviewed by operator
- Offsite ops bundle current (pack-bundle.sh run after all secrets finalised)
- verify-t08.sh: 0 FAILs