|
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, and the `metadata: read` the sender gate's permission read needs; |
| 24 | +# plus, for a `workflow_dispatch` stroke ALONE, the `actions: write` the |
| 25 | +# dispatch endpoint needs — minted from the validator's per-stroke output, so |
| 26 | +# every other run's token is exactly the four grants above) |
24 | 27 | # — and revoked by that action's post step. The workflow's own `GITHUB_TOKEN` gets nothing |
25 | 28 | # (`permissions: {}` below); the job grants it `contents: read` for the |
26 | 29 | # checkout and nothing else, so the run's ONLY write path is the App token, |
|
84 | 87 | # non-integer number, an over-cap string or an over-cap payload with |
85 | 88 | # every reason in the step summary and zero writes; on success it hands |
86 | 89 | # the mint below the repository NAMES its token must reach through |
87 | | - # `$GITHUB_OUTPUT` — one for every stroke, two for a transfer stroke. |
| 90 | + # `$GITHUB_OUTPUT` — one for every stroke, two for a transfer stroke — |
| 91 | + # and `permission_actions`: `write` for a stroke carrying the one |
| 92 | + # `workflow_dispatch` action, EMPTY for every other stroke. |
88 | 93 | - name: Validate the payload (closed schema, zero writes on refusal) |
89 | 94 | id: validate |
90 | 95 | env: |
@@ -119,6 +124,15 @@ jobs: |
119 | 124 | # or branch write — so this grant is spent only by those two mutations. |
120 | 125 | permission-contents: write |
121 | 126 | permission-metadata: read |
| 127 | + # ONE consumer: the `workflow_dispatch` row — `POST .../actions/workflows/{file}/dispatches` |
| 128 | + # on an allowlisted file at `main`. Minted ONLY for a stroke carrying that op: the validator |
| 129 | + # writes `permission_actions=write` for such a stroke and an EMPTY value for every other, |
| 130 | + # and `actions/create-github-app-token` skips an empty `permission-*` input (its |
| 131 | + # `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` |
| 133 | + # also reaches cancel, re-run, delete, cache and artifact endpoints; the op table has no |
| 134 | + # row for any of them, and `validate.mjs --self-test` pins that none is reachable. |
| 135 | + permission-actions: ${{ steps.validate.outputs.permission_actions }} |
122 | 136 |
|
123 | 137 | # The sender gate, then the actions in order, then the step summary — |
124 | 138 | # request id · sender and role · session · target · one row per request. |
|
0 commit comments