Commit Graph

65 Commits

Author SHA1 Message Date
eebaa4fc81 chore(workplan): add T08a (DNS records) and T08b (Go install) tasks
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-22 00:40:40 +00:00
d1fd73e7ed chore(workplan): NK-WP-0003-T08 blocked — DNS records + Go missing
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-22 00:36:56 +00:00
c8c6efbc55 chore(workplan): NK-WP-0003-T07 done — KeyCape running
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-22 00:32:45 +00:00
880f89bf98 fix(keycape): NK-WP-0003-T07 — fix deployment image + add demo-app client
- deployment.yaml: image → 92.205.130.254:32166/coulomb/key-cape:latest
  (Gitea OCI registry, delivered by KEY-WP-0002; imagePullPolicy: Always)
- k3s insecure registry hosts.toml: fixed server endpoint to http:// so
  containerd does not attempt HTTPS against the plain-HTTP Gitea NodePort
- create-secrets.sh: add demo-app OIDC client (required for KeyCape to
  start; also needed for T08 acceptance tests)
- keycape-config Secret updated in-place (no re-bootstrap needed)

KeyCape pod 1/1 Running; /healthz OK; OIDC discovery live at
https://kc.coulomb.social/.well-known/openid-configuration

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-22 00:30:58 +00:00
d0629e7f20 chore(workplan): NK-WP-0003-T07 blocked — awaiting GHCR image from key-cape
Deployment applied; pod in ImagePullBackOff. Secrets already correct.
Capability request 0e0aefd7 filed; key-cape must publish ghcr.io image.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-21 22:24:32 +00:00
f2f07871eb fix(sso-mfa): commit T02–T06 fixes and workplan status updates
- authelia: users_filter uid→{username_attribute}, OIDC client secret
  moved from env var to inline bcrypt hash in configmap (4.38 limitation)
- authelia: remove unsupported CLIENTS_0_SECRET_FILE env var
- lldap: drop runAsNonRoot/runAsUser (image init requires root)
- verify-t02: keycloak→keycape NetworkPolicy check rename
- workplan: T02/T03/T05/T06 marked done with notes

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-21 20:25:03 +00:00
a60f4fc834 chore(workplan): NK-WP-0003-T04 done — privacyIDEA deployed and bootstrapped
Pod Running with correct image and config. enckey, audit keys, pi-admin,
trigger-admin all created via agent bootstrap (NK-WP-0005).
Remaining: TLS cert + trigger-admin policy via WebUI.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-21 12:13:52 +00:00
59ba9e6fe1 fix(creds-bootstrap): harden agent bootstrap for non-interactive execution
- creds-bootstrap-agent.sh: skip Phase 3 if all secrets already applied
  (avoids CNPG SSL connection drops from repeated reconciliation)
- creds-bootstrap-agent.sh: wait for rollout to complete after restart
  before running enckey/admin bootstrap (fixes race with old pod)
- creds-bootstrap-agent.sh: only restart privacyIDEA when Phase 3 ran
- create-pi-token.sh: use env-var + retry for token fetch (no heredoc
  stdin; handles transient 500 from idle connection pool)
- create-pi-token.sh: create keycape-pi-token K8s Secret after fetching
- creds-verify.sh: map keycape-pi-token to secrets_applied.keycape
  (not pi_admin_created, which caused spurious Phase 5 re-runs)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-21 12:11:13 +00:00
56036cd4be chore(creds): bootstrap complete [agent NK-WP-0005] 2026-03-21 12:10:53 +00:00
329f086743 chore(creds): encrypted secrets [agent NK-WP-0005] 2026-03-21 12:09:53 +00:00
aa0edabb81 chore(creds): encrypted secrets [agent NK-WP-0005] 2026-03-21 11:43:02 +00:00
49ded70e4b chore(creds): encrypted secrets [agent NK-WP-0005] 2026-03-21 11:37:13 +00:00
eb7c21a00c chore(creds): encrypted secrets [agent NK-WP-0005] 2026-03-21 11:34:50 +00:00
152c2aac72 chore(creds): encrypted secrets [agent NK-WP-0005] 2026-03-21 11:24:38 +00:00
daeeb863cb chore(creds): encrypted secrets [agent NK-WP-0005] 2026-03-21 11:22:53 +00:00
ca853a84b7 chore(creds): encrypted secrets [agent NK-WP-0005] 2026-03-21 10:59:13 +00:00
5d032db3dd chore(creds): encrypted secrets [agent NK-WP-0005] 2026-03-21 10:51:47 +00:00
0ea05b302c chore(creds): encrypted secrets [agent NK-WP-0005] 2026-03-21 10:50:22 +00:00
963a4700ef chore(creds): encrypted secrets [agent NK-WP-0005] 2026-03-21 10:44:37 +00:00
33b9b93dba chore(creds): encrypted secrets [agent NK-WP-0005] 2026-03-21 10:42:39 +00:00
f227dfbd3d fix(privacyidea): add PI_ADDRESS/PI_PORT; switch readiness probe to tcpSocket
gpappsoft entrypoint requires PI_ADDRESS and PI_PORT env vars to build
the gunicorn bind argument. Without them the container crashes immediately.

/token/ returns 401 for unauthenticated GET requests so the httpGet
readiness probe was permanently failing. Switch to tcpSocket to match
the startup and liveness probes.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-21 10:41:13 +00:00
9587d14803 fix(privacyidea): override PRIVACYIDEA_CONFIGFILE to use mounted pi.cfg
gpappsoft image sets PRIVACYIDEA_CONFIGFILE=/privacyidea/etc/pi.cfg
internally, causing it to ignore our mounted configmap at
/etc/privacyidea/pi.cfg and fall back to SQLite.

Override the env var so the entrypoint reads our pi.cfg, which points
to PostgreSQL via PI_SQLALCHEMY_DATABASE_URI from the secret.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-21 09:43:35 +00:00
bececac7b8 fix(privacyidea): correct image to ghcr.io/gpappsoft, port 5001→8080
privacyidea/privacyidea:3.12 and privacyidea/otpserver:3.12.2 do not
exist on Docker Hub. Correct image is ghcr.io/gpappsoft/privacyidea-docker:3.12.2
which listens on port 8080.

Update all port references: deployment, service, ingress, netpol-mfa,
netpol-sso (keycape→privacyIDEA egress rule).

Also: creds-bootstrap-agent.sh — restart privacyIDEA deployment after
applying new secrets so the pod picks up updated env vars.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-21 09:37:38 +00:00
bcae4bc6dd fix(workplans): portable key-cape path in NK-WP-0003-T08; add /creds-init skill
- NK-WP-0003 T08: replace hardcoded /home/worsch/key-cape with
  $(git rev-parse --show-toplevel)/../key-cape so acceptance tests
  run correctly on any machine
- NK-WP-0005 T04: create .claude/commands/creds-init.md — the
  autonomous credential bootstrap skill (reads creds-state.yaml,
  resumes from current phase, honours emergency bundle gate)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-21 10:01:14 +01:00
0670e17b42 chore(workplans): revise workplans post NK-WP-0005
NK-WP-0005: mark all tasks done, status → done
NK-WP-0003: T01 marked done (NK-WP-0004/0005 complete); pre-conditions
  updated; done criteria reflect agent-bootstrap model (no KeePassXC)
NK-WP-0001: status → deferred; T05-T08 (Keycloak) deferred indefinitely;
  superseded_by: NK-WP-0003 added

Active work path is now NK-WP-0003 T02-T09.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-21 08:47:44 +00:00
95656f2324 feat(creds): NK-WP-0005 — agent-driven credential bootstrap
Implements all 7 tasks from NK-WP-0005:

T01: creds-state.yaml → schema_version: 2, agent_mode: true
     Replaces keepass_confirmed with emergency_bundle_delivered,
     adds phase tracking fields for fully automated flow.

T02: creds-bootstrap-agent.sh — single entrypoint for autonomous
     bootstrap. 10 phases, idempotent re-runs via state file.
     Only human touchpoint: emergency bundle confirmation gate.

T03: emergency-bundle.sh — assembles and displays emergency bundle
     (age key + break-glass passwords + ops bundle location).
     Writes temp file, shreds on confirmation, clears screen.
     Supports --reprint for re-delivery.

T04: ~/.claude/commands/creds-init.md — /creds-init skill replaces
     /creds-bootstrap. Fully autonomous execution via the agent.

T05: Makefile — creds-agent-init, creds-agent-status,
     creds-emergency-reprint targets.

T06: creds-rotate.sh — --non-interactive flag for agent-driven
     rotation. Auto-confirms all gates; tracks last_rotated_<key>
     in creds-state.yaml. LLDAP web UI step prints warning in
     non-interactive mode.

T07: canon/standards/credential-management_v0.2.md — updated
     standard: KeePassXC removed from operational path, agent
     bootstrap as Phase 0, emergency bundle section, prohibited
     patterns updated.

Also: creds-status.sh handles both schema v1 (legacy) and v2.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-21 08:38:52 +00:00
8db000e5f0 feat(workplan): NK-WP-0005 — agent-driven credential bootstrap
Replaces the human-as-operator model from NK-WP-0004 with full agent
automation. Agent generates, encrypts (SOPS), injects into cluster,
and delivers a single emergency bundle (age key + break-glass passwords).
Human only stores that bundle in their personal password manager.

KeePassXC removed from operational path. creds-state.yaml redesigned
with agent_mode and emergency_bundle_delivered gate. Standard to be
updated to v0.2 (T07).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-21 09:25:36 +01:00
b4a3a5966f chore(consistency): NK-WP-0004 complete — correct regressed task statuses
All 7 tasks were implemented in c10d7d2 but fix-consistency on the
workstation reverted all statuses to todo (CUST-WP-0026 regression bug).
Corrected all task blocks to status: done and workplan status to done.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-21 09:19:37 +01:00
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
a96d72193c New Workplans 2026-03-21 00:25:42 +01: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
0d5d12cb67 Added provided capabilities section 2026-03-20 01:01:52 +01: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
87d85261ca docs: add SCOPE.md for rapid orientation
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-17 23:10:45 +01: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
7c3cde06b5 docs: introduce CONFIG.md config point registry (CP-NK-001)
Establishes the local config point registry pattern. A config point is an
explicit non-default value that cannot be derived from topology, naming
convention, component defaults, or automation. Minimizing the list is a
design goal — absence of an entry means "accepting the upstream default".

CP-NK-001: ACME contact email (bernd.worsch+netkingdom@gmail.com)
  Location: sso-mfa/k8s/cert-manager/issuers.yaml:38
  Why non-default: ACME requires a real monitored inbox; no system default
  qualifies. Automation via Local Identity GECOS email is deferred.

State-hub extension point EP 8e1cda6a registered in custodian domain:
  "Config point registry: centralized view of explicit non-default
  configuration values" — proposes ConfigPoint entity type + MCP tools
  + cross-domain minimization metric.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-02 11:47:14 +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
52d44daec2 refactor(local-identity): post-Stage4 cleanups and micro-fixes
- audit: chmod only on file creation, not every append (TOCTOU fix)
- jwt_utils: add extract_unverified_payload() helper
- cli: use extract_unverified_payload + JWTError instead of inline decode
- keys: extract _public_key_bytes() helper, import _b64url from jwt_utils
- security: FileNotFoundError try/except instead of path.exists() (TOCTOU fix)
- serve: cache JWK response at server init instead of per-request recompute

138 tests passing.

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