Refuse single sign-on into an account the roster forgot - #13
Merged
Conversation
An identity provider records the account it authenticated by user id, so a removed member's next single sign-on login arrives at the parked account. With the roster row gone, that login was read as staff and admitted outside the allowlist: the removal flipped the member from governed to exempt, on an account no roster lists and no endpoint reaches, and the provider then wrote the stripped address back onto it, confirmed. The reader group is the mark of an account the allowlist created: provisioning adds it before the roster row, and a removal leaves it in place. An account carrying the mark without a roster row is therefore one the roster forgot, and is refused rather than exempted. The same refusal closes the single sign-on route into an account left behind by a failed provisioning. The user-list handler's check of the same mark is renamed to say what it reads, since holding the reader group no longer implies being a member. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Forgetting a member never ran against a roster holding anyone else, so a delete that forgot the whole roster survived the suite. The CSRF gate was never exercised over DELETE, the refused-rename answer never reached the endpoint's error mapping in a test, and the rename log's performer and the failure log's address hashing were unasserted. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The REST framework answers the rethrown failure with an error response, after which the request's transaction round commits as usual: nothing rolls the atomic section back but this cancel. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #13 +/- ##
============================================
+ Coverage 85.83% 86.27% +0.44%
- Complexity 519 523 +4
============================================
Files 61 61
Lines 1793 1807 +14
============================================
+ Hits 1539 1559 +20
+ Misses 254 248 -6 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
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.
Follows-up to #12
A post-merge review of #12 found one blocking defect, fixed here, along with test hardening and two
corrections to that PR's description.
The defect
An identity provider records the account it authenticated by user id, and the rename does not touch
that record. A removed member's next single sign-on login therefore arrived at the parked account,
which — having no roster row — was read as staff and admitted outside the allowlist: removal flipped
the member from governed by the allowlist to exempt from it, and deleting their allowlist entry
changed nothing, since the exempt path never consults it. PluggableAuth then wrote the provider's
address back onto the parked account, confirmed, undoing the removal's stripping of it and
re-opening the password-reset route into an account that still carries the reader group. The account
shows in no roster, and deactivation and removal both answer
not_a_memberfor it — the stateissue #3 exists to eliminate, recreated for single sign-on members.
The reader group is the mark of an account the allowlist created: provisioning adds it before the
roster row, and removal leaves it in place. An account carrying the mark without a roster row is
therefore one the roster forgot rather than staff, and is now refused. The same refusal closes the
single sign-on route into an account left behind by a failed provisioning, the third defect of
issue #3. A removed member's way back in is the code route, which reaches a fresh account; their
single sign-on logins stay refused, since the provider keeps pointing at the parked account. The
README scopes both claims now, and the user-list handler's check of the same mark is renamed to say
what it reads, since holding the reader group no longer implies being a member.
Test hardening
whole roster survived the suite.
endpoint's error mapping in a test.
Corrections to #12's description
block" is wrong: the extension grantsmemberaccess-manageto bureaucrats, and default bureaucrats holduserrights,noratelimitand
renameuser, notblock. A bureaucrat who is no sysop can therefore remove a deactivated,still-admitted member, undoing a deactivation they could neither place nor lift — though such an
account could also grant itself sysop. Whether removal should require the
blockright remainsopen, now on corrected facts.
route only; single sign-on stays refused, as above.
Considered, omitted
even where the allowlist does not apply to single sign-on — but it places a block on behalf of a
performer the endpoint deliberately does not require the
blockright of, so it belongs with thatopen decision rather than in this fix.
on the parked account, and it is the one mark that tells a forgotten account from staff. For the
same reason, taking the group off a parked account by hand turns it into an exempt staff account.
already destroys the reader revocations wholesale, and none of our deployments configures one.