All checks were successful
Map uncaught HTTPError from LLDAP login to a structured dependency_unavailable response, add /readyz as the provisioner-to-directory preflight, keep /healthz as process liveness, and run the contract in CI. Auth rejection is not retried during cooldown. NK-WP-0036-T05 remains in progress until the immutable image is published, pinned with /readyz, and one native login/create/password-setup journey is verified. Assistant: grok Assistant-Session: 01a09dc6-3f0e-78f1-a884-c8c703c24ddf
199 lines
9.7 KiB
Markdown
199 lines
9.7 KiB
Markdown
---
|
|
id: NK-WP-0036
|
|
type: workplan
|
|
title: "Restore native portal login and tenant-onboarding integration"
|
|
domain: infotech
|
|
repo: net-kingdom
|
|
status: active
|
|
owner: the-custodian
|
|
topic_slug: netkingdom
|
|
created: "2026-09-11"
|
|
updated: "2026-09-14"
|
|
related: [KEY-WP-0007, RAPPS-WP-0014, VERGABE-WP-0019]
|
|
state_hub_workstream_id: "6e1358d6-87e4-52e7-b3dd-09abdc48cefc"
|
|
---
|
|
|
|
The demo-company operator login returns `invalid_profile_usage`, feature
|
|
`client_id`, description `unknown client_id`. The approved public client from
|
|
KEY-WP-0007 is absent from live `sso/keycape-config`. The bootstrap generator
|
|
also omits it; this is a demonstrated regeneration hazard, not proof of which
|
|
historical change removed the live registration. User requests retry/repair
|
|
under continued demo-tenant onboarding authority.
|
|
|
|
## Preserve the existing registration in source and prepare the bounded repair
|
|
|
|
```task
|
|
id: NK-WP-0036-T01
|
|
status: done
|
|
priority: high
|
|
state_hub_task_id: "7f30efcb-beac-5843-bca7-a5cbc1c715cc"
|
|
```
|
|
|
|
Keep `user-engine-portal` public, authorization-code/S256 PKCE, exact callback
|
|
`https://users.92-205-62-239.nip.io/oidc/callback`, and only
|
|
`openid profile email groups`. Add the existing declaration to the bootstrap
|
|
generator and test equality with `register-user-engine-portal.py`.
|
|
`portal-client-rollout.py` adds only a missing declaration, preserving other
|
|
configuration bytes and Secret data. It refuses changed/duplicate registrations,
|
|
controller ownership, wrong cluster and stale UID/resourceVersion. Secret values
|
|
stay in memory/child stdin and never enter output, arguments or persisted files.
|
|
Four synthetic regression tests pass. No credentials or roles are granted.
|
|
|
|
## Restore and verify the live login entry point
|
|
|
|
```task
|
|
id: NK-WP-0036-T02
|
|
status: done
|
|
priority: high
|
|
state_hub_task_id: "8a3c3e91-d604-59ee-9d15-f79223667780"
|
|
```
|
|
|
|
Inspect and server-dry-run the exact observed Secret revision, apply the bounded
|
|
patch, read back unchanged unrelated data, and restart the existing KeyCape
|
|
deployment to load configuration. Keep the current image and 25m resources.
|
|
Record readiness and valid-client authorize redirect, invalid-callback and
|
|
missing-PKCE refusal. Reopen a fresh portal login only after positive preflight.
|
|
Actual human login and demo tenant creation continue in RAPPS-WP-0014-T02;
|
|
this repair alone is not evidence of tenant existence or operator entitlement.
|
|
|
|
If native verification fails, retain the exact non-secret failure and reconcile
|
|
the current resource revision; do not replay a stale complete Secret. Hand any
|
|
remaining actionable defects to live records before finishing this plan.
|
|
|
|
Live repair succeeded on 2026-09-11. The exact missing client was added without
|
|
changing unrelated Secret data. KeyCape restarted at its existing image and
|
|
resources. Valid authorization redirects to Authelia; wrong callback and missing
|
|
PKCE are refused. The operator subsequently authenticated as platform-root and
|
|
reached the platform form. See docs/evidence/2026-09-11-native-portal-repair.md.
|
|
|
|
## Repair and verify the portal-to-tenant policy contract
|
|
|
|
```task
|
|
id: NK-WP-0036-T03
|
|
status: done
|
|
priority: high
|
|
state_hub_task_id: "378b03b3-aedc-50c3-8de7-94064794582b"
|
|
```
|
|
|
|
The real form submission returned provisioning_unavailable, correlation
|
|
corr_d41f417c61713afc7ddea08f. Tenant Engine logs show POST /tenants returning
|
|
403 before its create transaction. Its PDP recognizes only tenant-engine and
|
|
flex-auth; the shipped portal calls as user-engine. Tenant read is also missing
|
|
from that policy despite the shipped endpoint requiring it.
|
|
|
|
Register the existing user-engine service for only non-platform tenant create
|
|
and read in flex-auth/examples/tenant-engine. Keep ServiceAccount caller auth
|
|
enforced. Preserve denied grants, lifecycle, plan and guardrail mutations.
|
|
In user-engine, preserve display name and correlation id in the create request,
|
|
and map authority denial to the existing redacted 403 path, proving that no
|
|
administrator is created after a tenant-authority denial.
|
|
|
|
Run owner regression suites, publish through existing Forgejo image CI, pin and
|
|
roll only the Tenant Engine PDP and rapp-user-engine runtime, and verify the
|
|
actual allowed/denied contract with authenticated consumer calls. Then reconcile
|
|
native demo tenant existence before retrying the operator form. RAPPS-WP-0014
|
|
retains actual tenant onboarding and product placement; this workplan does not
|
|
claim tenant existence or application readiness from component tests alone.
|
|
|
|
Completed: both owner suites and CI images passed, the Tenant Engine PDP and
|
|
User Engine runtime were independently promoted by immutable digest, nine live
|
|
policy/caller checks passed, and native demo-company readback returns not-found.
|
|
Remaining actual operator submission, administrator onboarding and application
|
|
placement remain live in RAPPS-WP-0014-T02 and VERGABE-WP-0019-T03/T04. This
|
|
integration repair is complete; the invited product pilot is not yet admitted.
|
|
|
|
|
|
Follow-through: the operator submitted the native form successfully at 19:03:18
|
|
UTC. Independent authority readback confirms demo-company active/version 1;
|
|
User Engine shows the first administrator as invited. Remaining ordinary members,
|
|
identity activation and product accounts are retained in RAPPS-WP-0014-T02.
|
|
|
|
|
|
## Reconcile the identity provisioner's rejected directory credential
|
|
|
|
```task
|
|
id: NK-WP-0036-T04
|
|
status: done
|
|
priority: high
|
|
needs_human: false
|
|
state_hub_task_id: "3497d77a-1dc2-5fe6-8784-33949321f556"
|
|
```
|
|
|
|
A subsequent native Create login fails before directory identity creation, at
|
|
LLDAPProvisioner._login, HTTP 401. The existing identity-provisioner image
|
|
5b460f5c was restarted to reload its lldap-secrets reference; readiness passed
|
|
but contained provider authentication still returns 401. No provider credential
|
|
was changed and no rejected create was replayed. Native user records remain.
|
|
|
|
The non-printing, field-only attended repair and seven synthetic tests are
|
|
prepared at sso-mfa/k8s/lldap/identity-provisioner-reconcile.py. See
|
|
docs/identity-provisioner-bind-repair.md for exact scope, operator input,
|
|
metadata guard, candidate authentication, apply, reload and verification.
|
|
The operator completed the hidden-input apply on 2026-09-11. Its sanitized
|
|
receipt confirms provider_login and consumer_login true, provider_password_changed
|
|
false, and the existing Secret resourceVersion advanced from 51345775 to
|
|
60026132. Independent consumer login plus directory-read verification returns
|
|
reloaded-check-passed; the deployment is ready 1/1 at its unchanged image.
|
|
The existing native user can now retry Create login; successful identity linkage
|
|
and password setup remain the pilot onboarding task. The unresolved warden route is a pointer, not authority
|
|
to export another live Secret. Retain NK-WP-0033's separate incident residuals.
|
|
|
|
## Make dependency failure visible before another human onboarding attempt
|
|
|
|
```task
|
|
id: NK-WP-0036-T05
|
|
status: progress
|
|
priority: high
|
|
state_hub_task_id: "46d33ab6-d76b-537f-8d60-32c4451675b5"
|
|
```
|
|
|
|
Cover the real provisioner-to-directory contract in a contained preflight,
|
|
return a redacted structured dependency failure instead of an uncaught HTTPError,
|
|
and make CI execute those contract tests. Keep process liveness distinct from
|
|
functional readiness. Publish and promote through a reviewed immutable image
|
|
lane, then verify provider login, user creation/linkage and password setup as a
|
|
single native onboarding journey. Preserve credential secrecy and avoid
|
|
unbounded password-check retries. Actual demo users and application admission
|
|
remain RAPPS-WP-0014 and VERGABE-WP-0019.
|
|
|
|
2026-09-14 agent implementation (not yet done): source now maps directory
|
|
HTTPError/URLError to redacted `{"error":"dependency_unavailable",
|
|
"dependency":"directory","reason":"auth_rejected|unreachable|protocol_error"}`.
|
|
`GET /healthz` remains process liveness; `GET /readyz` runs one login plus one
|
|
directory read. Auth rejection is cached for 30s so probes do not retry a
|
|
rejected password unbounded. 28 provider tests pass locally, including the new
|
|
directory-contract suite. identity-journeys CI discovers those tests;
|
|
identity-provisioner-image.yaml is the immutable publish lane.
|
|
|
|
Remaining operator steps before T05 can be marked done:
|
|
1. Push this commit to `main` so identity-journeys and identity-provisioner-image
|
|
run. Confirm journeys green, then record the image digest from
|
|
`coulomb/identity-provisioner`.
|
|
2. Pin that digest in `sso-mfa/k8s/identity-provisioner/deployment.yaml`, switch
|
|
readiness to `/readyz` with `timeoutSeconds: 5` or higher, keep liveness on
|
|
`/healthz`, apply, and confirm Ready 1/1 with `/readyz` returning
|
|
`{"status":"ready","dependency":"directory"}`.
|
|
3. Verify one native onboarding journey: provider login, user create/linkage,
|
|
password setup. Do not retry a rejected password in a loop. Demo users and
|
|
application admission stay RAPPS-WP-0014 and VERGABE-WP-0019.
|
|
|
|
|
|
## Admit the canonical users hostname and preserve callback validation
|
|
|
|
```task
|
|
id: NK-WP-0036-T06
|
|
status: done
|
|
priority: high
|
|
state_hub_task_id: "d736f4d1-1c97-5cf3-894e-600ea113c785"
|
|
```
|
|
|
|
Operator supplied DNS for users.coulomb.social on 2026-09-12. The contained
|
|
portal-client-rollout helper now upgrades only the exact legacy public client
|
|
by appending https://users.coulomb.social/oidc/callback. It preserves unrelated
|
|
configuration bytes and Secret fields; six synthetic tests pass, including
|
|
idempotence and refusal of altered scopes/type/callbacks. The bootstrap and
|
|
registration declarations agree. Server dry-run passed; guarded Secret revision
|
|
59999030 became 60090393, UID unchanged. KeyCape restarted at its unchanged
|
|
image/resources. Canonical authorize redirects to Authelia; wrong callback and
|
|
missing PKCE return 400. The runtime package owns portal routing and callback
|
|
cutover; final human login confirmation is recorded there. No password rotated.
|