-
Notifications
You must be signed in to change notification settings - Fork 317
Ability for checkout_pr_branch.cjs to preserve .github/skills/ and .github/instructions/ from base branch #23769
Description
Problem
When a gh-aw workflow uses pull_request_target or issue_comment triggers, the platform's checkout_pr_branch.cjs checks out the full PR branch — including .github/skills/ and .github/instructions/. This means fork PRs can inject modified skill files that alter the agent's behavior.
User steps: run before platform steps, so even if a user step restores .github/ from the base branch, checkout_pr_branch.cjs overwrites it afterward. There is no way to insert a user step between the platform checkout and the agent container start.
Execution order (from compiled lock.yml)
| Order | Step | Source |
|---|---|---|
| 1-5 | Setup, checkout base branch | Platform |
| 6-7 | User steps (gate, restore infra) | User steps: |
| 8 | Configure Git credentials | Platform |
| 9 | checkout_pr_branch.cjs — overwrites entire workspace |
Platform |
| 10+ | Install CLI, start agent | Platform |
Impact
A fork PR can include a crafted SKILL.md that instructs the agent to behave differently — e.g., skip evaluation steps, produce misleading results, or attempt to read environment variables. While the agent sandbox (firewall, output sanitization, detection agent, XPIA prompt) mitigates the blast radius, the trust boundary is weaker than documented.
Who is affected
Any gh-aw workflow that:
- Uses
pull_request_targetorissue_commenttriggers - References skill files from the workspace (e.g., "read
.github/skills/my-skill/SKILL.md") - Could be triggered on fork PRs (directly or via maintainer slash commands)
Current workaround
For workflow_dispatch, we run a user step (Checkout-GhAwPr.ps1) that:
- Saves the base branch SHA before checkout
- Checks out the PR branch
- Deletes
.github/skills/and.github/instructions/ - Restores them from the base branch SHA
This works because checkout_pr_branch.cjs is skipped for workflow_dispatch. But for pull_request_target and issue_comment, no workaround exists.
Proposed solutions (any of these would work)
-
Have
checkout_pr_branch.cjspreserve.github/from the base branch — After checking out the PR branch, restore.github/skills/and.github/instructions/from the base commit (similar to what users already do manually forworkflow_dispatch). -
Add a frontmatter option to exclude paths from PR checkout — e.g.,
checkout: { exclude: [".github/skills", ".github/instructions"] } -
Allow user steps to run after
checkout_pr_branch.cjs— Apost-checkout-steps:section in frontmatter that executes after the platform checkout but before the agent starts.
References
- dotnet/maui uses this pattern:
Checkout-GhAwPr.ps1 - Related umbrella issue: Using gh-aw in forks of repositories #18481 (covers fork support broadly but does not mention this specific overwrite behavior)