Commit Graph

17 Commits

Author SHA1 Message Date
6fdfe8a669 chore 2026-03-21 00:15:58 +00:00
01c8a07f3a fix(sso-mfa): NK-WP-0003-T04 — correct privacyIDEA image and port
privacyidea/privacyidea:3.12 does not exist on Docker Hub.
Correct image: privacyidea/otpserver:3.12.2 (port 5001).

Updated files:
- deployment.yaml: image, containerPort, probes, service port
- ingress.yaml: backend service port
- netpol-mfa.yaml: ingress port + keycloak → keycape label
- netpol-sso.yaml: KeyCape egress port to privacyIDEA

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-20 23:54:18 +00:00
c10d7d2f8a feat(creds): implement NK-WP-0004 Credential Management Foundation
- .sops.yaml + keys/age.pub: SOPS age encryption for all secrets/ paths
- .gitignore: broad secrets/ catch-all (any depth)
- .githooks/pre-commit: blocks unencrypted secrets/, *.env outside bootstrap/,
  and known plaintext patterns (PI_SECRET_KEY=, LLDAP_JWT_SECRET=, etc.)
- Makefile: full credential lifecycle (creds-init/generate/bundle/apply/verify/
  status/rotate) + SOPS helpers (sops-setup/edit/encrypt/decrypt/rotate/check-secrets)
  + hooks/hooks-test
- creds-apply.sh: runs create-secrets.sh in dependency order (postgresql → lldap →
  authelia → privacyidea), skips keycape with printed instructions, updates state
- creds-verify.sh: checks all K8s secrets exist, updates creds-state.yaml
- creds-status.sh: human-readable state table from creds-state.yaml
- creds-rotate.sh: guided rotation for all 9 secret types with impact descriptions
  and atomic multi-component update sequences
- creds-state.yaml: committable state file tracking generation, bundle, KeePassXC
  confirmation, per-component apply status, enckey and pi-admin bootstrap flags

NK-WP-0003-T01 unblocked. /creds-bootstrap skill registered separately.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-20 23:39:35 +00:00
2bbe328aec docs(sso-mfa): record T04 blocker — wrong image reference (ImagePullBackOff)
privacyidea/privacyidea:3.12 does not exist on Docker Hub. Pod is deployed
but stuck. Correct image reference must be identified before proceeding.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-20 17:16:35 +00:00
bee0936d5d docs(sso-mfa): fix stale Keycloak refs and add T04 apply section to WORKPLAN
- README.md: ipAllowList → ipWhiteList (match Traefik v2 fix)
- verify-t04.sh: update success message (Keycloak → LLDAP+Authelia+KeyCape)
- WORKPLAN.md: add full T04 section with deliverables, pending steps, done-criteria

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-20 07:33:47 +00:00
a375b3814d fix(sso-mfa): use ipWhiteList for Traefik v2 in LLDAP and privacyIDEA middleware
Traefik 2.10 (K3s 1.30 bundle) requires ipWhiteList, not ipAllowList.
Updated both middleware files and clarified comments to match cluster version.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-20 07:28:06 +00:00
6d25d088d7 feat(sso-mfa): T02/T03 live apply — age-encrypted secrets, CNPG cluster (NK-WP-0001-T02/T03)
- Add encrypt-secrets.sh / decrypt-secrets.sh: age-based secrets workflow
  replaces KeePassXC dependency; encrypted .env.age files committed to repo
- Add bootstrap/secrets.enc/: all component secrets encrypted to age pubkey
- Fix .gitignore: allow secrets.enc/**/*.age while blocking plaintext
- Fix verify-t02.sh: update netpol names for Authelia+LLDAP+KeyCape stack
- Fix verify-t03.sh: remove keycloak_db/role checks; fix ((PASS++)) set-e bug
- Update postgresql/cluster.yaml: drop keycloak_db, bootstrap privacyidea_db only
- Update postgresql/create-secrets.sh: remove keycloak secret
- Fix netpol-databases.yaml: add port 8000 for CNPG instance manager HTTP API
- T02 COMPLETE: namespaces, network policies, cert-manager issuers applied
- T03 COMPLETE: CNPG operator installed, net-kingdom-pg cluster healthy

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-20 02:57:41 +00:00
6c062e1295 feat(sso-mfa): T07/T08 user mgmt, backups, DR & break-glass (NK-WP-0001-T07/T08)
T07 — User management & self-service:
- k8s/lldap/bootstrap-users.sh: creates net-kingdom-users and net-kingdom-admins
  groups in LLDAP via GraphQL API; idempotent.
- k8s/lldap/break-glass.sh: creates break-glass bypass account in LLDAP,
  sets BREAKGLASS_PASSWORD, assigns to net-kingdom-admins.
- k8s/verify-t07.sh: 6 checks — groups, break-glass, self-service portal,
  KeyCape OIDC client registrations.

T08 — Backups, DR, break-glass:
- k8s/backup/cronjob-sqlite-backups.yaml: daily CronJobs for LLDAP SQLite,
  Authelia SQLite (with scale-down/up RBAC), and privacyIDEA enckey backup.
  7-day retention, 03:00/03:15/03:30 UTC staggered schedule.
- k8s/backup/DR-RUNBOOK.md: full restore runbook — scenarios, restore order,
  LLDAP/Authelia/PI SQLite restore procedure, full node rebuild sequence,
  offsite age-encrypted export.
- k8s/verify-t08.sh: 9 checks — CronJobs, RBAC, run history, backup files
  on PVCs, DR runbook presence, offsite backup (manual confirmation).
- WORKPLAN.md: T07/T08 sections with done-criteria added.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 09:17:03 +00:00
69e900ddb1 feat(sso-mfa): T06 realm config & MFA flow manifests (NK-WP-0001-T06)
- k8s/privacyidea/bootstrap-realm.sh: creates LLDAP resolver
  "lldap-netkingdom", the "netkingdom" default realm, TOTP self-enrollment
  policy, and passthru authentication policy (phase-1 rollout).
- k8s/verify-t06.sh: verifies realm, resolver, LDAP user resolution,
  KeyCape→privacyIDEA admin token, API connectivity, and policies.
- WORKPLAN.md: mark T05 done, add T06 section with done-criteria.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 09:04:07 +00:00
c0e17611cc chore(sso-mfa): mark T05 complete in WORKPLAN.md
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 08:32:35 +00:00
0754dc32e6 feat(sso-mfa): T05 SSO stack pivot — Keycloak → Authelia + LLDAP + KeyCape (NK-WP-0001-T05)
Replaces the Keycloak+privacyIDEA SSO tier with the lightweight stack built
during KEY-WP-0001: Authelia (password frontend), LLDAP (directory), and
KeyCape (OIDC orchestration). privacyIDEA is retained as the MFA engine.

Stack:
  kc.coulomb.social   — KeyCape OIDC server (stateless, custom Go)
  auth.coulomb.social — Authelia login portal (password auth → Authelia OIDC → KeyCape)
  lldap.coulomb.social — LLDAP admin UI (IP-restricted)
  pink.coulomb.social — privacyIDEA MFA engine (unchanged)

Changes:
- Remove sso-mfa/k8s/keycloak/ (7 files)
- Add sso-mfa/k8s/lldap/ (pvc, deployment, middleware, ingress, create-secrets, README)
- Add sso-mfa/k8s/authelia/ (pvc, configmap, deployment, ingress, create-secrets, README)
- Add sso-mfa/k8s/keycape/ (deployment, middleware, ingress, create-secrets, create-pi-token, README)
- Update network-policies/netpol-sso.yaml for new component topology
- Update verify-t05.sh: checks LLDAP + Authelia + KeyCape (23 checks)
- Update CONFIG.md: fix CP-NK-004 (KeyCape), add CP-NK-005 (Authelia), CP-NK-006 (LLDAP)
- Update bootstrap/gen-secrets.sh: add LLDAP/Authelia/KeyCape sections, remove Keycloak
- Update k8s/README.md: network policy table reflects new traffic paths
- Add sso-mfa/WORKPLAN.md: resumable task checklist

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 08:31:51 +00:00
d0ed7d9cd6 feat(sso-mfa): T05 Keycloak manifests (NK-WP-0001-T05)
Deploys Keycloak (SSO core) in the sso namespace.

Files:
  sso-mfa/k8s/keycloak/pvc.yaml          — keycloak-data PVC (build cache)
  sso-mfa/k8s/keycloak/middleware.yaml   — rate-limit, admin-allowlist, HSTS
  sso-mfa/k8s/keycloak/deployment.yaml   — Deployment + Service; init container
                                           downloads privacyIDEA provider JAR
  sso-mfa/k8s/keycloak/ingress.yaml      — Ingress for kc.coulomb.social (CP-NK-004)
  sso-mfa/k8s/keycloak/create-secrets.sh — keycloak-config Secret
  sso-mfa/k8s/keycloak/bootstrap-realm.sh— hardens master realm, creates net-kingdom realm
  sso-mfa/k8s/keycloak/README.md         — apply order, custom image guide, DR
  sso-mfa/k8s/verify-t05.sh              — T05 done-criteria verification script

Config points added: CP-NK-004 (kc.coulomb.social), CP-NK-005 (provider JAR URL).
CP-NK-005 must be set before applying deployment.yaml.

Pending: apply to live cluster, set CP-NK-005, run bootstrap-realm.sh, verify-t05.sh.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 02:00:51 +00:00
1d94652ba1 feat(sso-mfa): T04 privacyIDEA manifests (NK-WP-0001-T04)
Deploy privacyIDEA (MFA core) in the mfa namespace:
- pvc.yaml: privacyidea-data (5Gi) and privacyidea-logs (2Gi)
- configmap.yaml: pi.cfg reading secrets from env vars
- deployment.yaml: Deployment + ClusterIP Service (port 8080)
- middleware.yaml: Traefik RateLimit + admin IP AllowList
- ingress.yaml: pink.coulomb.social (portal + admin), pink-account.coulomb.social (self-service)
- create-secrets.sh: creates privacyidea-config Secret
- enckey-bootstrap.sh: post-deploy key extraction + DR Secrets
- bootstrap-admin.sh: pi-admin, trigger-admin, privacyidea-trigger-admin Secret
- verify-t04.sh: 8-section done-criteria checker

Config points CP-NK-002 (pink.coulomb.social) and CP-NK-003
(pink-account.coulomb.social) registered in CONFIG.md.

pink = PrivacyIDEA Net Knights (project mnemonic).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 01:22:41 +00:00
8929bf65bc feat(sso-mfa): T03 PostgreSQL manifests (NK-WP-0001-T03)
CloudNativePG Cluster CR (net-kingdom-pg, PostgreSQL 16) with two
application databases: keycloak_db (owner: keycloak) and privacyidea_db
(owner: privacyidea). Passwords managed continuously via managed.roles.
WAL archiving section stubbed and commented; activate when object storage
is available. ScheduledBackup CR included (daily 02:00 UTC, 7d retention).

Also: sync workplan status for T01 (Phase 0a done), T02 (manifests done),
T03 (manifests done, restore drill pending); close NK-WP-0002.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-05 09:22:13 +01:00
2ebb231f19 custodian integration and some cleanuo 2026-03-04 23:31:28 +01:00
ee794a61ab feat(sso-mfa): T02 K8s foundations manifests (NK-WP-0001-T02)
namespaces/namespaces.yaml:
  - sso, mfa, databases with net-kingdom/component labels for NetworkPolicy selectors

network-policies/{netpol-sso,netpol-mfa,netpol-databases}.yaml:
  - Default-deny-all posture on all three namespaces
  - sso: ingress from Traefik; egress to databases:5432 and mfa:8080
  - mfa: ingress from Traefik + Keycloak; egress to databases:5432
  - databases: ingress from sso/mfa + CNPG operator; egress to kube-dns + K8s API
  - DNS (kube-system:53) allowed for all pods in all namespaces

cert-manager/issuers.yaml:
  - selfsigned-issuer (ClusterIssuer) for internal/test use
  - letsencrypt-prod (ClusterIssuer, HTTP-01/Traefik) — fill ACME_EMAIL before apply
cert-manager/test-certificate.yaml:
  - 24h self-signed cert to smoke-test cert-manager

storage/verify-pvc.yaml:
  - Test PVC + Pod to confirm default StorageClass provisioning

verify-t02.sh:
  - Full verification script: namespaces, NetworkPolicies, issuers, certs, StorageClass

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-02 09:49:39 +01:00
c5761884f4 feat(sso-mfa): Phase 0a bootstrap tooling (NK-WP-0001-T01)
- sso-mfa/bootstrap/gen-secrets.sh: generates all pre-cluster secrets
  (PI_SECRET_KEY, PI_PEPPER, DB passwords, Keycloak admin, break-glass)
  into a structured secrets/ directory; prints summary with truncated values.
  PI_ENCFILE deferred — must be generated inside the privacyIDEA container.
- sso-mfa/bootstrap/pack-bundle.sh: age-encrypts the secrets directory into
  an offsite ops bundle.
- sso-mfa/bootstrap/README.md: KeePassXC group/entry structure, full workflow
  (generate → KeePassXC → bundle → shred → PI_ENCFILE post-deploy).
- .gitignore: add sso-mfa/bootstrap/secrets/, *.age, *.kdbx.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-02 09:01:50 +01:00