[hardening] Limit privileged workflow_run wakes by conclusion and branch
Summary
The example DeployBot workflow runs a privileged DeployBot job on every completed workflow_run event for the configured CI workflow name. GitHub documents that workflow_run fires regardless of the upstream workflow's conclusion, supports branch filters, and gives the downstream workflow access to secrets and write tokens even if the upstream workflow was unprivileged.
DeployBot's example should demonstrate the narrow privileged trigger pattern it expects users to copy.
Evidence
Impact
Users copying the example can run a write-token DeployBot job for failed, cancelled, or irrelevant upstream CI runs. DeployBot's internal checks reduce the chance of an unsafe merge, but the workflow still expands the privileged execution surface and creates unnecessary queue wakeups.
Because workflow_run is specifically a privilege-boundary event in GitHub Actions, examples should be conservative by default.
Proposed fix
- Add a
branches filter under the workflow_run trigger for the intended base/default branch where possible.
- Add a workflow_run guard to the job
if, for example requiring:
github.event.workflow_run.conclusion == 'success'
github.event.workflow_run.head_branch == github.event.repository.default_branch when the DeployBot handoff expects default-branch CI.
- Document how to adapt the branch guard if a repository intentionally uses workflow_run events from a protected release branch.
- Add a workflow syntax/test fixture if the project already validates example workflows.
Verification
- Review
examples/github-workflow.yml against GitHub's workflow_run docs.
python3 -m pytest -q
[hardening] Limit privileged workflow_run wakes by conclusion and branch
Summary
The example DeployBot workflow runs a privileged DeployBot job on every completed
workflow_runevent for the configured CI workflow name. GitHub documents thatworkflow_runfires regardless of the upstream workflow's conclusion, supports branch filters, and gives the downstream workflow access to secrets and write tokens even if the upstream workflow was unprivileged.DeployBot's example should demonstrate the narrow privileged trigger pattern it expects users to copy.
Evidence
examples/github-workflow.ymlconfiguresworkflow_runforworkflows: [CI]andtypes: [completed]in lines 8-11.ifblock filterspull_request_targetandcheck_suite, but has noworkflow_runbranch or conclusion guard inexamples/github-workflow.ymllines 29-51.examples/github-workflow.ymllines 16-21.workflow_runworkflow can access secrets and write tokens even if the previous workflow was not privileged in https://github.com/github/docs/blob/main/content/actions/reference/workflows-and-actions/events-that-trigger-workflows.md.workflow_runtriggers regardless of the previous workflow's conclusion and recommends usinggithub.event.workflow_run.conclusionfor conditional behavior in https://github.com/github/docs/blob/main/content/actions/reference/workflows-and-actions/events-that-trigger-workflows.md.workflow_runsupportsbranches/branches-ignorefilters in https://github.com/github/docs/blob/main/content/actions/reference/workflows-and-actions/events-that-trigger-workflows.md.Impact
Users copying the example can run a write-token DeployBot job for failed, cancelled, or irrelevant upstream CI runs. DeployBot's internal checks reduce the chance of an unsafe merge, but the workflow still expands the privileged execution surface and creates unnecessary queue wakeups.
Because
workflow_runis specifically a privilege-boundary event in GitHub Actions, examples should be conservative by default.Proposed fix
branchesfilter under theworkflow_runtrigger for the intended base/default branch where possible.if, for example requiring:github.event.workflow_run.conclusion == 'success'github.event.workflow_run.head_branch == github.event.repository.default_branchwhen the DeployBot handoff expects default-branch CI.Verification
examples/github-workflow.ymlagainst GitHub'sworkflow_rundocs.python3 -m pytest -q