net-kingdom/sso-mfa/WORKPLAN.md
tegwick 84c5dbeec8
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 2s
security: retire unsafe legacy LDAP lifecycle callers
Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a1346b-72a4-7d40-b8bd-8b8ca346cfa2
2026-10-14 00:08:42 +02:00

9.3 KiB
Raw Blame History

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 mfa namespace)

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 PVCs
  • k8s/privacyidea/configmap.yaml — pi.cfg template (secrets injected at runtime)
  • k8s/privacyidea/create-secrets.sh — privacyidea-config Secret
  • k8s/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.social
  • k8s/privacyidea/enckey-bootstrap.sh — extract enckey + audit keys post-start
  • k8s/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-wf858 is deployed in mfa namespace but stuck in ImagePullBackOff
  • Image privacyidea/privacyidea:3.12 does 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 missing coulomb realm/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.sh only 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 API
  • k8s/lldap/break-glass.sh — creates the break-glass bypass account and assigns to net-kingdom-admins
  • k8s/verify-t07.sh — verifies groups, break-glass user, self-service portal, OIDC client registrations

Pending (needs live cluster)

  • Run lldap/bootstrap-users.sh to 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/up
  • k8s/backup/DR-RUNBOOK.md — full restore runbook: scenarios, restore order, node rebuild procedure, offsite export
  • k8s/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-test kubectl create job -n sso --from=cronjob/authelia-backup authelia-backup-test kubectl 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