user-engine/docs/account-journeys.md
tegwick 259deb2763
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Establish scoped KeyCape factor custody and verified automatic renewal
Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a092fe-13b1-7f12-ac74-7d258af4d79c
2026-09-13 16:25:33 +02:00

15 KiB

Account and access journeys

Owner: user-engine, with KeyCape/NetKingdom for sign-in and factors, tenant-engine for tenant lifecycle, and applications for workload admission. Acceptance work: USER-WP-0027; OTP dependency: KEY-WP-0035 and NK-WP-0033. Reviewed against the portal on 2026-09-13. This is the browser acceptance contract; headless capability alone does not mean a journey is usable or verified live.

Common interaction rules

  • The header states the verified portal identity, or “Not signed in to this portal.” A valid portal session shows Log out; an absent/expired session shows Sign in. Never infer identity from URL parameters or an existing provider tab.
  • The portal cannot observe every application or shared-provider session. Explain this once in sign-out confirmation or expandable identity-switch help, not as competing login/logout actions everywhere. “Use another account” remains reachable when a wrong shared identity prevents portal login.
  • Log out opens a confirmation with the scope made explicit. GET never signs out. Invalid confirmation leaves the current session intact. Do not claim global sign-out when only the portal session ended.
  • Name the person, selected tenant, and application separately. Platform administration is not tenant membership and does not imply application access.
  • Every action has a visible result and a useful next step. Failure is not success; unknown provider state is not “disabled.” Keep recovery reachable before login.
  • Use one primary action per step, familiar wording, labelled fields and errors, keyboard-visible focus, and layouts usable on a phone. Preserve safe form input after validation failure; never redisplay secrets or trust unverified returns.
  • A status change requires authoritative confirmation. A sent message is not delivered mail; an invitation is not a login; opening a setup link is not OTP activation; recorded membership is not guaranteed workload admission.

User perspective

ID / intent Success Failure and recovery Current support / acceptance
U01 — Know whether I am signed in Header names my verified account; exactly the appropriate Sign in or Log out control Expired/unknown cookie shows signed-out state; sign in again Implemented; automated anonymous/expired/member/operator tests
U02 — Sign in to my company application Personal login lands in the intended tenant and application Wrong credentials stay on provider; denied membership leads to account help with identity switching Recovery deployed previously; actual fresh-user acceptance waiting on OTP
U03 — Accept an invitation Confirm intended tenant/role, accept once, then see next setup step Expired/used/wrong-person invitation explains next step; admin reissues without duplicates Service/browser routes exist; live delivery and full browser acceptance pending
U04 — Set or recover my password Use actual login name, complete single-use setup, return to sign-in Missing mail or expired link offers admin-assisted new setup link Password setup reported successful; email delivery unresolved; display-name/login-name clarity needs work
U05 — Use password-only access before optional OTP enrollment Ordinary application permits login when provider confirms no activated factor Provider unavailable gives recovery, never silently bypasses enrolled OTP KEY-WP-0035 source tested; live credential/policy gate unresolved
U06 — Turn on authenticator codes voluntarily My account → Sign-in security → provider; confirm identity, scan QR, verify current code, see activation confirmed, test fresh login Bad code retries; cancellation does not report enabled; interruption can resume safely; support reachable without portal login Help and configurable provider handoff implemented; provider activation/cancel semantics and live enrollment unverified
U07 — Sign in with an enrolled authenticator Current code completes login; existing AAL1 session cannot skip OTP Invalid code explains retry; lost device has a recovery route Issuer policy tested; real-user enrolled/recovery acceptance pending
U08 — Replace or remove my authenticator Provider reauthenticates; replacement verified before old factor removed; status and recovery instructions clear Lost old factor triggers verified recovery, not a bypass link; policy-required MFA cannot be disabled Required provider journey; not verified/available from portal yet
U09 — See my tenants and usable applications Account page lists allowed tenants and launchable applications with the current context Empty membership explains request-access route; unavailable/stale access is labelled and refreshable Personal membership display exists; authoritative application catalogue/request-access journey pending USER-WP-0026-T03
U10 — Change tenant or account Explicit tenant switch confirms new authority; account switch ends relevant sessions and lets me choose identity Denied tenant leaves a clear recovery route; stale shared identity can be cleared Tenant reauthentication and shared sign-out implemented; real multi-identity acceptance pending
U11 — Sign out Confirmation states scope; portal session ends; correct signed-out controls appear CSRF rejection retains session; shared-provider failure explains remaining scope and retry Portal automated tests; prior shared logout browser checks; current real-user acceptance pending
U12 — Recover from denied access or service outage Plain explanation, reference for support, and account/help navigation No automatic login loop; no private claims/codes echoed; safe retry only HTML browser denial/recovery implemented; JSON API semantics retained
U13 — Update my profile and finish onboarding Saved values and required steps are confirmed; external steps reflect provider evidence Validation keeps safe input; provider-owned steps cannot be manually faked complete Existing routes; form-preservation and external completion UX acceptance pending

