net-kingdom/docs/identity-provisioner-bind-repair.md
tegwick c8ad7a85ea
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
docs: record verified identity provisioner credential repair
Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a07ff8-19d0-7820-b4d0-1353833cb7fc
2026-09-11 22:00:37 +02:00

4.4 KiB

Repair the identity provisioner's stored LLDAP credential

NK-WP-0036-T04, 2026-09-11. Attended live repair completed and independently verified.

The native User Engine Create login request reached identity-provisioner, whose LLDAP admin login returned HTTP 401 before identity creation. Reloading the existing lldap-secrets reference did not fix it. The tenant and user-domain records are independent and remain intact. Root portal login is working.

This procedure performs an attended consumer-reference reconciliation. It does not rotate the LLDAP account, change signing keys, restore an exposed predecessor, read a Secret payload, or rebuild KeyCape's configuration. The operator must supply the currently working LLDAP admin password from existing custody through a hidden terminal prompt. The platform-root portal password is a different input. No value belongs in chat, shell arguments or work records. Do not fetch values through the unresolved warden pointer lane or a Kubernetes Secret export.

The owner contract is warden route net-kingdom-lldap-bind-credential, with railiance-platform custody and the NetKingdom attended procedure. Operator acceptance of this narrow repair is required before its explicit apply command; the older full-bundle incident approval is not reused. If the current working credential is unavailable, stop at the custody-owner recovery boundary.

The helper is sso-mfa/k8s/lldap/identity-provisioner-reconcile.py. Run inspect first; it emits only the exact Secret UID/resourceVersion and rejects controller ownership or the wrong cluster:

python3 sso-mfa/k8s/lldap/identity-provisioner-reconcile.py inspect
python3 sso-mfa/k8s/lldap/identity-provisioner-reconcile.py check

check requires an interactive terminal and a hidden current-password prompt. It authenticates the existing admin against the pinned in-cluster LLDAP URL and performs a directory read. It changes no provider or consumer state.

Use the current UID/resourceVersion from inspect. The following command records the accepted and completed 2026-09-11 execution; its old resourceVersion will now be refused:

python3 sso-mfa/k8s/lldap/identity-provisioner-reconcile.py apply   --expected-uid c6a9e6be-5bb5-47e6-9faa-06b8d72afec3   --expected-resource-version 51345775

The helper validates the candidate against the provider before any write, server dry-runs a JSON patch, then updates only lldap-secrets/LLDAP_LDAP_USER_PASS with UID/resourceVersion tests. Values travel only in child stdin/process memory; there is no temporary credential file, Secret export or full-manifest output. It restarts only identity-provisioner, waits for readiness and verifies the reloaded credential through the consumer. Failure after a successful field update is reported as incomplete verification; the rejected old value is never restored. Other login services and the LLDAP provider are not restarted.

Seven synthetic tests cover exact patch scope, stale metadata and controller refusal, candidate rejection before writes, check-only behavior, stdin-only value handling, redaction of child errors and the apply/reload/proof sequence. The operator subsequently supplied the working password only through the hidden terminal prompt and completed apply. Its sanitized receipt reports result reconciled, provider_login true, consumer_login true, and provider_password_changed false. Secret UID is unchanged; resourceVersion is now 60026132. Independent verification from the restarted consumer confirms directory authentication plus a directory read. Deployment readiness is 1/1, with its existing image digest 5b460f5ca9e329e287939f4707a2bb8d5674b7f94e24cfb5f6d790f54c3f8d06. No native user/password-setup completion is inferred from these service checks.

After success, retry Create login only for the existing intended user, inspect the returned password-setup page and record the native identity linkage. Password setup links are private, short-lived and must not enter evidence. User Engine's display name is not necessarily its directory username: the current provider derives a name from email unless preferred_username is sent. Keep the requested demo login-name mapping explicit before provisioning.

Follow-up remains necessary for credential custody/publication and a functional provisioner preflight: the current /healthz confirms process health while the directory connection is broken. The HTTP handler also fails to catch the upstream HTTPError. These are tracked in NK-WP-0036-T05.