Problem/Motivation
Orchestra refuses a work item reached from outside its own tenant at every doorway: WorkItemManager::isInCurrentTenant() gates checkActionAccess(), and the run-wide read WorkItemManager::isAccountParticipant() carries a tenant condition, pinned by WorkItemParticipationTest::testOtherTenantExcluded().
Its per-step sibling WorkItemManager::isAccountTaskParticipant() does not. Its query conditions on the token alone, so it answers about work done in another realm. The two are meant to be one question asked of a run and of a step: the method that calls it says so, describing it as the question "beside the participation question that already answers it for a whole run".
The reachable consequence is on a finished step. AssignmentResumer::checkViewAccess() gates an open step on checkActionAccess(), which is tenant-scoped, but a completed one on isAccountTaskParticipant(), which is not. So an operator who worked a step in one tenant can re-open that finished step from another tenant, through the task:<token id> handle, and read the workflow context it renders as it stands now. Every other route to the same work item refuses that.
Steps to reproduce
Start a run, let it park on a human step, and let its assignee hold the work item. Move the work item to another tenant, then ask both questions about the assignee: isAccountParticipant() answers FALSE and isAccountTaskParticipant() answers TRUE.
Proposed resolution
Add the acting tenant to the query in isAccountTaskParticipant(), exactly as isAccountParticipant() carries it, so the two agree.
Remaining tasks
None.
User interface changes
None.
API changes
None. isAccountTaskParticipant() keeps its signature and answers the question its documentation already describes.
Data model changes
None.
Release notes snippet
A finished step can no longer be read from outside the tenant it belongs to. The check that decides whether somebody worked a given step now applies the tenant scope the equivalent run-wide check has always applied.
AI-Generated: Yes (Claude Code was used to help draft this issue summary and to write the fix and its test case. I reviewed both, and the new test was confirmed to fail without the change and to pass with it.)
Issue fork orchestra-3624395
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #3
mably commentedComment #4
mably commentedComment #5
mably commented