Jobs without a permissions block get the repository's default token
scope, and reusable workflow calls pass the caller's grants straight
through. Scopes are now derived from what each workflow actually does
with the token:
- every build workflow declares contents: read; none of them writes
through the GITHUB_TOKEN.
- build-linux-hosts.yml keeps security-events: write for the CodeQL
upload; the other callers had that grant too but never upload
scanning results, so they drop it.
- build-windows-hosts.yml gets actions: read, which the SignPath
action documents needing to read job details and download the
unsigned artifact.
- build-release.yml declares contents: write, matching the grant its
caller already makes for creating the release.
Runs that execute pull request code now hold a token that can do
nothing but read the repository.
Every reusable workflow call used 'secrets: inherit', which hands the
caller's whole secret set to the called workflow, but the only secret
any of them reads is SIGNPATH_API_TOKEN in build-windows-hosts.yml.
Passing that one secret explicitly and dropping inherit everywhere else
means a compromised step in, say, a BSD build VM has no signing token
to steal, and the workflow files now show exactly which secret flows
where.
The secret is declared optional in the reusable workflow so runs
without it (pull requests, forks) behave as before; the signing step
is already guarded to upstream push events.
A version tag like @v1 or a branch like @master is a movable pointer:
whoever controls the action repository can re-point it, and the next
run executes whatever it points at. Several of these actions run in
jobs whose outputs ship to users: build-release.yml creates the GitHub
release with the downloadable binaries, and build-windows-hosts.yml
holds the SignPath signing token, so a re-pointed tag there could ship
a tampered or wrongly signed release. This is exactly how the
tj-actions/changed-files compromise propagated (CVE-2025-30066).
Pinning by full commit SHA makes the reviewed code the code that runs,
the same way docker/setup-qemu-action is already pinned in
build-linux-vms.yml. Refs that pointed at master (cross-platform-actions,
setup-alpine, get-latest-release) are pinned to their latest release
tag. Every pin keeps a version comment, and each SHA was resolved from
the upstream repository and cross-checked against its release tag.
The minimal (core) installation ships the `ubuntustudio-desktop-core`
metapackage instead of `ubuntustudio-desktop`, so the existing check
missed it and the system was reported as Kubuntu.
Fixes#2485