Sure, that particular workflow is quite busted. But GitHub encourages this garbage design.
For example:
> GITHUB_TOKEN: ${{ secrets.POSTHOG_BOT_GITHUB_TOKEN }}
In no particular order:
- The use of secrets like this should be either entirely invalid or strongly, strongly discouraged. If allowed at all, there should be some kind of explicit approval required for the workflow step that gets to use the secret. And a file in the branch’s tree should not count as approval.
- This particular disaster should at least have been spelled something like ${{ dynamic_secret.assign_reviewer }} where that operation creates a secret that can assign a reviewer and nothing else and that lasts for exactly as long as the workflow step runs.
- In an even better design, there would be no secret at all. One step runs the script and produces output and has no permissions:
- name: Run reviewer assignment script
env:
PR_NUMBER: ${{ github.event.pull_request.number }}
GITHUB_REPOSITORY: ${{ github.repository }}
BASE_SHA: ${{ github.event.pull_request.base.sha }}
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
input: worktree ro at cwd
output: reviewer from /tmp/reviewer
run: |
node .github/scripts/assign-reviewers.js
I made up the syntax - that’s a read only view of “worktree” (a directory produced by a previous step) mounted at cwd. The output is a file at /tmp/reviewers that contains data henceforth known as “reviewer”. Then the next step isn’t a “run” — it’s something else entirely:
- name: Assign the reviewer
env:
PR_NUMBER: ${{ github.event.pull_request.number }}
REVIEWER: ${{ outputs.reviewer }}
action: assign-reviewer
That last part is critical. This does not execute anything in the runner VM. It consumes the output from the previous step in the VM and then it … drumroll, please, because this is way too straightforward for GitHub … assigns the reviewer. No token, no secrets, no user-modifiable code, no weird side effects, no possibility of compromise due to a rootkit installed by a previous step into the VM, no containers spawned, no nothing. It just assigns a reviewer.
In this world, action workflows have no “write” permission ever. The repository config (actual config, not stuff in .github) gives a menu of allowed “actions”, and the owner checks the box so that this workflow may do “assign-reviewer”, and that’s it. If the box is checked, reviewers may be assigned. If not, they may not. Checking the box does not permit committing things or poisoning caches or submitting review comments or anything else - those are different checkboxes.
Oh, it costs GitHub less money, too, because it does not need to call out to the runner, and that isn’t free.