Why
PSAliasFinder ships as a binary module (compiled .NET 8 DLL). For users with supply-chain hygiene, that's an opaque artifact published by a relatively unknown maintainer — they can't easily verify what the DLL does or that it matches the source on this repo.
Mitigation: move the build + publish to GitHub Actions and emit a build provenance attestation so anyone can verify cryptographically that the DLL on the PowerShell Gallery was produced by Actions on this repo at a specific tagged commit. Also moves the PSGallery API key off the maintainer's local machine into a GitHub Secret, removing a manual-handling failure mode.
Outcome
- Pushing a tag like
2.0.2 triggers a workflow that:
- Builds the DLL via the existing
build.ps1.
- Generates a build provenance attestation against the DLL.
- Stages a clean ship layout (no
src/, no tests/, no demo gif).
- Publishes to PSGallery using a stored API key.
- Creates a GitHub Release with auto-generated notes and the DLL attached.
- End users can verify locally:
Save-Module PSAliasFinder -RequiredVersion 2.0.2 -Path .
gh attestation verify ./PSAliasFinder/2.0.2/bin/PSAliasFinder.dll --repo backmind/PSAliasFinder
One-time setup (manual, before the workflow runs)
a) Generate a scoped PSGallery API key
- Sign in to https://www.powershellgallery.com/account/apikeys.
- Create, with:
- Key Name:
PSAliasFinder-CI
- Expires: 365 days (max).
- Scopes:
Push only new package versions of existing packages (sufficient because 2.0.x is already published; new keys can also pick Push new packages and package versions if needed).
- Glob Pattern:
PSAliasFinder (limits the key to this module).
- Copy the key (only shown once).
b) Add the key as a repo secret
- Go to https://github.com/backmind/PSAliasFinder/settings/secrets/actions.
- New repository secret:
- Name:
PSGALLERY_API_KEY
- Value: paste the key from (a).
Workflow file
Save as .github/workflows/release.yml:
name: Release
on:
push:
tags:
- '[0-9]+.[0-9]+.[0-9]+'
permissions:
contents: write # for GitHub Release creation
id-token: write # required by attest-build-provenance
attestations: write # required by attest-build-provenance
jobs:
build-and-publish:
runs-on: windows-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-dotnet@v4
with:
dotnet-version: '8.0.x'
- name: Build
shell: pwsh
run: ./build.ps1
- name: Generate build provenance attestation
uses: actions/attest-build-provenance@v1
with:
subject-path: bin/PSAliasFinder.dll
- name: Stage clean ship layout
shell: pwsh
run: |
$ship = Join-Path $env:RUNNER_TEMP 'ship/PSAliasFinder'
New-Item -ItemType Directory -Path "$ship/bin" -Force | Out-Null
Copy-Item PSAliasFinder.psd1, PSAliasFinder.psm1, README.md, LICENSE $ship
Copy-Item bin/PSAliasFinder.dll "$ship/bin/"
"SHIP_PATH=$ship" | Out-File $env:GITHUB_ENV -Append
- name: Publish to PowerShell Gallery
shell: pwsh
env:
PSGALLERY_API_KEY: ${{ secrets.PSGALLERY_API_KEY }}
run: |
Publish-Module -Path $env:SHIP_PATH -NuGetApiKey $env:PSGALLERY_API_KEY
- name: Create GitHub Release
uses: softprops/action-gh-release@v2
with:
name: PSAliasFinder ${{ github.ref_name }}
generate_release_notes: true
files: bin/PSAliasFinder.dll
Steps to land this
- Manual setup (a) and (b) above. ~5 minutes.
- Create the workflow file in a feature branch, push, open a PR.
- Test by tagging a
0.0.0-prefixed tag on the branch — actually no, tags trigger the workflow only on default branch. To test the workflow without publishing, comment out the Publish-Module step temporarily and push a 99.99.99-test tag.
- Once the dry-run is clean, remove the comment and push a real
2.0.2 tag (next time there's something to release).
- Update README to mention the attestation: add a "Verifying the build" section pointing at
gh attestation verify.
References
Out of scope
- Authenticode code signing (separate higher-cost path; Microsoft Trusted Signing or a commercial cert from DigiCert/Sectigo). Could be added later if a corporate user requests it.
- Sigstore signing (emerging, not yet integrated with PSGallery verification).
- Strong-name signing the assembly (legacy .NET concept; not relevant for this module).
Why
PSAliasFinder ships as a binary module (compiled .NET 8 DLL). For users with supply-chain hygiene, that's an opaque artifact published by a relatively unknown maintainer — they can't easily verify what the DLL does or that it matches the source on this repo.
Mitigation: move the build + publish to GitHub Actions and emit a build provenance attestation so anyone can verify cryptographically that the DLL on the PowerShell Gallery was produced by Actions on this repo at a specific tagged commit. Also moves the PSGallery API key off the maintainer's local machine into a GitHub Secret, removing a manual-handling failure mode.
Outcome
2.0.2triggers a workflow that:build.ps1.src/, notests/, no demo gif).One-time setup (manual, before the workflow runs)
a) Generate a scoped PSGallery API key
PSAliasFinder-CIPush only new package versions of existing packages(sufficient because 2.0.x is already published; new keys can also pickPush new packages and package versionsif needed).PSAliasFinder(limits the key to this module).b) Add the key as a repo secret
PSGALLERY_API_KEYWorkflow file
Save as
.github/workflows/release.yml:Steps to land this
0.0.0-prefixed tag on the branch — actually no, tags trigger the workflow only on default branch. To test the workflow without publishing, comment out thePublish-Modulestep temporarily and push a99.99.99-testtag.2.0.2tag (next time there's something to release).gh attestation verify.References
gh attestation verifymanual — verification command reference.Publish-Modulereference — PSGallery publish cmdlet.PSGALLERY_API_KEYsecret lives.Out of scope