Skip to content

Checkout PR branch refuses GitHub Apps listed in on.bots for comment-triggered workflows #67155

Description

@jaroslawgajewski

Summary

A workflow that lists a GitHub App in on.bots activates for that App's /command comment, then fails in the agent job at Checkout PR branch:

ERR_PERMISSION: Refusing PR checkout: actor '***' has 'none' permission (requires write or higher)

checkout_pr_branch.cjs requires GET /repos/{owner}/{repo}/collaborators/{actor}/permission to return write, maintain or admin. GitHub Apps are not collaborators and always get none. The only exemption is for pull_request opened/synchronize events sent by a Bot on a same-repository PR (the code comment says comments "do not prove the sender can write the PR branch"). GH_AW_ALLOWED_BOTS / on.bots is not consulted, and there is no setting for this.

Reproduction

  1. Workflow with on.slash_command, on.bots: ["my-app[bot]"] and a PR checkout in the agent job (any pull-requests: read review workflow).
  2. my-app[bot] posts /command as a comment on a same-repository PR.
  3. pre_activation passes ("matched the allowed bots list"), activation passes, agent fails at Checkout PR branch with the error above.

Seen in two independent fleets, on GitHub Enterprise Cloud with data residency and on github.com, for an automation that requests a deep review after remediation.

Expected

on.bots should mean what the docs say for the whole run. Suggested rule in assertTrustedCheckoutRuntime, for issue_comment and pull_request_review_comment events:

  • the actor (canonicalized, <slug> and <slug>[bot] equivalent) is in GH_AW_ALLOWED_BOTS, and
  • payload.sender.type === "Bot" and the comment author is that actor, and
  • the PR head repository id equals the base repository id (never a fork).

Every other actor keeps today's collaborator check.

Security notes

The allow-list is an explicit, reviewed choice in the workflow source. A same-repository head branch already requires push access, so trusting an allow-listed bot's comment does not execute code from an untrusted author. Forks stay refused.

Workarounds today

  • Post the command with a machine user token that has write (works, but every caller needs that token).
  • Patch the step to answer the permission lookup write for that one actor; we have this as a small shim but would rather not carry it.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions