[release/v7.4.15] [StepSecurity] ci: Harden GitHub Actions tokens#27231
Conversation
Signed-off-by: StepSecurity Bot <[email protected]>
There was a problem hiding this comment.
Pull request overview
Backport of #27202 to harden GitHub Actions GITHUB_TOKEN usage on release/v7.4.15 by setting least-privilege, read-only permissions for workflows involved in xUnit testing, Windows packaging, and Copilot setup.
Changes:
- Add top-level
permissions: contents: readto reusable xUnit and Windows packaging workflows. - Add (restore) the Copilot setup workflow with read-only token permissions.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| .github/workflows/xunit-tests.yml | Adds top-level read-only contents permission for the reusable xUnit workflow. |
| .github/workflows/windows-packaging-reusable.yml | Adds top-level read-only contents permission for the reusable Windows packaging workflow. |
| .github/workflows/copilot-setup-steps.yml | Adds Copilot setup workflow configured with read-only permissions and bootstrap steps. |
| Import-Module ./build.psm1 -Verbose -ErrorAction Stop | ||
| Write-LogGroupEnd -Title $title | ||
|
|
||
| $title = 'Switch to public feed' | ||
| Write-LogGroupStart -Title $title | ||
| Switch-PSNugetConfig -Source Public | ||
| Write-LogGroupEnd -Title $title | ||
|
|
||
| $title = 'Bootstrap' | ||
| Write-LogGroupStart -Title $title | ||
| Start-PSBootstrap -Scenario DotNet | ||
| Write-LogGroupEnd -Title $title | ||
|
|
||
| $title = 'Install .NET Tools' | ||
| Write-LogGroupStart -Title $title | ||
| Start-PSBootstrap -Scenario Tools | ||
| Write-LogGroupEnd -Title $title | ||
|
|
||
| $title = 'Sync Tags' | ||
| Write-LogGroupStart -Title $title | ||
| Sync-PSTags -AddRemoteIfMissing | ||
| Write-LogGroupEnd -Title $title | ||
|
|
||
| $title = 'Setup .NET environment variables' | ||
| Write-LogGroupStart -Title $title | ||
| Find-DotNet -SetDotnetRoot | ||
| Write-LogGroupEnd -Title $title |
There was a problem hiding this comment.
Each Write-LogGroupStart/Write-LogGroupEnd pair here can be left unclosed if the command inside the group throws (e.g., Switch-PSNugetConfig, Start-PSBootstrap, Sync-PSTags, Find-DotNet). Consider wrapping each grouped operation in try/finally (or using a small helper pattern) so the ::endgroup:: marker is always emitted on error for cleaner CI logs.
| Import-Module ./build.psm1 -Verbose -ErrorAction Stop | |
| Write-LogGroupEnd -Title $title | |
| $title = 'Switch to public feed' | |
| Write-LogGroupStart -Title $title | |
| Switch-PSNugetConfig -Source Public | |
| Write-LogGroupEnd -Title $title | |
| $title = 'Bootstrap' | |
| Write-LogGroupStart -Title $title | |
| Start-PSBootstrap -Scenario DotNet | |
| Write-LogGroupEnd -Title $title | |
| $title = 'Install .NET Tools' | |
| Write-LogGroupStart -Title $title | |
| Start-PSBootstrap -Scenario Tools | |
| Write-LogGroupEnd -Title $title | |
| $title = 'Sync Tags' | |
| Write-LogGroupStart -Title $title | |
| Sync-PSTags -AddRemoteIfMissing | |
| Write-LogGroupEnd -Title $title | |
| $title = 'Setup .NET environment variables' | |
| Write-LogGroupStart -Title $title | |
| Find-DotNet -SetDotnetRoot | |
| Write-LogGroupEnd -Title $title | |
| try { | |
| Import-Module ./build.psm1 -Verbose -ErrorAction Stop | |
| } | |
| finally { | |
| Write-Host "::endgroup::" | |
| } | |
| $title = 'Switch to public feed' | |
| Write-LogGroupStart -Title $title | |
| try { | |
| Switch-PSNugetConfig -Source Public | |
| } | |
| finally { | |
| Write-LogGroupEnd -Title $title | |
| } | |
| $title = 'Bootstrap' | |
| Write-LogGroupStart -Title $title | |
| try { | |
| Start-PSBootstrap -Scenario DotNet | |
| } | |
| finally { | |
| Write-LogGroupEnd -Title $title | |
| } | |
| $title = 'Install .NET Tools' | |
| Write-LogGroupStart -Title $title | |
| try { | |
| Start-PSBootstrap -Scenario Tools | |
| } | |
| finally { | |
| Write-LogGroupEnd -Title $title | |
| } | |
| $title = 'Sync Tags' | |
| Write-LogGroupStart -Title $title | |
| try { | |
| Sync-PSTags -AddRemoteIfMissing | |
| } | |
| finally { | |
| Write-LogGroupEnd -Title $title | |
| } | |
| $title = 'Setup .NET environment variables' | |
| Write-LogGroupStart -Title $title | |
| try { | |
| Find-DotNet -SetDotnetRoot | |
| } | |
| finally { | |
| Write-LogGroupEnd -Title $title | |
| } |
| permissions: | ||
| contents: read | ||
|
|
There was a problem hiding this comment.
The workflow sets permissions: contents: read at both the workflow level and again at the job level. The job-level block is redundant unless you intend to override permissions per-job; consider removing it to reduce duplication.
| permissions: | |
| contents: read |
| Import-Module ./build.psm1 -Verbose -ErrorAction Stop | ||
| Write-LogGroupEnd -Title $title |
There was a problem hiding this comment.
The first log group is started with a raw workflow command, but if Import-Module ./build.psm1 -ErrorAction Stop fails the step will exit before emitting ::endgroup::, leaving the GitHub Actions log group unclosed. Consider wrapping the import in a try/finally (emitting ::endgroup:: in finally) so the group is always closed even on failure.
| Import-Module ./build.psm1 -Verbose -ErrorAction Stop | |
| Write-LogGroupEnd -Title $title | |
| try { | |
| Import-Module ./build.psm1 -Verbose -ErrorAction Stop | |
| } | |
| finally { | |
| Write-Host "::endgroup::" | |
| } |
Backport of #27202 to release/v7.4.15
Triggered by @daxian-dbw on behalf of @step-security-bot
Original CL Label: CL-BuildPackaging
/cc @PowerShell/powershell-maintainers
Impact
REQUIRED: Choose either Tooling Impact or Customer Impact (or both). At least one checkbox must be selected.
Tooling Impact
Adds least-privilege GitHub Actions token permissions to release/v7.4.15 workflows used for Copilot setup, Windows packaging, and xUnit test execution.
Customer Impact
Regression
REQUIRED: Check exactly one box.
This is not a regression.
Testing
The cherry-pick completed on release/v7.4.15 after resolving one workflow file state conflict. The resulting workflows all include the intended top-level read-only contents permission, and CI on the backport PR will validate that the affected reusable workflows still execute successfully.
Risk
REQUIRED: Check exactly one box.
Medium risk because the change affects workflow permissions across build and test automation, but it narrows privileges rather than expanding behavior and is limited to three workflow files.
Merge Conflicts
Resolved one delete/update conflict in .github/workflows/copilot-setup-steps.yml by keeping the valid workflow file content and preserving the intended top-level 'permissions: contents: read' hardening from the original PR.