Revoke the Artifact Registry owner role when a user leaves or is removed from an organization
Summary
!250806 (merged) syncs the Artifact Registry owner role when someone is promoted or demoted. It does not cover a user being removed from an organization, or leaving one. This issue is that remaining case.
It was deliberately left out of !250806 (merged) rather than missed, because it needs something that does not exist yet. Two parts.
There is no hook on the removal path. !250806 (merged) enqueues the owner role sync from EE::Organizations::OrganizationUsers::UpdateService, which only handles access level changes. Removal goes through Organizations::OrganizationUsers::DestroyService, which has no hook. So the organization_admin tuple is left behind. Artifact Registry validates tokens locally and never calls back to Rails, so the tuple's absence is the only thing that cuts access.
There is no valid actor for a self removal. !250819 (merged) adds a Leave organization action, so a user removes themselves. The only person involved is the one leaving, and IAM's AuthorizeWrite refuses any non-owner writing the organization's own resource. The acting user approach !250806 (merged) settled on has nobody to act as.
Falling back to another owner was considered and rejected, because the record would then name an uninvolved person as having removed you when in fact you left. See !250806#note_3769905713.
Also unsupported today
!250806 (merged) intentionally does not handle the acting user losing ownership between enqueue and execution, since the job is async. The revoke is skipped and logged. That shares the root cause, because there is no way to authorize the write except as a user who is currently an owner.
Worth noting the skip is quiet. DataAccessClient#request_error reports to error tracking, but only when a gRPC call fails, and a skipped job never reaches IAM. A skipped revoke means retained access, so it should be distinguishable from benign skips like a missing organization.
What this needs
A hook on the removal path, and a way to authorize the write when the person losing access is the only one involved.
For the second part the options discussed so far are
- a self deletion rule in the IAM Data Access service, so a subject can delete a relationship where they are the subject. Started in iam!594 and set aside, because that authorization logic is meant to move to GLAZ and the Data Access service does not embed GLAZ yet
- the IAM outbox approach, which does not act as any particular user and would remove the need to borrow an identity at all
Why the ordering matters
Neither !250806 (merged) nor !250819 (merged) has merged, so nothing is broken today. Once both are in, a user who leaves an organization keeps their Artifact Registry access and nothing records it, because Artifact Registry validates tokens locally and only the tuple's absence cuts access. So this wants to land close behind them rather than drift.
How this differs from #610042
#610042 is about the user going away. Account deletion, blocking, banning. Its proposal is a sweep that deletes every tuple for a subject, plus their identity and principal rows.
This issue is about the user staying and leaving one organization. They keep their account and any roles they hold elsewhere, so the operation is a scoped delete of that organization's tuples rather than a sweep. Different trigger, different service, and a different authorization problem, since a self removal has no valid actor.
#610042's case 3 mentions organization member removal, but at the time it noted that removal "does not exist in Rails yet". It does now, through Organizations::OrganizationUsers::DestroyService, and !250819 (merged) makes it self service. Its caveat about the case collapsing into blocking does not apply either, because DestroyService refuses removal from the home organization and customers work in promoted ones, which is exactly the live case.
Links
- !250806 (merged) which covers promote and demote, and where this case was deferred
- !250819 (merged) the Leave organization action
- #610042 user offboarding does not revoke Artifact Registry role assignments
- #626779 (closed) the revoke assignee check, which would also block a departed member
- artifact-registry#977 the home organization coupling this came out of