pre_activation role check fails for workflow_run events (should use workflow-based trust)
Problem
When a gh-aw workflow is triggered via workflow_run, the pre_activation job always fails the role check because check_membership.cjs evaluates github.actor, which is github-actions[bot] for workflow_run events. Since github-actions[bot] has no repository collaborator role, the check outputs activated = false and the entire workflow silently skips.
This makes it impossible to chain gh-aw agentic workflows via workflow_run while keeping the role-based security gate.
Repro
-
Create a gh-aw workflow (agent.md) with workflow_run trigger:
on:
workflow_run:
workflows: ["CI"]
types: [completed]
-
Compile with gh aw compile
-
Trigger the upstream CI workflow (via PR, push, or another agent)
-
CI completes → workflow_run fires → pre_activation runs
-
check_membership.cjs checks github.actor = github-actions[bot]
-
Bot has no repo role → activated = false → workflow silently skips
Root Cause
check_membership.cjs uses context.actor to determine who triggered the workflow. For workflow_run events, GitHub Actions sets github.actor to the automation bot, not the original actor.
Why triggering_actor alone doesn't solve this
GitHub provides github.triggering_actor which preserves the original human in simple chains:
| Context |
pull_request event |
workflow_run (human-initiated) |
github.actor |
alice |
github-actions[bot] |
github.triggering_actor |
alice |
alice |
However, workflow_run chains are also commonly initiated by other agents or automated workflows (e.g., an overnight linter bot creates a PR → CI runs → downstream agent workflow triggers). In that case, github.triggering_actor is also github-actions[bot] — it's bots all the way down, and the role check still fails.
Current Workaround
Setting roles: all in the workflow frontmatter disables the pre_activation job entirely. This works but removes the role-based security gate, which is the only thing preventing untrusted actors from triggering agentic workflows.
Proposed Fix
For workflow_run events, the trust model should be based on which upstream workflow triggered the run rather than actor identity. GitHub's workflow_run already validates that the triggering workflow is in the same repository and provides github.event.workflow_run.workflow_id to identify it.
A possible approach:
- For
workflow_run events where github.triggering_actor is a human, check that human's role (current behavior but using triggering_actor)
- For
workflow_run events where github.triggering_actor is a bot, trust the event if the triggering workflow is in the same repository and is not from a fork — the upstream workflow's own activation already validated the original actor
- Optionally allow an allowlist of trusted upstream workflow IDs in the frontmatter
This would allow workflow_run chains to work without roles: all while maintaining security against fork-based attacks.
References
pre_activation role check fails for workflow_run events (should use workflow-based trust)
Problem
When a gh-aw workflow is triggered via
workflow_run, thepre_activationjob always fails the role check becausecheck_membership.cjsevaluatesgithub.actor, which isgithub-actions[bot]forworkflow_runevents. Sincegithub-actions[bot]has no repository collaborator role, the check outputsactivated = falseand the entire workflow silently skips.This makes it impossible to chain gh-aw agentic workflows via
workflow_runwhile keeping the role-based security gate.Repro
Create a gh-aw workflow (
agent.md) withworkflow_runtrigger:Compile with
gh aw compileTrigger the upstream
CIworkflow (via PR, push, or another agent)CIcompletes →workflow_runfires →pre_activationrunscheck_membership.cjschecksgithub.actor=github-actions[bot]Bot has no repo role →
activated = false→ workflow silently skipsRoot Cause
check_membership.cjsusescontext.actorto determine who triggered the workflow. Forworkflow_runevents, GitHub Actions setsgithub.actorto the automation bot, not the original actor.Why
triggering_actoralone doesn't solve thisGitHub provides
github.triggering_actorwhich preserves the original human in simple chains:pull_requesteventworkflow_run(human-initiated)github.actoralicegithub-actions[bot]github.triggering_actoralicealiceHowever,
workflow_runchains are also commonly initiated by other agents or automated workflows (e.g., an overnight linter bot creates a PR → CI runs → downstream agent workflow triggers). In that case,github.triggering_actoris alsogithub-actions[bot]— it's bots all the way down, and the role check still fails.Current Workaround
Setting
roles: allin the workflow frontmatter disables thepre_activationjob entirely. This works but removes the role-based security gate, which is the only thing preventing untrusted actors from triggering agentic workflows.Proposed Fix
For
workflow_runevents, the trust model should be based on which upstream workflow triggered the run rather than actor identity. GitHub'sworkflow_runalready validates that the triggering workflow is in the same repository and providesgithub.event.workflow_run.workflow_idto identify it.A possible approach:
workflow_runevents wheregithub.triggering_actoris a human, check that human's role (current behavior but usingtriggering_actor)workflow_runevents wheregithub.triggering_actoris a bot, trust the event if the triggering workflow is in the same repository and is not from a fork — the upstream workflow's own activation already validated the original actorThis would allow
workflow_runchains to work withoutroles: allwhile maintaining security against fork-based attacks.References