|
20 | 20 | # alone, that transfer's one target too: `transferIssue` needs issues write on |
21 | 21 | # both ends) and to the permissions the op table declares (`issues: write`, |
22 | 22 | # `pull-requests: write`, the `contents: write` GitHub's auto-merge mutations |
23 | | -# require, and the `metadata: read` the sender gate's permission read needs; |
| 23 | +# require, the `workflows: write` that arming auto-merge on a pull changing a |
| 24 | +# workflow file requires, and the `metadata: read` the sender gate's permission read needs; |
24 | 25 | # plus, for a `workflow_dispatch` stroke ALONE, the `actions: write` the |
25 | 26 | # dispatch endpoint needs — minted from the validator's per-stroke output, so |
26 | | -# every other run's token is exactly the four grants above) |
| 27 | +# every other run's token is exactly the five grants above) |
27 | 28 | # — and revoked by that action's post step. The workflow's own `GITHUB_TOKEN` gets nothing |
28 | 29 | # (`permissions: {}` below); the job grants it `contents: read` for the |
29 | 30 | # checkout and nothing else, so the run's ONLY write path is the App token, |
@@ -123,13 +124,20 @@ jobs: |
123 | 124 | # The op table in `scripts/pm/fleet-write/ops.mjs` has NO contents op — no file, ref |
124 | 125 | # or branch write — so this grant is spent only by those two mutations. |
125 | 126 | permission-contents: write |
| 127 | + # ONE consumer: `automerge_enable` on a pull that changes `.github/workflows/**` — |
| 128 | + # GitHub refuses to enqueue such a pull for an App token without `workflows` (measured: |
| 129 | + # "refusing to allow a GitHub App to create or update workflow … without `workflows` |
| 130 | + # permission"). Literal on every stroke by the maintainer's ruling (comment 6104822731). |
| 131 | + # It also reaches workflow-file writes through contents and git endpoints; the op table |
| 132 | + # has no row for either, and `validate.mjs --self-test` pins that none is reachable. |
| 133 | + permission-workflows: write |
126 | 134 | permission-metadata: read |
127 | 135 | # ONE consumer: the `workflow_dispatch` row — `POST .../actions/workflows/{file}/dispatches` |
128 | 136 | # on an allowlisted file at `main`. Minted ONLY for a stroke carrying that op: the validator |
129 | 137 | # writes `permission_actions=write` for such a stroke and an EMPTY value for every other, |
130 | 138 | # and `actions/create-github-app-token` skips an empty `permission-*` input (its |
131 | 139 | # `lib/get-permissions-from-inputs.js`: an empty value leaves the set unchanged, measured |
132 | | - # at the v3 tag), so every other run keeps exactly the four grants above. `actions: write` |
| 140 | + # at the v3 tag), so every other run keeps exactly the five grants above. `actions: write` |
133 | 141 | # also reaches cancel, re-run, delete, cache and artifact endpoints; the op table has no |
134 | 142 | # row for any of them, and `validate.mjs --self-test` pins that none is reachable. |
135 | 143 | permission-actions: ${{ steps.validate.outputs.permission_actions }} |
|
0 commit comments