Tenant administrator perspective

ID / intent Success Failure and recovery Current support / acceptance
T01 — Enter the right tenant administration Header shows identity; managed tenant is explicit; only permitted admin navigation Non-admin/cross-tenant request denied with account recovery Existing authorization/navigation tests; broader browser matrix pending
T02 — Invite someone with the right role Review name, email, tenant and role; show invitation state and next action Duplicate, wrong address, expired invite: inspect, correct/reissue or expire without making a second account Invitation routes and checks exist; delivery/preview usability pending
T03 — Prepare an account that can actually log in Distinguish profile, directory login name, invitation, password setup, and tenant access; admin can give the correct login name Partial provisioning shows what exists and retry reconciles it; never show display name as login implicitly Create-login/setup-link routes exist; plain login-name presentation and lifecycle state view pending
T04 — Help someone who cannot sign in Identify affected tenant/account; distinguish password, OTP, membership, and outage; give safe recovery step No access to passwords, OTP seed or current codes; provider failure has support reference/escalation Password setup and help page exist; verified lost-factor recovery/provider status pending
T05 — Grant/change/revoke application access Review exact tenant/application/role; apply authorized change; confirm effective result Policy denial or stale version explains reason and refresh; no silent broad grant Service capabilities vary; consolidated browser application-access management pending
T06 — Suspend/reactivate/remove a tenant account Confirm target and scope; show resulting state and whether access propagation is pending Stale or failed operation leaves truthful state; retry after readback; shared identity in other tenants preserved Existing lifecycle routes; confirmation/propagation UX and cross-tenant browser drills pending
T07 — Track incomplete onboarding See invited, identity missing, password pending, OTP problem, and access denied as distinct actionable states Stale/unknown provider state is labelled; administrator gets the correct owner/action Headless diagnostics exist; consolidated browser status and retry workflow pending
T08 — Manage admin succession and audit Grant the next admin only with authority; preserve an accountable admin; review who changed what Prevent loss of last administrator or provide platform recovery; no self-escalation Required journey; last-admin guard and browser audit acceptance need review

Platform administrator perspective

