Skip to content

Sign the Windows slicec binary in release builds - #825

Merged
pepone merged 2 commits into
mainfrom
sign-windows-release-binary
Sep 15, 2026
Merged

pepone merged 2 commits into
mainfrom
sign-windows-release-binary

Conversation

@pepone

@pepone pepone commented Sep 14, 2026

Copy link
Copy Markdown
Member

The release workflow uploads slicec.exe to download.zeroc.com without an Authenticode signature, and IceRpc.Slice.Tools bundles it unchanged. The tools/windows-x64/slicec.exe in IceRpc.Slice.Tools 0.6.0 on nuget.org is NotSigned, while the managed assemblies in the same package carry ZeroC's signature. This was found while fixing icerpc/icerpc-csharp#4949.

This PR signs the Windows binary on the Windows build leg, before the artifact upload, with the same Trusted Signing account, certificate profile and action version as icerpc-csharp's build-packages.yml:

  • Releases (any quality other than nightly): signing is mandatory.
  • Nightly builds: signing is optional, through a new authenticode_sign input (default false) on workflow_call and workflow_dispatch. The scheduled nightly doesn't set it, so it stays unsigned. A manual nightly run can opt in.
  • Verify step: after signing, a step fails the build unless Get-AuthenticodeSignature reports Valid, so a signing problem can't lead to an unsigned binary being uploaded. The upload job needs build, so nothing is published in that case.

The signing action is pinned to a commit SHA, as in icerpc-csharp, because it receives the signing credentials.

Before merging

The AZURE_TENANT_ID, AZURE_CLIENT_ID and AZURE_CLIENT_SECRET secrets are organization secrets that are not currently shared with this repository. An org admin needs to add icerpc/slicec to their selected repositories. Until then, a non-nightly release fails at the signing step. The scheduled nightly doesn't sign, so it isn't affected.

Testing

  • actionlint 1.7.12 reports no issues.
  • The signing policy script gives true for stable and RC with any input value, false for nightly by default, and true for nightly with authenticode_sign: true.
  • The verify step's PowerShell passes on a ZeroC-signed assembly from nuget.org and fails on the unsigned 0.4.0 slicec.exe.
  • The signing step itself can only run here once the secrets are shared. A manual workflow_dispatch with quality: nightly and authenticode_sign: true exercises it without publishing a stable release.

The workflow is the same on 0.4.x, so this commit cherry-picks cleanly and a 0.4.1 release would ship a signed slicec.exe.

What's Changed

None - release pipeline change: the published Windows slicec binary is now Authenticode-signed; the compiler itself is unchanged.

slicec.exe was uploaded to download.zeroc.com unsigned, and IceRpc.Slice.Tools
bundles it as is. Sign it with Authenticode on the Windows build leg, before
the artifact upload: always for non-nightly releases, and for nightly builds
when the new authenticode_sign input is set. A follow-up step checks the
signature, so a release build fails instead of publishing an unsigned binary.
Copilot AI lite review requested due to automatic review settings September 14, 2026 10:52
@pepone pepone added this to the 0.4.1 milestone Sep 14, 2026

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔵 Needs a closer look

Release signing and publication gating depend on organization secrets and warrant final human review.

Pull request overview

Updates the release workflow to Authenticode-sign Windows slicec.exe before publication.

Changes:

  • Adds configurable signing for releases and nightly builds.
  • Verifies signatures before artifact upload.
  • Blocks publication when required signing fails.
File summaries
File Summary
.github/workflows/build-release.yml Adds signing policy, Azure Trusted Signing, verification, and release gating.
Review details
  • Files reviewed: 1/1 changed files
  • Comments generated: 0
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@InsertCreativityHere InsertCreativityHere 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.

Looks good, maybe some things could be simplified, maybe not.

One tangential ask, as someone who does test builds off their fork of slicec, could we also check github.repository == 'icerpc/slicec' so the new actions only run for our repository?

Without that, forks will always have red CI, since they can't access our secrets, and so the job would fail.

Comment thread .github/workflows/build-release.yml Resolved
Comment thread .github/workflows/build-release.yml Resolved
@pepone

pepone commented Sep 15, 2026

Copy link
Copy Markdown
Member Author

Addressed all three review suggestions in 213c3ca:

  • Removed the signing-policy step and output; signing and verification now check the full condition directly.
  • Added github.repository == 'icerpc/slicec' to both steps, so fork builds skip signing and verification even for non-nightly releases or an explicit signing opt-in.
  • Required a timestamp certificate as well as a valid signature before artifact upload.

Validation: actionlint 1.7.12 and git diff --check pass; all 36 combinations of repository, OS, release quality, and signing opt-in pass; the extracted PowerShell verification script parses and passes four mocked signature cases. Actual Azure signing was not exercised locally.

Replied to and resolved both inline review threads.

@pepone
pepone merged commit 8a8a13b into main Sep 15, 2026
7 checks passed
pepone added a commit that referenced this pull request Sep 16, 2026
@InsertCreativityHere
InsertCreativityHere deleted the sign-windows-release-binary branch September 16, 2026 14:19
pepone added a commit to icerpc/icerpc-csharp that referenced this pull request Sep 16, 2026
The release workflow can publish unsigned first-party binaries when the
signing catalog misses a file that `dotnet pack` includes, such as an
MSBuild task assembly or a dependency copied into a Tools package.

When `authenticode_sign` is enabled, inspect every produced `.nupkg`
after both packing steps and require a valid Authenticode signature on
every DLL and EXE except an explicit list of bundled third-party files.
Temporarily exempt `slicec.exe` until the bundled compiler includes
icerpc/slicec#825. Report each invalid signature with its package and
entry path, then fail before artifact upload.

Fixes #4961.

Validation: six temporary PowerShell fixture tests passed, covering
valid binaries, multiple invalid signatures across packages, exceptions,
exception path matching, missing packages, and corrupt archives.
Workflow placement, the signing condition, extraction cleanup, and `git
diff --check` also passed. Signature results were simulated on Linux;
real Authenticode validation still requires Windows CI.

## What's Changed entry

None — this adds a release packaging check with no user-facing API or
runtime change.
pepone added a commit to icerpc/icerpc-csharp that referenced this pull request Sep 16, 2026
The release workflow can publish unsigned first-party binaries when the
signing catalog misses a file that `dotnet pack` includes, such as an
MSBuild task assembly or a dependency copied into a Tools package.

When `authenticode_sign` is enabled, inspect every produced `.nupkg`
after both packing steps and require a valid Authenticode signature on
every DLL and EXE except an explicit list of bundled third-party files.
Temporarily exempt `slicec.exe` until the bundled compiler includes
icerpc/slicec#825. Report each invalid signature with its package and
entry path, then fail before artifact upload.

Fixes #4961.

Validation: six temporary PowerShell fixture tests passed, covering
valid binaries, multiple invalid signatures across packages, exceptions,
exception path matching, missing packages, and corrupt archives.
Workflow placement, the signing condition, extraction cleanup, and `git
diff --check` also passed. Signature results were simulated on Linux;
real Authenticode validation still requires Windows CI.

## What's Changed entry

None — this adds a release packaging check with no user-facing API or
runtime change.

(cherry picked from commit 5e7e7dc)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants