- 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>
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>
- 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>
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>
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>
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>
- 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>
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>
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>
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>
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>
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>
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>
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>
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>