ID / intent Success Failure and recovery Current support / acceptance
P01 — Administer platform without joining every tenant Platform console reachable with platform role; personal memberships remain truthful Opening a workload as platform admin can be denied; account console remains reachable Existing platform navigation/authority tests; full workload denial journey acceptance pending
P02 — Create tenant and first administrator Confirm tenant identifier/type/name and first admin; show tenant created versus admin onboarding pending Conflict/partial failure readback avoids duplicate tenant; resume only missing stages Existing platform creation/result routes; live end-to-end drill pending
P03 — Find and inspect a tenant Search exact identifier or disambiguate matching names; clearly state selected scope Unknown/ambiguous name presents choices without guessing authority Existing tests for unknown/ambiguous names and tenant selection
P04 — Recover a tenant administrator Verify request and affected scope; audited, bounded account/factor recovery returns control Insufficient proof denies; provider outage yields pending state and named owner Identity-recovery route exists; lost-factor recovery and audited browser acceptance pending
P05 — Operate sign-in, factor and notification services See degraded component and impacted journeys; renew scoped credentials; verify recovery Expired factor-read credential blocks assurance decision; missing mail uses explicit assisted setup; no hidden MFA bypass Factor-read custody, automatic renewal and mounted delivery verified (RPF-WP-0040); provider expiry/revocation drills and mail delivery remain open
P06 — Set authentication policy Distinguish optional-after-enrollment, mandatory, and application step-up; preview impact and rollback Unsupported/ambiguous policy rejected; avoid locking out unenrolled users or weakening privileged actions KeyCape optional policy source tested; scoped rollout and privileged-portal policy acceptance pending
P07 — Suspend/retire/reactivate tenant Confirm blast radius and resulting tenant lifecycle; applications reflect effective policy Stale version or partial propagation provides readback/retry; recovery retains audit Existing tenant lifecycle APIs; browser confirmation/propagation drill pending
P08 — Review audit and service recovery Follow correlation reference without exposing secrets; see actor, tenant, action and result; prove rollback Missing telemetry or unknown state visible; no success until authoritative readback Existing service events/references; unified browser audit/support workflow pending

OTP activation state contract

The provider owns credential material and proof of possession. The portal owns explanation, navigation, and handoff; it never collects OTP seeds or codes.

State What the user sees Allowed next step Required evidence
Unknown / unavailable “We cannot confirm your authenticator status”; setup unavailable when no verified handoff is configured Help; provider management only when operator-configured and verified Do not infer off from lookup failure or AAL1 session
Not enrolled Optional setup, plus continue without OTP where policy permits Start enrollment Authoritative factor absence and applicable client policy
Enrollment pending QR/code confirmation at provider; no success badge yet Confirm, retry, cancel or resume Pending token cannot accidentally lock normal login
Enabled Confirmation and recovery instructions Test fresh sign-in; later manage device Provider verifies possession and reports activated factor
Replacement pending Old factor remains usable until replacement confirmed Confirm replacement or cancel No gap allowing MFA bypass
Recovery required Clear lost-device recovery instructions Verified recovery with audit Provider proof/authorized recovery, never tenant membership alone

Deployment gate: verify the live provider's activation, cancellation, realm mapping, scoped factor-read credential and renewal contract before enabling optional policy or setting USER_ENGINE_MFA_MANAGEMENT_URL. Both successful and empty token queries must be tested against controlled accounts; self-service credentials are not an administrative lookup credential. The portal help page is reachable before login so OTP-required login does not hide recovery.

Executable implementation status

Implementation workplans: USER-WP-0028 (users), USER-WP-0029 (tenant admins), USER-WP-0030 (platform admins), USER-WP-0031 (automated suites), and NK-WP-0038 (scoped provider lifecycle). The original review column above records the starting gaps. For the current per-journey implementation state and executable tests, use tests/journey-coverage.json and make test-journeys; the report never equates provider-boundary tests with real OTP or mail acceptance.

Now implemented: actual login-name handoff, profile validation/retry, scoped provider lifecycle, role succession, cross-connection last-admin protection, confirmation/stale-state checks, first-admin bootstrap rollback/retry, invitation delivery readout, onboarding follow-up, tenant audit, and platform delivery retry.

Acceptance and remaining work

USER-WP-0027 tracks the matrix and role-based usability gaps. KEY-WP-0035 tracks OTP policy/provider rollout. USER-WP-0026 retains authoritative workload catalogue work. Do not close these based solely on this document or a unit-test pass.

Run every journey with an ordinary member, tenant admin, and platform operator as applicable, plus an anonymous/expired session. For each capture: initial state, visible controls, action, authoritative result, failure, recovery, and cross-tenant isolation. Use synthetic identities in stored evidence. Include keyboard-only and narrow-screen checks; never store passwords, QR images or OTP values in evidence.

Automated portal coverage: test_account_clarity.py, test_account_recovery.py, test_portal_navigation.py and existing test_web.py authorization/lifecycle tests. Automated issuer coverage: KEY-WP-0035 optional MFA tests. Actual provider OTP, notification delivery and multi-user workload acceptance remain separate evidence.