Three fixes:
1. gql() default vars '${2:-{}}' — bash parsed first '}' as closing the
parameter expansion, appending a stray '}' to every caller's vars.
Fixed by storing '{}' in a local variable first.
2. make_vars() — add VAR_INT_KEYS support so groupId is emitted as a
JSON integer (Int!) rather than a string, matching LLDAP's schema.
3. Password setting — LLDAP has no GraphQL mutation for admin password
reset. Replace the broken resetUserPasswordFromAdmin mutation with
an RFC 3062 LDAP Password Modify operation via kubectl port-forward
to the in-cluster LLDAP service, using ldap3.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
--test derives the password from the display name (spaces → hyphens, append -Pwd),
e.g. "Test User" → "Test-User-Pwd". Skips the interactive prompt.
Useful for provisioning test accounts in a non-interactive flow.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Pass GraphQL query/variables and group names via environment variables
to python3 instead of shell argument interpolation. Prevents breakage
when display names, emails, or passwords contain quotes or spaces.
Also adds --admin flag support and interactive password prompt.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Creates a user in LLDAP via GraphQL, adds them to net-kingdom-users,
optionally net-kingdom-admins (--admin flag), and sets a password interactively.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Once any admin policy exists, PI enforces it for all admins. Without an
explicit policy, pi-admin is locked out of the REST API after trigger-admin-rights
is created. Add pi-admin-all-rights (scope=admin, action=*) via pi-manage
(in-pod) as step 5, before the REST-based trigger-admin-rights step.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
PI_NO_RESPONSE_SIGN=True works around Werkzeug 3.x crash where request.json
raises BadRequest on GET requests with empty bodies (sign_response path).
Rate limit raised from 20/5 to 200/100 req/min to allow the AngularJS UI's
burst of ~50 parallel static asset requests on each page load without being
throttled by Traefik. TODO: split tight /auth+/validate vs loose /static limits.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Added allow-traefik-to-acme-solver NetworkPolicy to sso and mfa namespaces.
The default-deny-all policy was blocking HTTP-01 challenge traffic from Traefik
to the cert-manager solver pods, causing all TLS certs to stay pending (502).
Workplan NK-WP-0003 updated: T02, T03, T04, T05, T06, T07, T08a all done on
RAILIANCE01 as of 2026-03-25. T08 (e2e auth test) is now unblocked.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
All 3 KeyCape test packages pass (migration, negative, profile).
DNS resolves for all 4 subdomains; Go 1.22.10 available at ~/go/bin/go.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- 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>