The four repository_dispatch consumers of the release flow (openemr/openemr-devops, openemr/website-openemr, openemr/demo_farm_openemr, and the conductor's own permissions-check probe path in openemr/openemr) all accept the dispatch envelope at face value once the job-level if: confirms the workflow is running on an openemr/* repo.
The repository_dispatch API itself requires write/repo permission on the target repo, and the openemr-release-app's installation list is explicitly scoped, so the practical risk is low. But the dispatch envelope already carries a documented repo field (per dispatch.schema.json's common envelope), and verifying client_payload.repo == 'openemr/openemr' would be a cheap defense-in-depth check that catches a misconfigured App, a stolen App credential firing into the wrong repo, or a future App scope expansion.
Proposal
Add a uniform payload-origin verification step at the top of each consumer workflow's job:
- Reject if
client_payload.repo is not openemr/openemr.
- Reject if
client_payload.event doesn't match the workflow's expected event type.
- Continue to allow
workflow_dispatch to bypass (so manual recovery still works).
Apply across:
openemr/openemr-devops: release-rotation.yml, ship-release.yml, build-release.yml, build-patch.yml, release-permissions-check.yml
openemr/website-openemr: release-docs.yml, release-permissions-check.yml
openemr/demo_farm_openemr: bump-tag.yml
openemr/openemr: release-permissions-check.yml
References
The four
repository_dispatchconsumers of the release flow (openemr/openemr-devops,openemr/website-openemr,openemr/demo_farm_openemr, and the conductor's own permissions-check probe path inopenemr/openemr) all accept the dispatch envelope at face value once the job-levelif:confirms the workflow is running on anopenemr/*repo.The
repository_dispatchAPI itself requires write/repo permission on the target repo, and the openemr-release-app's installation list is explicitly scoped, so the practical risk is low. But the dispatch envelope already carries a documentedrepofield (perdispatch.schema.json's common envelope), and verifyingclient_payload.repo == 'openemr/openemr'would be a cheap defense-in-depth check that catches a misconfigured App, a stolen App credential firing into the wrong repo, or a future App scope expansion.Proposal
Add a uniform payload-origin verification step at the top of each consumer workflow's job:
client_payload.repois notopenemr/openemr.client_payload.eventdoesn't match the workflow's expected event type.workflow_dispatchto bypass (so manual recovery still works).Apply across:
openemr/openemr-devops:release-rotation.yml,ship-release.yml,build-release.yml,build-patch.yml,release-permissions-check.ymlopenemr/website-openemr:release-docs.yml,release-permissions-check.ymlopenemr/demo_farm_openemr:bump-tag.ymlopenemr/openemr:release-permissions-check.ymlReferences
bump-tag.yml)tools/release/contracts/dispatch.schema.json