Skip to content

ci: declare workflow-level contents: read on 16 build/regen workflows - #2584

Merged
Perksey merged 2 commits into
dotnet:mainfrom
arpitjain099:chore/declare-workflow-perms-readonly
Jul 26, 2026
Merged

ci: declare workflow-level contents: read on 16 build/regen workflows#2584
Perksey merged 2 commits into
dotnet:mainfrom
arpitjain099:chore/declare-workflow-perms-readonly

Conversation

@arpitjain099

Copy link
Copy Markdown
Contributor

Pins the default GITHUB_TOKEN to contents: read on every workflow in .github/workflows/. They are all native-library binding regen workflows (angle, assimp, dxvk, glfw, moltenvk, openal-soft, sdl2, shaderc, spirv-cross, spirv-reflect, swiftshader, vkd3d, vulkan-loader, wgpu) plus bindings-regeneration and codeowners checks. None of them call a GitHub API beyond the initial checkout.

Why

CVE-2025-30066 (March 2025 tj-actions/changed-files supply-chain compromise) exfiltrated GITHUB_TOKEN from workflow logs. Pinning per workflow caps runtime authority irrespective of the repo or org default, gives drift protection if the default ever widens, and is credited per-file by the OpenSSF Scorecard Token-Permissions check.

YAML validated locally with yaml.safe_load on each touched file.

@arpitjain099

Copy link
Copy Markdown
Contributor Author

@dotnet-policy-service agree

@Perksey

Perksey commented May 30, 2026

Copy link
Copy Markdown
Member

Pretty sure these workflows make use of write permissions (to push the regenerated bindings)

@arpitjain099

Copy link
Copy Markdown
Contributor Author

Good thing to check, and you're right that these workflows do push the regenerated bindings. I looked at how they authenticate that push, though, and it doesn't go through the default GITHUB_TOKEN:

  • Each workflow runs actions/checkout@v2 with token: ${{ secrets.PUSHABLE_GITHUB_TOKEN }}, so the persisted git credential is that PAT, and the later push from the nuke build uses it (angle.yml:36, bindings-regeneration.yml:19, sdl2.yml:41, etc).
  • The build/regen step that does the actual push gets the PAT via env: PUSHABLE_GITHUB_TOKEN, not the default token.

A workflow-level permissions: block only scopes the default GITHUB_TOKEN. Since none of these 16 use the default token for anything, contents: read doesn't touch the bindings-push path; it just shrinks the default token's blast radius if one of the build actions were ever compromised (the CVE-2025-30066 supply-chain case). These run on push with a powerful PAT in scope, so tightening the ambient token is worthwhile.

I deliberately left build.yml out of this PR for exactly the reason you raised: it's the one that uses secrets.GITHUB_TOKEN directly (PushToNuGet to GitHub Packages at build.yml:81), so it genuinely needs packages: write and isn't a contents: read candidate.

Happy to walk through any specific file if you'd like, or drop any you're not comfortable with.

Pins the default GITHUB_TOKEN to contents: read on every workflow in
.github/workflows/. They are all native-library binding regen
workflows (angle, assimp, dxvk, glfw, moltenvk, openal-soft, sdl2,
shaderc, spirv-cross, spirv-reflect, swiftshader, vkd3d,
vulkan-loader, wgpu) plus bindings-regeneration and codeowners checks.
None call a GitHub API beyond the initial checkout.

Motivation: CVE-2025-30066 (March 2025 tj-actions/changed-files
compromise) exfiltrated GITHUB_TOKEN from workflow logs. Per-workflow
caps bound runtime authority irrespective of repo or org default,
give drift protection if the default ever widens, and are credited
per-file by the OpenSSF Scorecard Token-Permissions check.

YAML validated locally with yaml.safe_load.

Signed-off-by: Arpit Jain <arpitjain099@gmail.com>
@arpitjain099
arpitjain099 force-pushed the chore/declare-workflow-perms-readonly branch from d22ff41 to 9ba99d7 Compare June 10, 2026 07:35

@Perksey Perksey left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmmm, okay I'll merge but I'm not happy with the AI-generated explanation, however accurate it may be. Would appreciate human words next time.

@github-project-automation github-project-automation Bot moved this from Todo to In Progress in Silk.NET Development Tracker Jul 26, 2026
@Perksey
Perksey enabled auto-merge (squash) July 26, 2026 16:58
@Perksey
Perksey disabled auto-merge July 26, 2026 17:00
@Perksey
Perksey enabled auto-merge (squash) July 26, 2026 17:05
@Perksey
Perksey merged commit 9b54298 into dotnet:main Jul 26, 2026
3 checks passed
@github-project-automation github-project-automation Bot moved this from In Progress to Done in Silk.NET Development Tracker Jul 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants