[release/v7.6.1] [StepSecurity] ci: Harden GitHub Actions tokens by daxian-dbw · Pull Request #27218 · PowerShell/PowerShell · GitHub
Skip to content

[release/v7.6.1] [StepSecurity] ci: Harden GitHub Actions tokens#27218

Merged
daxian-dbw merged 1 commit intoPowerShell:release/v7.6.1from
daxian-dbw:backport/release/v7.6.1/27202-601f0167e
Apr 9, 2026
Merged

[release/v7.6.1] [StepSecurity] ci: Harden GitHub Actions tokens#27218
daxian-dbw merged 1 commit intoPowerShell:release/v7.6.1from
daxian-dbw:backport/release/v7.6.1/27202-601f0167e

Conversation

@daxian-dbw
Copy link
Copy Markdown
Member

Backport of #27202 to release/v7.6.1

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

  • Required tooling change
  • Optional tooling change (include reasoning)

Backports the GitHub Actions token permission hardening needed to apply least-privilege defaults to release workflow definitions.

Customer Impact

  • Customer reported
  • Found internally

Regression

REQUIRED: Check exactly one box.

  • Yes
  • No

This is not a regression.

Testing

Verified by cherry-picking onto release/v7.6.1 and resolving a single delete-vs-add conflict in .github/workflows/copilot-setup-steps.yml by keeping the incoming workflow file from the PR. No local workflow run was performed; CI on the backport PR will validate the updated workflow permissions.

Risk

REQUIRED: Check exactly one box.

  • High
  • Medium
  • Low

Medium risk because the change affects CI workflow permissions, which can break automation if permissions are too restrictive. The scope is limited to workflow metadata and the conflict resolution preserved the incoming security hardening change.

Merge Conflicts

Conflict in .github/workflows/copilot-setup-steps.yml. On release/v7.6.1 the file was absent, while the incoming PR modified it to add workflow-level permissions. Resolved as a delete-vs-add conflict by keeping the incoming workflow file so the token hardening change is preserved.

Signed-off-by: StepSecurity Bot <bot@stepsecurity.io>
@daxian-dbw daxian-dbw requested review from a team and jshigetomi as code owners April 9, 2026 05:54
@daxian-dbw daxian-dbw added the CL-BuildPackaging Indicates that a PR should be marked as a build or packaging change in the Change Log label Apr 9, 2026
Copilot AI review requested due to automatic review settings April 9, 2026 05:54
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Backport to release/v7.6.1 to harden GitHub Actions GITHUB_TOKEN permissions to least-privilege defaults across selected workflows.

Changes:

  • Add workflow-level permissions: contents: read to reusable xUnit test workflow.
  • Add workflow-level permissions: contents: read to reusable Windows packaging workflow.
  • Add copilot-setup-steps workflow with contents: read permissions and bootstrapping steps.

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 Restricts workflow token to contents: read.
.github/workflows/windows-packaging-reusable.yml Restricts workflow token to contents: read.
.github/workflows/copilot-setup-steps.yml Adds a Copilot setup workflow and applies least-privilege token permissions.

# You can define any steps you want, and they will run before the agent starts.
# If you do not check out your code, Copilot will do this for you.
steps:
- uses: actions/checkout@v6
Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

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

actions/checkout@v6 is the only usage of checkout v6 in this repo; other workflows use v4/v5 or pin to a specific commit SHA. Please align this workflow to an existing supported version (or a pinned SHA) to avoid failures if v6 is not available and to keep dependencies consistent across workflows.

Suggested change
- uses: actions/checkout@v6
- uses: actions/checkout@v5

Copilot uses AI. Check for mistakes.
Comment on lines +37 to +63
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
Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

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

The log group started with Write-Host "::group::$title" isn't guaranteed to be closed if Import-Module fails (the ::endgroup:: is emitted after the failing command). Wrap the grouped block in try/finally so the ::endgroup:: (or equivalent) is always emitted even on errors.

Suggested change
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
}

Copilot uses AI. Check for mistakes.
Comment on lines +36 to +63
Write-Host "::group::$title"
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
Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

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

Each Write-LogGroupStart should be paired with a guaranteed Write-LogGroupEnd even when a command inside the group throws (e.g., Switch-PSNugetConfig, Start-PSBootstrap). Consider wrapping each grouped section in try/finally so a failure doesn't leave the remainder of the job output collapsed inside an unclosed group.

Suggested change

Copilot uses AI. Check for mistakes.
@daxian-dbw daxian-dbw merged commit 02413bb into PowerShell:release/v7.6.1 Apr 9, 2026
40 checks passed
@daxian-dbw daxian-dbw deleted the backport/release/v7.6.1/27202-601f0167e branch April 9, 2026 16:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CL-BuildPackaging Indicates that a PR should be marked as a build or packaging change in the Change Log

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants