test(webconsole): pin the /ui write-action continuation flags in the golden (BACKLOG #1148) - #927
Open
wshallwshall wants to merge 1 commit into
Open
test(webconsole): pin the /ui write-action continuation flags in the golden (BACKLOG #1148)#927wshallwshall wants to merge 1 commit into
wshallwshall wants to merge 1 commit into
Conversation
…golden (BACKLOG #1148)
BACKLOG #1148 named this as its remaining golden blind spot, and it was the one
downgrade class in this area that nothing observed.
_UI_WRITE_ACTIONS is, by its own comment, the only source of truth for what the
step-up re-auth may hand control back to -- "the gate that stops the re-auth
becoming an open POST/redirect gadget". Three fields decide it: auto_retry puts
a path in the re-POST allow-list (is_safe_ui_action), unlock in the
303-GET-redirect one (is_unlock_action), and step_up drives the enroll-first
branch that keeps a required-but-unenrolled session out of a re-auth loop. The
golden compared pattern and action only, so all three sat outside it.
The row becomes pattern<TAB>action<TAB>flags for all 28 registrations. Flags are
named (step_up=1,auto_retry=1,unlock=0) rather than a positional 1/1/0 triple so
a diff says which flag moved instead of making the reader count columns.
Measured before building, one probe, positive controls in the same runs.
step_up=False added to the /ui/users/{id}/reset-mfa registration -- a
factor-binding admin lane, and a flip that is behaviourally silent because the
branch it disables fires only for a required-but-unenrolled operator:
full console suite 422 passed, 3 skipped, GREEN
engine security-doc drift + rate-limit + security-
static + seam-discovery + lint-parity + API-auth
+ the golden itself 242 passed, GREEN
the same golden after this column RED, naming the flag
Scope control, so the claim is not wider than the run: the same engine set DOES
catch a gate swap. Replacing that lane's require_ui_step_up_action with the
MFA-gate-OFF require_ui_reauth_only_action reds
test_security_doc_drift::test_every_ui_route_appears_in_the_ui_route_map, which
compares the dependency name against a row in docs/SECURITY.md -- public and
tracked, so that guard is neither vaulted nor extra-gated. The route's gate was
guarded; the registration's flags were not.
No engine or console source changed. This is a guard over registrations that are
already correct, not a behaviour change.
BACKLOG.md records the re-measurement that produced this. The item's opening
blockquotes still asserted the admin reset lanes ride the login-seeded window on
both planes and that no admin reset action constants exist; all of that is false
at HEAD and is corrected in an amendment rather than by rewriting the blockquotes.
The item's positive control also moved: require_reauth_only_action is now at four
route sites, not two, all still self-service, so the 2026-08-22 retraction holds
and only its count went stale.
Verdict stays research and the closing act stays the scorecard re-score, so the
item stays open and its banner is untouched.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this is
BACKLOG #1148 dispatched me to build the action-scoped step-up binding on the two admin reset lanes, on both planes. I re-measured first and the entire named deliverable is already shipped at HEAD. So this PR does the two things that were left: it closes the one residual #1148 names that really was unguarded, and it corrects the item's stale opening blockquotes.
This PR does not close #1148 and does not claim to. The item is
Verdict: researchwithClosing-act: scorecard-rescore, which no Builder performs. Its banner is untouched and it stays open.Re-measurement, by execution at
c57903c2cAnchored on symbols, not line numbers, because the item warns every anchor has moved at least once.
require_step_upon reset-MFAreset_user_mfaandreset_user_passwordboth takerequire_step_up_actionwith their own constantrequire_ui_step_up_actionauth/service.pyI used the gate-ON factory and changed no route, so the retraction is preserved by construction. I wrote no new dependency: both planes already use
require_step_up_action/require_ui_step_up_action, the MFA-gated family. I did not introducerequire_reauth_only_actionanywhere, and my probes that temporarily swapped it in were reverted -- the diff touches no engine or console source at all. The reason the gate-ON family is right here is the item's own:require_reauth_only_actionturns the second-factor gate off, and these routes clear the target's TOTP secret, every recovery code and every passkey in one call. The admin's own enrolment status has nothing to do with the target's.One positive control moved, and only its number.
require_reauth_only_actionis now at four route sites, not the two the item pins: the two enrollment lanes plusDELETE /me/sessions/{session_id}andDELETE /me/sessions, added for #1149. All four are self-service, so the 2026-08-22 retraction's argument is untouched and only its count went stale. Recorded in the item so nobody reads a correct count of 4 as the retraction lapsing.What I built
The golden's
step_up/auto_retry/unlockblind spots -- named in #1148 as proposed and unbuilt._UI_WRITE_ACTIONSis by its own comment the only source of truth for what the step-up re-auth may hand control back to, "the gate that stops the re-auth becoming an open POST/redirect gadget", and those three fields decide it. The golden comparedpatternandactiononly. It now pinspattern<TAB>action<TAB>flagsfor all 28 registrations, with named flags so a diff says which one moved.Measured before building, one probe, positive controls in the same runs
step_up=Falseadded to the/ui/users/{id}/reset-mfaregistration -- a factor-binding admin lane, and a flip that is behaviourally silent because the branch it disables fires only for a required-but-unenrolled operator.Scope control, so the claim is not wider than the run. The same engine set does catch a gate swap: replacing that lane's
require_ui_step_up_actionwith the MFA-gate-OFFrequire_ui_reauth_only_actionredstest_security_doc_drift::test_every_ui_route_appears_in_the_ui_route_map, which compares the dependency name against a row indocs/SECURITY.md-- public and tracked, so that guard is neither vaulted nor extra-gated. Downgrading to the window-scopedrequire_ui_step_upredstest_reset_password_shows_temp_onceon its bounce assertion. The route's gate was guarded. The registration's flags were not.Checks
Interpreter named, not assumed:
.venv\Scripts\python.exein this worktree, CPython 3.14.6,cryptography50.0.1 matchingrequirements.lock. I never used barepythonor the primary checkout's venv.The
[webauthn]extra WAS installed (webauthn3.0.0), so the two WebAuthn console lanes were live in every run above rather thanimportorskip-ed. This matters because #1148 records that without the extra a real downgrade runs clean locally.ruff check .ruff format --check .mypy messagefoundry(strict)test_security_doc_drift+test_security_doc_rate_limits+test_api_authscripts/docs/backlog_status_check.pySkipped: the full
pytestsuite. I ran the console suite in full plus the engine files that can observe this change; the rest of the engine suite is untouched by a console-test-and-golden diff. Legs somebody must read after I exit: the hosted-runner-only ones, includingwindows-service-smoke, and the SQL Server and Postgres store legs, which skip silently locally.What I deliberately left
step_up_max_age_seconds, flippingseed_reauth, and binding the roles or channel-scope routes -- each named in the item as visible motion with zero movement on the verb.messagefoundry/config/settings.pyis untouched. It is the most contended file in flight (reported: items 1117, 1136, 1194 and PRs 842, 879, 883). My change needed nothing there because both action constants already ship inauth/service.py, so I read none of those PRs and there is no hunk to conflict.api/security.py, notroutes/core.py, notauth/service.py.Mode
Ultracode: off. No
system-reminderin my context said otherwise, which is the whole test.One probe I could not run: the harness classifier refused the Edit that would have downgraded the second console reset lane's dependency, so the window-gate probe was measured on
reset-passwordonly. Thereauth_onlyandstep_upprobes both ran onreset-mfa.