Enable bounded browser account administration for Phase 8D.7

Allow other-account add/password and forced delete/role commands through
shared dispatcher and handler policy. Keep self-target,
generated-secret,
key, bootstrap, and recovery workflows blocked.

Revalidate currentness after password prompts and before database API
admission. Document that admitted mutations may finish after disconnect,
while subsequent stale operations must reject.

Add policy, transaction-failure, cleanup, and targeted-revocation
regressions. Record completed review, passing host tests and firmware
build, with target validation and M2 acceptance still pending.
This commit is contained in:
2026-09-07 10:03:45 +02:00
parent 326119812f
commit fe1e2d98b4
11 changed files with 533 additions and 13 deletions
+30 -1
View File
@@ -1,6 +1,35 @@
# Phase 8D.7 — Web-shell lifecycle parity and M2 acceptance
## Current status — second bounded certificate slice
## Current status: third bounded account slice
**Account slice reviewed / host-tested / build-verified (2026-09-07); no actionable findings remain. Target validation and 8D.7/M2 acceptance remain pending.** This supersedes the account restrictions and next-slice statements in the historical sections below, not their recorded validation limits.
Browser admins may now operate on other accounts with exact parsed `user add <name> user|admin`, `user password <name>`, `user delete <name> --force`, and `user role <name> user|admin --force`. Add/password use hidden password and confirmation prompts. Dispatcher policy and the canonical handler both enforce this bounded allowlist. Self-target mutations (even no-op role changes), generated-password output, key workflows, bootstrap and recovery remain blocked for browsers. Existing inspection is unchanged. Database final-admin and migrated-account protections remain authoritative.
### Operation-admission currentness
The guarantee is **operation-admission currentness**, not currentness at commit. Account, originating owner/session and console token are checked after password prompts and before admitting the database API operation; delete/role also revalidate before API admission. Queued or subsequent stale operations must reject. Disconnect, logout, expiry or revocation during password derivation does not cancel or roll back an already admitted operation. Such an operation may persist and request target-only web/SSH revocation after the initiating browser is gone. Notification failure does not undo a committed mutation, and completion output is not a receipt guarantee.
After a disconnect with an uncertain result, reconnect using a current administrator and inspect `user list` / `user show <name>` before retrying. Password values cannot be inspected; verify the intended login outcome or deliberately reset the target password rather than assuming cancellation. Do not expose credentials in status or logs.
### Review and verification
Independent production and regression reviews found no actionable defects. The earlier proposed precommit-currentness finding was withdrawn as inconsistent with the existing executing-handler contract. No production changes were needed during this review continuation; inherited changes were preserved.
Passed in this continuation: `python3 tests/admin_console_boundary/accounts.py`, `python3 tests/admin_console_boundary/run.py`, `python3 tests/admin_ssh_policy/run.py` (review agent); `python3 tests/admin_console_boundary/lifecycle.py`, `python3 tests/web_admin_transport/run.py --tickets` (25 transport / 12 ticket groups), and `python3 tests/web_session_store/run.py --serial` (parent). Account regressions cover admitted derivation invalidation, successful commits and target-only notification arguments, NVS open/write/commit failures, candidate cleanup, and rejection of the next stale operation.
These are deterministic handler/database and separate console/transport boundary tests, not real HTTPD disconnect/expiry, scheduler or end-to-end socket tests. Account tests double currentness, prompts, crypto, NVS and notification APIs; they do not independently prove live connection isolation. No device or sanitizer validation was performed.
`pio run` passed (incremental, 3.35 s): **95,580 B linked RAM / 1,648,577 B flash**, **0 / +516 B** versus the recorded certificate slice, **0 / +2,088 B** versus 8D.6, **+1,048 / +48,604 B** versus 8D.0. No new task, queue depth, route, socket capacity, assets or stack size; runtime reserves and stack margins remain unmeasured.
### Pending account target checks
1. Exercise each enabled other-account command, hidden confirmation/mismatch/cancel, and self/generated/key/bootstrap/recovery rejection. Verify final-admin protections and unchanged UART0/admin SSH behavior.
2. Confirm successful target mutations revoke only that account's web/SSH sessions, retaining unrelated browser serial/admin, USB and SSH traffic. Check stale queued commands and prompts after logout/expiry/revocation and slot reuse.
3. Where safely injectable, disconnect during admitted derivation and inspect the resulting account state after reconnect; do not expect cancellation. Check persistence failure and retry recovery without logging secrets. Unavailable timing/failure injection remains unexecuted.
4. Run the lifecycle/full-mix/soak/resource checklist below as well. Remaining self/generated/key/legacy-credential and other owner-specific parity work stays blocked until separately implemented; this review does not close M2 or start another slice.
## Second bounded certificate slice history
**Second slice implemented / host-tested / build-verified; independent reviewer reports no actionable findings. No hardware validation or 8D.7/M2 acceptance.** The user explicitly authorized continuing to stack the next bounded slice; this is a continuation decision, not target sign-off. Next comes credential/account handling, then other owner-specific slices. Prior 8D.6 sign-off stands; numeric reserves remain open.