Permissions contract¶
What each workflow needs from its caller, why a missing grant fails before any job starts, and how the contract is kept.
What to grant¶
A called workflow's jobs can use at most the permissions the calling job grants. Grant at least:
| Workflow | Caller must grant | Why |
|---|---|---|
ru-build.yml |
contents: read, pull-requests: write |
checkout; firmware size comment on pull requests |
ru-release-with-artifacts.yml |
contents: write |
create the release and upload the firmware |
Set them on the calling job, as in the Quickstart. A top-level permissions: block in the
caller also works, but then every job in that file gets them.
What happens when a grant is missing¶
GitHub checks the permissions before it starts the called workflow. If a job asks for more than the caller
grants, the run ends with startup_failure, shows no jobs and no logs, and only the run summary names the
problem. This is why the contract is part of the version: a new permission on @v1 would break every caller at
once.
How the contract is kept¶
- Every job in a
ru-*.ymldeclares its ownpermissions:; a top-level block is not allowed. .github/scripts/check_permissions.py(self-CI) fails when the union of a workflow's job permissions differs from the table above in either direction, when a workflow has no row, or when a caller in this repository grants less..github/scripts/check_contract.pyfails a pull request that widens a permission without a### Breakingentry in the changelog; that change needs a new major. See Versioning.
The table above is the README's, copied when the site is built, so the site and the checked table are the same.