Repository navigation
Authorize allowlisted GitHub App actors on repository_dispatch - #63492
Conversation
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
The new error guard can fail open for an empty error message, and the documentation inaccurately describes some authorization paths.
Get a fresh assessment by requesting another Copilot review.
Review effort: Balanced
Findings: 1
Open (3)
What changed in this PR
Enables allowlisted GitHub Apps to trigger repository_dispatch workflows while retaining existing authorization behavior elsewhere.
Changes:
- Relaxes App installation verification for allowlisted repository dispatches.
- Adds authorization and failure-path tests.
- Documents the behavior and adds a patch changeset.
| File | Description |
|---|---|
actions/setup/js/check_membership.cjs |
Implements conditional App authorization. |
actions/setup/js/check_membership.test.cjs |
Tests dispatch authorization guardrails. |
docs/src/content/docs/reference/triggers.md |
Documents App-triggered dispatches. |
.changeset/repository-dispatch-app-bots.md |
Records the patch release change. |
💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.
|
|
||
| Omit `types:` to fire on any `event_type`. | ||
|
|
||
| The dispatch sender still goes through the [role check](#filtering-by-repository-access-roles-onroles-onskip-roles). A PAT-based sender is checked against `on.roles:`; a GitHub App sender is never a repository collaborator and must be allowlisted with [`on.bots:`](#filtering-by-bot-onbots-onskip-bots). |
There was a problem hiding this comment.
Qualified in d9fc499 — the sentence now reads "Unless on.roles: all is set (which disables the check entirely), the dispatch sender goes through the role check."
|
|
||
| The `[bot]` suffix is optional — `github-actions` matches `github-actions[bot]` automatically. | ||
|
|
||
| Allowlisted bots must be installed on the repository, which is verified through the repository collaborator API. GitHub App identities are not collaborators, so that lookup finds nothing for them. On `repository_dispatch` the check is therefore relaxed: an allowlisted App is authorized without the installation lookup, because sending the event already requires `contents: write` access to the repository. This is how an App-triggered `repository_dispatch` is admitted — `on.roles:` is matched against repository collaborator roles and never matches an App sender. |
There was a problem hiding this comment.
Reworded in d9fc499 to describe the actual fail-closed behavior: the lookup is still performed, authorization happens only on a conclusive "not a collaborator" result, and a failed lookup (outage/rate limit) is still denied.
|
@copilot Please review the current head, address any remaining maintainer feedback, refresh the branch if needed, and continue with the
|
Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com>
|
@copilot update safe output specs and specs tests. |
|
@copilot Please review the current head, address any remaining maintainer feedback, refresh the branch if needed, and continue with the
|
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
…-issues Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com>
Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com>
Refreshed the branch from current |
|
🎉 This pull request is included in a new release. Release: |


on.roles:is matched against repository collaborator roles, and GitHub App identities are never collaborators — so an App-sentrepository_dispatchalways resolved to permissionnoneand the run was skipped at pre-activation. The documented escape hatch,on.bots:, was broken for the same reason:checkBotStatusverifies installation through the same collaborator API and reported the App as "not active/installed".Changes
actions/setup/js/check_membership.cjs:checkBotAllowlistAuthorizationtakes aninstallationCheckOptionaloption, set bymain()only forrepository_dispatch. An allowlisted actor whose collaborator lookup conclusively reports "not a collaborator" is authorized, since posting arepository_dispatchalready requirescontents: writeon the repository.on.bots:are admitted — everyone else still goes through the normalon.roles:gate; transient lookup failures (5xx, rate limiting) seterrorand still deny; all other events are unchanged and still require the bot to be installed.repository_dispatch, non-allowlisted App still denied, other events still require installation, transient failure still denies.reference/triggers.md): therepository_dispatchandon.bots:sections now state that App senders are admitted viaon.bots:rather thanon.roles:.Working configuration for an App→App chain:
Deliberately not implemented: blanket exemption of all
repository_dispatchsenders, which would silently downgrade a workflow declaringroles: [admin]to "anyone with write access".Unrelated to the code change, two claims in the issue do not reproduce on
main:on.roles:does change the compiledGH_AW_REQUIRED_ROLES(a top-levelroles:key is rejected with a schema error pointing aton.roles), and there is nonone/anyvalue —allis the documented "no restrictions" setting.