coulomb-social/docs/release/native-recovery-browser-review-2026-10-31.md
tegwick 7b4b75089c
Some checks failed
Use-case regression gate / usecase-regressions (push) Has been cancelled
Verify native reset SMTP issuer and app recovery through Chromium
Assistant: codex
Assistant-Model: gpt-6.1-sol
Assistant-Session: 01a18e2d-f513-7742-b8e7-12af0b744ff3
2026-10-31 00:15:24 +01:00

7.1 KiB

Isolated native account-recovery browser gate

WP-0015-T04 now has an exact native UC-009 browser node: scripts/native_recovery/test_journey.py::test_native_reset_directory_smtp_issuer_and_app. It passes with no skips. It supplements the existing personal acceptance and loopback-double regression; it does not promote UC-009 to an established automated journey or supply a productive verdict. No production configuration, account, permission, sender or deployment was changed.

Verified path

Chromium uses the actual Authelia 4.39.28 reset forms. Authelia looks up the synthetic user in actual LLDAP 0.6.2 and sends its native SMTP messages to a bounded local sink. The browser reads the synthetic mailbox, follows the native link and submits the replacement password. It verifies consumed-link replay and an expired native handle; the expiry fixture uses a one-second native lifespan and waits three seconds, without rewriting a token or database record.

The read-only bind reproduces the expected failed password change. The positive fixture uses a password-manager bind; independent native directory login confirms that the old password no longer works and the replacement does. Both service identities are refused directory group creation. The separate native API proof also retains service-login and unverified-reset denial coverage.

The browser then starts sign-in from the real app, observes refusal of the old password and signs in with the replacement through native Authelia and KeyCape. Actual PKCE/code exchange, issuer JWT/JWKS verification and the app callback run. The app's real HTTP identity bridge calls the actual user-engine portal and verified-claims normalizer. Session details show the expected issuer, canonical LDAP subject, tenant and HTTP identity-link provenance. One owner user and one app Member exist, and the app-local password is unusable. The consumed app callback refuses replay.

Unknown-client and wrong-redirect requests include valid unrelated PKCE preconditions, then verify the native issuer's specific refusal. For the tenant test, Alice has an explicit directory tenant group. A separately registered client declares a conflicting tenant: a real authorization code reaches a synthetic callback receiver, and the native token endpoint refuses issuance with 403 and the tenant-binding reason. That receiver is a fixture, not the app's callback. No token is forged and no issuer response is mocked.

A default tenant alone is not an explicit directory assignment. The issuer's existing contract lets a trusted static registration supply a tenant for an unplaced user. This fixture establishes the directory assignment before testing a conflict; it does not change that contract or mislabel legitimate registration- supplied tenancy as an issuer defect.

Boundaries and artifacts

Component Execution boundary
Authelia and LLDAP Exact retained native images, fresh synthetic stores and generated secrets
SMTP Actual native SMTP transport to a fixture accepting only the reserved sender/recipient; no provider
Browser Locked Playwright 1.62.1 and matching retained Chromium revision1234/version151.0.7922.34, copied as public runtime assets
KeyCape Actual static executable extracted from the pinned deployment-owner image and hashed; a separate read-only directory bind
user-engine Actual packaged HTTP portal and claims adapter; explicit in-memory storage and standalone authorization double
App Current tracked source overlaid on the retained Python/dependency image; fresh SQLite/content, actual HTTP identity bridge, standalone app authorization

Native identity, directory and SMTP are no longer protocol doubles in this node. The owner storage/PDP fixtures do not certify production authorization or PostgreSQL behavior. Ordinary AAL1 sign-in is tested using the fixture client's explicit policy; no OTP/MFA ceremony, global token revocation, productive sender, provider inbox receipt or full production TLS acceptance is claimed.

All running peers share a unique network-none container's loopback namespace. There are no published ports, external routes, network bridges or host mounts. Backend flags are inspected before fixture import: nonroot UID, read-only root, dropped capabilities, no new privileges and bounded resources. Public browser assets and the reviewed issuer executable use an executable private tmpfs; credentials, stores and browser profiles are disposable. The browser allows only the exact fixture origins and also observes requests across redirects; no outside HTTP(S) request was observed. Native TLS is checked against the generated fixture certificate by a separate probe. Chromium ignores trust errors for this private certificate within the bounded context; that is not a production trust-store test.

Cleanup verifies that every backend, browser, probe and temporary image-extraction container is absent. No persistent volume or production pair is imported. Usable links, passwords, proxy secrets, tokens and message bodies are absent from the public receipt. Failed attempts retain only private redacted diagnostics.

Run explicitly with the retained images and locked local browser prerequisites:

make check-native-recovery \
  NATIVE_BROWSER_RECEIPT=/tmp/fresh-native-recovery.json

No image or browser download is performed. The runner strips inherited credentials and configuration, disables pytest plugin autoload, requires the exact single unskipped node, and refuses an existing receipt or manifest. Keep the JSON with its adjacent .sources.txt; it binds executed fixture sources, runtime asset hashes, image identities, app-source aggregate hash and native JUnit result. The candidate registry names this explicit native gate. make check continues to run the established app/browser gate without requiring these owner images.

The native gate passes one exact node with zero skips. Separate synthetic JUnit envelope checks verify refusal of a wrong, skipped, failed or extra node and confirm the child environment is restricted; these are verifier checks, not additional native executions. The ordinary make check gate passes396cases, zero failures/errors/skips, including its required browser journeys. Source manifest hashes match the executed files, and whitespace/Ruff checks pass.

Evidence: native-recovery-browser-2026-10-31.{json,sources.txt}. The native node passes all three reset scenarios and the issuer/app journey. The ordinary full regression result is retained in the same evidence JSON.

Remaining acceptance

The positive directory permission is synthetic. The existing NetKingdom NK-WP-0054-T05 reset-authority review remains required; the source read-only bind does not acquire password-manager rights because this test passed. No conclusion about currently installed directory privileges is inferred.

WP-0015-T04 still owns productive UC-010/011 verdicts, runtime admission and the remaining owner returns. UC-009's prior personal acceptance is preserved; its automated establishment remains separate. WP-0015-T02 sender/reply/bounce ownership and the other three workplans' release, recovery, source reconciliation and productive acceptance gates remain open.