Permissions
A called reusable workflow cannot hold more GITHUB_TOKEN permissions than the caller grants, and most repos default to a read-only token. So workflows that need to write must have the caller grant it on the calling job. The stubs in examples/ already include the right permissions: blocks; copy them as-is.
Per-workflow grants
-
check-ai-tells,check-bibliography-dois,check-code-similarity,check-equation-renders,check-extra,check-formatting,check-junk-files,check-new-line-breaks,check-news,check-non-standard-chars,check-phi,check-secrets,check-typos,cursor-code-review,lint-changed-files,lint-changed-lines,lint-markdown,lint-qmd,lint-workflows,lint-yaml,preview,r-cmd-check,spellcheck,test-coverage,version-checkneed onlycontents: read(the default), so nopermissions:block is needed. This list is checked against the workflows’ ownpermissions:blocks by.github/workflows/scripts/tests/run-permissions-docs-tests.py; keep the markers around it. check-linksopens an issue onmainfailures, so grantissues: write,pull-requests: read,contents: read.summarycomments on issues and calls the models API, so grantissues: write,models: read,contents: read.update-snapshotspushes the snapshot-update commit back to the branch, so grantcontents: write.quarto-publishdeploys to thegh-pagesbranch, so grantcontents: write, and set Settings -> Pages -> Source to “Deploy from a branch”, branchgh-pages/(root)once. Grantcontents: writeeven withdeploy: false: the deploy job is part of the workflow, so the caller must grant its permissions even when it is skipped.preview-deploy(deploy half) pushesgh-pagesand comments, so grantcontents: write,pull-requests: write,actions: read. Thepreviewbuild half is read-only, above.check-equation-rendersdownloads the build artifact. It is read-only, above, but a caller that narrows below the read-only default token still needsactions: readalongsidecontents: read.check-newsreads the PR’s labels live for its skip-label exemption. It is read-only, above, but a caller that narrows below the read-only default token still needsissues: readandpull-requests: readalongsidecontents: read.version-checkreads the PR’s labels live for itsno version incrementexemption. It is read-only, above, but a caller that narrows below the read-only default token still needspull-requests: readalongsidecontents: read. Notissues: read: that scope alone returned 403 on the same call (gha#724), since GitHub authorizes a label read on an issue object that is a pull request against the pull-requests permission.cleanup-pr-previewscommits deletions togh-pages, so grantcontents: write,pull-requests: read.bump-submodule,sync-shared-fragments,sync-upstreamopen a PR, so grantcontents: write,pull-requests: write, and enable Settings -> Actions -> General -> “Allow GitHub Actions to create and approve pull requests”.report-failurefiles or updates the issue tracking a failing workflow, so grantissues: writeon the reporting job – and nothing else. It performs no checkout, so it needs nocontentsgrant; the job it watches keeps its own permissions.claudepushes branches, opens PRs, and dispatches the review workflow, so grantcontents: write,pull-requests: write,issues: write,id-token: write,actions: write, and add either theCLAUDE_CODE_OAUTH_TOKENorANTHROPIC_API_KEYsecret.claude-code-review(read-only review) grantscontents: read,pull-requests: write,issues: write,actions: read, and either theCLAUDE_CODE_OAUTH_TOKENorANTHROPIC_API_KEYsecret. The model job’sGITHUB_TOKENhas no write scopes (contents/pull-requests/issues/actions: read); write is confined to jobs that never run the model (gather-contextandpost-review) (gha#580).actions: readis required on the caller: apermissions:block sets unspecified scopes to none, andpost-reviewneeds it to download the packed artifact (the model job also uses it for thegithub_ciMCP server).cursor-code-reviewqueues a Cursor Bugbot review. It is read-only, above, but does need theCURSOR_API_KEYsecret (Enterprise,admin:*scope).opencode-code-reviewis a read-only review that posts its own comment, so grantcontents: read,pull-requests: write,issues: write, and set theOPENCODE_API_KEYsecret (OpenCode Zen).ai-code-reviewselects the first available AI reviewer and dispatches its review workflow, so grantcontents: read,pull-requests: read,issues: read,actions: write, and pass the secrets of whichever agent review workflows are installed (seeexamples/ai-code-review.yml).issues: readis required since the delivery classifier’s comment scan landed (gha#638); a caller missing it fails at parse time with no API-visible diagnostic (gha#685).geminipushes branches, opens PRs, and dispatches the review workflow, so grantcontents: write,pull-requests: write,issues: write,id-token: write,actions: write, and add theGEMINI_API_KEYsecret.gemini-code-reviewposts the Gemini review, so grantcontents: read,pull-requests: write,issues: write,id-token: write, and theGEMINI_API_KEYsecret.antigravity-code-reviewposts the Antigravity review, so grantcontents: read,pull-requests: write,issues: write,id-token: write, and theGEMINI_API_KEYsecret.small-model-agentposts the small-model agent’s PR comment, so grantcontents: read,pull-requests: write.claude-manage-projectfiles issues and updates the project board, so grantcontents: read,issues: write,repository-projects: write, and add theCLAUDE_CODE_OAUTH_TOKENsecret (required).altdoc-multiversion-docsdeploys togh-pages, comments PR previews, and rewrites rendered links, so grantcontents: write,pull-requests: write, andissues: write, and set Settings -> Pages -> Source to “Deploy from a branch”, branchgh-pages/(root)once.request-dependabot-reviewrequests a reviewer on the PR, so grantpull-requests: write.bump-dev-versionopens (or auto-merges) a PR, so grantcontents: write,pull-requests: write, enable the same “Allow GitHub Actions to create and approve pull requests” setting as above, and (for its defaultauto-merge: true) “Allow auto-merge” too. Itsversion-checkcounterpart is read-only, above.
Optional secrets
WORKFLOW_TOKEN(a PAT or GitHub App token withcontents:write+workflows:write). The integratedGITHUB_TOKENcannot push changes to files under.github/workflows/; GitHub rejects them without theworkflowsscope. Add this secret ifclaudewill edit workflow files, to push to a protected branch, or – forbump-dev-versionwith its defaultauto-mergein a repo with required status checks – to let the bump PR’s checks run so it can merge (aGITHUB_TOKEN-authored PR’spull_requestchecks never report, so the merge stays blocked; see its reference page). UnlikeGITHUB_TOKEN, a PAT or App-token push does trigger otherpush-based workflows, so enabling it can set off extra CI runs. When the secret is absent andclaudedoes edit a workflow file, the rejected push is reported as an error naming this secret, and the commits are posted to the thread as agit format-patchso they survive the run.SUBMODULES_TOKEN. Public submodules clone anonymously; private ones need this secret. Relevant toclaude,claude-code-review,r-cmd-check, andbump-submodulewhencheckout-submodules(or the submodule update) touches a private submodule.
Notes for private consumers
Reusable workflows in this public repo are callable from public repos automatically. A private consumer must allow access to this repo under Settings -> Actions -> General -> Access before it can call these workflows.