MGS3027: queue run untrusted
magus queue apply was pointed at a run (run:<owner>/<name>/runs/<id>) and
read what started it before downloading anything. The run was not the
--workflow definition started by a push or a dispatch on --base of the
repository itself, so apply read nothing it uploaded.
[MGS3027] run acme/widgets/runs/7 is not .github/workflows/queue.yaml run by
acme/widgets's own main: "pull_request" started it, and that event runs a
definition a change supplied; apply reads nothing it uploaded
Why
Apply holds the write credential and merges what validation's artifacts say is green. Its trust in those artifacts rests on who wrote them: the plan and the verdicts must come from the base branch's own copy of the queue workflow.
A pull request event runs the pull request's own copy of the workflow file,
and a fork's run reaches this repository's workflow_run followers too. On
GitHub, workflow_run matches workflows by name, so any file named like the
queue's triggers it. Such a run can upload a mergequeue-plan and
mergequeue-verdict-<id> artifacts of its own choosing. Candidates are built
with a fixed identity and date, so a forged verdict can name the very commit
apply rebuilds, and apply would post success on a change nobody validated.
The run is refused when any of these holds:
- the event that started it runs a definition a change supplied (on GitHub,
anything but
pushandworkflow_dispatch); - it ran a commit of another repository than its own (a fork);
- it ran on another branch than
--base; - it ran another definition than
--workflow.
Resolution
Point apply at a run of the base's own queue workflow. In this repository's
setup, queue-apply.yaml follows only such a run, and answers a pull
request's run by dispatching queue.yaml on main instead. If a run you expected
to be followed was refused, check the --base and --workflow the workflow
passes, and that the run was started by a push to the base or a dispatch on it.
See the merge queue's trust model.