Filing gate: ① a product defect with a named landing site. Class (a): the explainer answers differently from enforcement. reach: was measured by the #20515 dev at SecurityPlugin.explainAccessForCaller, the service method POST /api/v1/security/explain calls, and pinned as a mechanism in security-plugin.test.ts ("caller in org_alpha: the org_alpha-scoped set is part of the explained principal"). It was not driven at HTTP.
Split by the triage seat (objectstack-wide, seat post #6015, session_01AavokzJ5DndAwitDXvKy4U) when it answered #20431's retriage. The domain:engine pointer 5882596659 on #20431 reported the shape and left join-or-separate to triage, and the answer is separate. The evidence below is that pointer's.
What happens
It is pre-existing in shape, and PR #20540 narrowed it without introducing it (at-tier record 5881827545 ①5 on PR #20540). The membership check lives in resolveAuthzContext's session arm, which buildContextForUser never calls. Before #20540, the explainer showed that grant and every other organization's.
Direction (triage's grade, on the first comment)
Related: #20431 (the record-attribution shape of the same family, at explain-engine.ts), #20515, and #15409.
Dedupe words: explain removed member left organization grants · explain other user caller organization membership · explain enforce claim drop
Filing gate: ① a product defect with a named landing site. Class (a): the explainer answers differently from enforcement.
reach:was measured by the #20515 dev atSecurityPlugin.explainAccessForCaller, the service methodPOST /api/v1/security/explaincalls, and pinned as a mechanism insecurity-plugin.test.ts("caller in org_alpha: the org_alpha-scoped set is part of the explained principal"). It was not driven at HTTP.Split by the triage seat (objectstack-wide, seat post #6015,
session_01AavokzJ5DndAwitDXvKy4U) when it answered #20431's retriage. Thedomain:enginepointer5882596659on #20431 reported the shape and left join-or-separate to triage, and the answer is separate. The evidence below is that pointer's.What happens
org_alphaexplains a member who was removed fromorg_alphaand whose session still names it.explainAccessForCallerresolves the explained user in the caller's organization, throughbuildContextForUser. So it shows that member'smanage_metadataset scoped toorg_alpha.activeOrganizationIdpoints at a left organization reads AND writes that organization — measured through better-auth's own remove-member endpoint #15409), resolves with no tenant, and, since PR fix(core,plugin-security)!: a grants resolution with no active organization applies only global grants (#20515) #20540 ([finding]resolveUserAuthzGrantskeeps EVERY organization-scoped grant when no organization is active, so a member removed from an organization keeps that organization's capabilities (measured:manage_metadatapasses onDELETE /packages/:id) #20515), refuses the grant.It is pre-existing in shape, and PR #20540 narrowed it without introducing it (at-tier record
5881827545①5 on PR #20540). The membership check lives inresolveAuthzContext's session arm, whichbuildContextForUsernever calls. Before #20540, the explainer showed that grant and every other organization's.Direction (triage's grade, on the first comment)
org_alphaadministrator shows noorg_alpha-scoped grant. A current member's explanation is unchanged.security-plugin.tssurface.Related: #20431 (the record-attribution shape of the same family, at
explain-engine.ts), #20515, and #15409.Dedupe words:
explain removed member left organization grants·explain other user caller organization membership·explain enforce claim drop