net-kingdom/docs/identity-provisioner-bind-repair.md
tegwick 8dc5050aa3
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Pin identity-provisioner digest and readiness to directory preflight
Promote CI image sha256:3317a2610ef9958b77cb258dce54d69d13dfabbc55ffaad673e018f997a6467c
with /readyz readiness and Recreate rollout. Live /healthz stays process
liveness; /readyz returned directory ready. Native onboarding remains for T05.

Assistant: grok
Assistant-Session: 01a09dc6-3f0e-78f1-a884-c8c703c24ddf
2026-09-14 04:57:39 +02:00

80 lines
4.7 KiB
Markdown

# 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:
```sh
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:
```sh
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.
NK-WP-0036-T05 adds `/readyz` as a contained provisioner-to-directory preflight
(one login plus one directory read), maps bind failures to a redacted
`dependency_unavailable` JSON body, and keeps `/healthz` as process liveness.
Auth rejection is not retried during a cooldown so kube probes cannot hammer a
rejected password. Synthetic contract tests run in identity-journeys CI.
Image sha256:3317a2610ef9958b77cb258dce54d69d13dfabbc55ffaad673e018f997a6467c
is live with `/readyz` readiness; a native onboarding journey is still required
before T05 is done. See the T05 workplan note.