feat(release): sign Windows artifacts with Azure - #141

Open
SunkenInTime wants to merge 1 commit into
mainfrom
codex/windows-artifact-signing
Open

feat(release): sign Windows artifacts with Azure#141
SunkenInTime wants to merge 1 commit into
mainfrom
codex/windows-artifact-signing

Conversation

@SunkenInTime

@SunkenInTimeSunkenInTime commented Aug 30, 2026

Copy link
Copy Markdown
Owner

Summary

  • authenticate GitHub Actions to Azure through OIDC
  • sign the Windows app, bundled FFmpeg/runtime DLLs, and installer with Artifact Signing
  • hash the updater archive only after signing, then verify every Authenticode signature before publication
  • parse all release PowerShell scripts in Windows CI

Verification

  • workflow YAML parsing and release-step ordering checks pass locally
  • fvm flutter analyze --no-fatal-infos passes with one pre-existing deprecation info
  • Windows CI analysis and PowerShell parsing pass
  • Windows CI reaches 429 passing tests and 1 skipped test; its two failures are the same migration-version assertions already failing on current main: https://github.com/SunkenInTime/icarus/actions/runs/31983055496

The release workflow is intentionally restricted to manual dispatches from main, matching the federated credential.

@coderabbitai

coderabbitaiBot commented Aug 30, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 02bd000a-b45a-4184-bc54-67c21ae580a6

📥 Commits

Reviewing files that changed from the base of the PR and between d7354a4 and 366c9fb.

📒 Files selected for processing (4)
  • .github/workflows/ci.yml
  • .github/workflows/release-desktop.yml
  • scripts/build_desktop_release.ps1
  • scripts/release_desktop.ps1

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

The desktop release now uses separate build, package, and stage phases. The workflow signs Windows binaries and the installer with Azure-based Authenticode signing, verifies signatures, and publishes only from main. CI validates PowerShell syntax.

Changes

Desktop release pipeline

Layer / File(s)Summary
Phase-aware release scripts
scripts/build_desktop_release.ps1, scripts/release_desktop.ps1
The scripts support all, build, package, and stage phases. Package validation checks archives, FFmpeg hashes, and size limits. Staging requires the signed installer and copies it to release paths.
Signed Windows release workflow
.github/workflows/release-desktop.yml
The workflow enforces the main branch, authenticates with Azure OIDC, signs release files and the installer, verifies Authenticode signatures, and runs phased release commands.
PowerShell script validation
.github/workflows/ci.yml
CI parses PowerShell files under scripts and installer and fails when parse errors exist.

Estimated code review effort: 4 (Complex) | ~45 minutes

Merge Risk:⚪ Minimal · up to 366c9

The release changes are merge-ready after normal checks and review; no actionable merge-blocking risk remains.

Sequence Diagram(s)

sequenceDiagram
participant GitHubActions
participant release_desktop.ps1
participant AzureOIDC
participant ArtifactSigning
participant AuthenticodeVerification
GitHubActions->>release_desktop.ps1: Run build phase
GitHubActions->>AzureOIDC: Authenticate with OIDC
GitHubActions->>ArtifactSigning: Sign release binaries
GitHubActions->>release_desktop.ps1: Run package phase
GitHubActions->>ArtifactSigning: Sign installer
GitHubActions->>AuthenticodeVerification: Verify signatures
GitHubActions->>release_desktop.ps1: Run stage phase
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check nameStatusExplanation
Docstring Coverage✅ PassedNo functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 0…
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title clearly and concisely describes the primary change: signing Windows release artifacts with Azure Artifact Signing.
Full details: Docstring Coverage

Explanation

No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 0 files. (4 skipped: 4 unsupported.)

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/windows-artifact-signing

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@greptile-apps

greptile-appsBot commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This change adds Azure OIDC-based signing to the Windows desktop release workflow. Release executables and DLLs are signed before updater hashes are generated, installers are signed and checked before the workflow publishes them, and releases started from non-main branches stop before Azure login.

The hosted release path has the intended protections, but the local prerelease publishing script can still publish an installer without Azure signing or Authenticode validation.

T-Rex validation blocked

Live Windows signing and Authenticode verification could not run because the environment is missing the Windows runner service and Windows PowerShell/Authenticode tools. Control-flow and ordering checks were executed instead. Configure VMs

Confidence Score: 4/5

The hosted Windows release workflow is protected, but the local prerelease publishing route can expose an unsigned installer.

Executable ordering and cross-script reachability checks verified all investigated release paths. Native Windows signing and Authenticode validation could not run without a Windows environment, but the local publication bypass is directly established by the release scripts.

Files Needing Attention: scripts/publish_prerelease_local.ps1, scripts/release_desktop.ps1, and scripts/build_desktop_release.ps1 need a mandatory signing-validation gate or publication restriction.

Security Review

Do not merge until local prerelease publication is protected. scripts/publish_prerelease_local.ps1 enables Pages publication through the shared PowerShell release path, which does not perform Azure signing or validate Authenticode status before placing the installer in the public prerelease downloads location. The GitHub-hosted release workflow correctly signs release binaries before packaging, rejects invalid signatures before publication, and blocks non-main runs before Azure login.

T-Rex T-Rex Logs

What T-Rex did

  • T-Rex compared the former archive path with the changed workflow and verified that release-binary signing occurs before package creation and that the signed release snapshot is copied before updater hashes are generated.
  • T-Rex compared the former direct publication route with the changed workflow and performed a workflow control-flow assertion that binary and installer signing precede signature rejection and publication; a live Authenticode check could not run because Windows PowerShell and Windows artifacts are unavailable in this environment.
  • T-Rex compared the main-branch baseline workflow with the changed branch gate and executed the non-main dispatch predicate for refs/heads/release-candidate; the predicate fails before Azure login and before either signing action can run.
  • T-Rex described the release flow changes, noting that the Sign Windows Release Binaries step precedes the Build Signed Updater Archive And Installer step and that the Release snapshot is copied before updater hash generation; the after-check confirmed these two ordering truths.
  • T-Rex captured the Windows signing gate runtime blocker logs and related excerpts and produced proofs for posted P1 findings (see review comments).

View all artifacts

T-Rex Ran code and verified through T-Rex

Comments Outside Diff (2)

  1. scripts/publish_prerelease_local.ps1, line 15-35 (link)

    P1securityLocal prerelease publisher bypasses signing verification

    The local prerelease entry point enables Pages publication and reaches the shared release flow without the workflow-only Azure Artifact Signing actions or Get-AuthenticodeSignature check. The shared build path only checks that the installer exists before copying it into the publishable downloads directory, so an unsigned installer can be force-published to the public prerelease channel.

    T-Rex Ran code and verified through T-Rex

  2. General comment

    P1Local prerelease publisher bypasses Azure signing and Authenticode verification

    • Bug
      • Running scripts/publish_prerelease_local.ps1 invokes the full desktop release flow with Pages publishing enabled. It can build an installer, stage it, and force-push downloads/windows/prerelease to GitHub Pages without passing through the workflow-only Azure signing actions or the workflow-only Get-AuthenticodeSignature verification. This allows an unsigned installer to be publicly published to the prerelease channel.
    • Cause
      • Signing and verification were added exclusively to .github/workflows/release-desktop.yml:85-163. The reusable/local PowerShell release path has no equivalent signing or validation gate: scripts/publish_prerelease_local.ps1:15-35 forces publication, scripts/release_desktop.ps1:83-124 invokes the build and publisher, and scripts/build_desktop_release.ps1:207-231 tests only installer presence before copying it to publishable paths.
    • Fix
      • Restrict publication to the signed GitHub Actions workflow, or add a mandatory signature-validation gate to the shared PowerShell release flow immediately before staging/copying the installer and before publish_pages_branch.ps1 is invoked. The gate must fail when every publishable EXE does not have Authenticode status Valid.

    T-Rex Ran code and verified through T-Rex

Reviews (1): Last reviewed commit: "feat(release): sign Windows artifacts wi..." | Re-trigger Greptile

Sign up for freeto 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.

1 participant

@SunkenInTime
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

feat(release): sign Windows artifacts with Azure - #141

Open
SunkenInTime wants to merge 1 commit into
mainfrom
codex/windows-artifact-signing
Open

feat(release): sign Windows artifacts with Azure#141
SunkenInTime wants to merge 1 commit into
mainfrom
codex/windows-artifact-signing

Conversation

@SunkenInTime

@SunkenInTimeSunkenInTime commented Aug 30, 2026

Copy link
Copy Markdown
Owner

Summary

  • authenticate GitHub Actions to Azure through OIDC
  • sign the Windows app, bundled FFmpeg/runtime DLLs, and installer with Artifact Signing
  • hash the updater archive only after signing, then verify every Authenticode signature before publication
  • parse all release PowerShell scripts in Windows CI

Verification

  • workflow YAML parsing and release-step ordering checks pass locally
  • fvm flutter analyze --no-fatal-infos passes with one pre-existing deprecation info
  • Windows CI analysis and PowerShell parsing pass
  • Windows CI reaches 429 passing tests and 1 skipped test; its two failures are the same migration-version assertions already failing on current main: https://github.com/SunkenInTime/icarus/actions/runs/31983055496

The release workflow is intentionally restricted to manual dispatches from main, matching the federated credential.

@coderabbitai

coderabbitaiBot commented Aug 30, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 02bd000a-b45a-4184-bc54-67c21ae580a6

📥 Commits

Reviewing files that changed from the base of the PR and between d7354a4 and 366c9fb.

📒 Files selected for processing (4)
  • .github/workflows/ci.yml
  • .github/workflows/release-desktop.yml
  • scripts/build_desktop_release.ps1
  • scripts/release_desktop.ps1

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

The desktop release now uses separate build, package, and stage phases. The workflow signs Windows binaries and the installer with Azure-based Authenticode signing, verifies signatures, and publishes only from main. CI validates PowerShell syntax.

Changes

Desktop release pipeline

Layer / File(s)Summary
Phase-aware release scripts
scripts/build_desktop_release.ps1, scripts/release_desktop.ps1
The scripts support all, build, package, and stage phases. Package validation checks archives, FFmpeg hashes, and size limits. Staging requires the signed installer and copies it to release paths.
Signed Windows release workflow
.github/workflows/release-desktop.yml
The workflow enforces the main branch, authenticates with Azure OIDC, signs release files and the installer, verifies Authenticode signatures, and runs phased release commands.
PowerShell script validation
.github/workflows/ci.yml
CI parses PowerShell files under scripts and installer and fails when parse errors exist.

Estimated code review effort: 4 (Complex) | ~45 minutes

Merge Risk:⚪ Minimal · up to 366c9

The release changes are merge-ready after normal checks and review; no actionable merge-blocking risk remains.

Sequence Diagram(s)

sequenceDiagram
participant GitHubActions
participant release_desktop.ps1
participant AzureOIDC
participant ArtifactSigning
participant AuthenticodeVerification
GitHubActions->>release_desktop.ps1: Run build phase
GitHubActions->>AzureOIDC: Authenticate with OIDC
GitHubActions->>ArtifactSigning: Sign release binaries
GitHubActions->>release_desktop.ps1: Run package phase
GitHubActions->>ArtifactSigning: Sign installer
GitHubActions->>AuthenticodeVerification: Verify signatures
GitHubActions->>release_desktop.ps1: Run stage phase
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check nameStatusExplanation
Docstring Coverage✅ PassedNo functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 0…
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title clearly and concisely describes the primary change: signing Windows release artifacts with Azure Artifact Signing.
Full details: Docstring Coverage

Explanation

No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 0 files. (4 skipped: 4 unsupported.)

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/windows-artifact-signing

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@greptile-apps

greptile-appsBot commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This change adds Azure OIDC-based signing to the Windows desktop release workflow. Release executables and DLLs are signed before updater hashes are generated, installers are signed and checked before the workflow publishes them, and releases started from non-main branches stop before Azure login.

The hosted release path has the intended protections, but the local prerelease publishing script can still publish an installer without Azure signing or Authenticode validation.

T-Rex validation blocked

Live Windows signing and Authenticode verification could not run because the environment is missing the Windows runner service and Windows PowerShell/Authenticode tools. Control-flow and ordering checks were executed instead. Configure VMs

Confidence Score: 4/5

The hosted Windows release workflow is protected, but the local prerelease publishing route can expose an unsigned installer.

Executable ordering and cross-script reachability checks verified all investigated release paths. Native Windows signing and Authenticode validation could not run without a Windows environment, but the local publication bypass is directly established by the release scripts.

Files Needing Attention: scripts/publish_prerelease_local.ps1, scripts/release_desktop.ps1, and scripts/build_desktop_release.ps1 need a mandatory signing-validation gate or publication restriction.

Security Review

Do not merge until local prerelease publication is protected. scripts/publish_prerelease_local.ps1 enables Pages publication through the shared PowerShell release path, which does not perform Azure signing or validate Authenticode status before placing the installer in the public prerelease downloads location. The GitHub-hosted release workflow correctly signs release binaries before packaging, rejects invalid signatures before publication, and blocks non-main runs before Azure login.

T-Rex T-Rex Logs

What T-Rex did

  • T-Rex compared the former archive path with the changed workflow and verified that release-binary signing occurs before package creation and that the signed release snapshot is copied before updater hashes are generated.
  • T-Rex compared the former direct publication route with the changed workflow and performed a workflow control-flow assertion that binary and installer signing precede signature rejection and publication; a live Authenticode check could not run because Windows PowerShell and Windows artifacts are unavailable in this environment.
  • T-Rex compared the main-branch baseline workflow with the changed branch gate and executed the non-main dispatch predicate for refs/heads/release-candidate; the predicate fails before Azure login and before either signing action can run.
  • T-Rex described the release flow changes, noting that the Sign Windows Release Binaries step precedes the Build Signed Updater Archive And Installer step and that the Release snapshot is copied before updater hash generation; the after-check confirmed these two ordering truths.
  • T-Rex captured the Windows signing gate runtime blocker logs and related excerpts and produced proofs for posted P1 findings (see review comments).

View all artifacts

T-Rex Ran code and verified through T-Rex

Comments Outside Diff (2)

  1. scripts/publish_prerelease_local.ps1, line 15-35 (link)

    P1securityLocal prerelease publisher bypasses signing verification

    The local prerelease entry point enables Pages publication and reaches the shared release flow without the workflow-only Azure Artifact Signing actions or Get-AuthenticodeSignature check. The shared build path only checks that the installer exists before copying it into the publishable downloads directory, so an unsigned installer can be force-published to the public prerelease channel.

    T-Rex Ran code and verified through T-Rex

  2. General comment

    P1Local prerelease publisher bypasses Azure signing and Authenticode verification

    • Bug
      • Running scripts/publish_prerelease_local.ps1 invokes the full desktop release flow with Pages publishing enabled. It can build an installer, stage it, and force-push downloads/windows/prerelease to GitHub Pages without passing through the workflow-only Azure signing actions or the workflow-only Get-AuthenticodeSignature verification. This allows an unsigned installer to be publicly published to the prerelease channel.
    • Cause
      • Signing and verification were added exclusively to .github/workflows/release-desktop.yml:85-163. The reusable/local PowerShell release path has no equivalent signing or validation gate: scripts/publish_prerelease_local.ps1:15-35 forces publication, scripts/release_desktop.ps1:83-124 invokes the build and publisher, and scripts/build_desktop_release.ps1:207-231 tests only installer presence before copying it to publishable paths.
    • Fix
      • Restrict publication to the signed GitHub Actions workflow, or add a mandatory signature-validation gate to the shared PowerShell release flow immediately before staging/copying the installer and before publish_pages_branch.ps1 is invoked. The gate must fail when every publishable EXE does not have Authenticode status Valid.

    T-Rex Ran code and verified through T-Rex

Reviews (1): Last reviewed commit: "feat(release): sign Windows artifacts wi..." | Re-trigger Greptile

Sign up for freeto 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.

1 participant

@SunkenInTime
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(release): sign Windows artifacts with Azure - #141

Open
SunkenInTime wants to merge 1 commit into
mainfrom
codex/windows-artifact-signing
Open

feat(release): sign Windows artifacts with Azure#141
SunkenInTime wants to merge 1 commit into
mainfrom
codex/windows-artifact-signing

Conversation

@SunkenInTime

@SunkenInTimeSunkenInTime commented Aug 30, 2026

Copy link
Copy Markdown
Owner

Summary

  • authenticate GitHub Actions to Azure through OIDC
  • sign the Windows app, bundled FFmpeg/runtime DLLs, and installer with Artifact Signing
  • hash the updater archive only after signing, then verify every Authenticode signature before publication
  • parse all release PowerShell scripts in Windows CI

Verification

  • workflow YAML parsing and release-step ordering checks pass locally
  • fvm flutter analyze --no-fatal-infos passes with one pre-existing deprecation info
  • Windows CI analysis and PowerShell parsing pass
  • Windows CI reaches 429 passing tests and 1 skipped test; its two failures are the same migration-version assertions already failing on current main: https://github.com/SunkenInTime/icarus/actions/runs/31983055496

The release workflow is intentionally restricted to manual dispatches from main, matching the federated credential.

@coderabbitai

coderabbitaiBot commented Aug 30, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 02bd000a-b45a-4184-bc54-67c21ae580a6

📥 Commits

Reviewing files that changed from the base of the PR and between d7354a4 and 366c9fb.

📒 Files selected for processing (4)
  • .github/workflows/ci.yml
  • .github/workflows/release-desktop.yml
  • scripts/build_desktop_release.ps1
  • scripts/release_desktop.ps1

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

The desktop release now uses separate build, package, and stage phases. The workflow signs Windows binaries and the installer with Azure-based Authenticode signing, verifies signatures, and publishes only from main. CI validates PowerShell syntax.

Changes

Desktop release pipeline

Layer / File(s)Summary
Phase-aware release scripts
scripts/build_desktop_release.ps1, scripts/release_desktop.ps1
The scripts support all, build, package, and stage phases. Package validation checks archives, FFmpeg hashes, and size limits. Staging requires the signed installer and copies it to release paths.
Signed Windows release workflow
.github/workflows/release-desktop.yml
The workflow enforces the main branch, authenticates with Azure OIDC, signs release files and the installer, verifies Authenticode signatures, and runs phased release commands.
PowerShell script validation
.github/workflows/ci.yml
CI parses PowerShell files under scripts and installer and fails when parse errors exist.

Estimated code review effort: 4 (Complex) | ~45 minutes

Merge Risk:⚪ Minimal · up to 366c9

The release changes are merge-ready after normal checks and review; no actionable merge-blocking risk remains.

Sequence Diagram(s)

sequenceDiagram
participant GitHubActions
participant release_desktop.ps1
participant AzureOIDC
participant ArtifactSigning
participant AuthenticodeVerification
GitHubActions->>release_desktop.ps1: Run build phase
GitHubActions->>AzureOIDC: Authenticate with OIDC
GitHubActions->>ArtifactSigning: Sign release binaries
GitHubActions->>release_desktop.ps1: Run package phase
GitHubActions->>ArtifactSigning: Sign installer
GitHubActions->>AuthenticodeVerification: Verify signatures
GitHubActions->>release_desktop.ps1: Run stage phase
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check nameStatusExplanation
Docstring Coverage✅ PassedNo functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 0…
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title clearly and concisely describes the primary change: signing Windows release artifacts with Azure Artifact Signing.
Full details: Docstring Coverage

Explanation

No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 0 files. (4 skipped: 4 unsupported.)

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/windows-artifact-signing

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@greptile-apps

greptile-appsBot commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This change adds Azure OIDC-based signing to the Windows desktop release workflow. Release executables and DLLs are signed before updater hashes are generated, installers are signed and checked before the workflow publishes them, and releases started from non-main branches stop before Azure login.

The hosted release path has the intended protections, but the local prerelease publishing script can still publish an installer without Azure signing or Authenticode validation.

T-Rex validation blocked

Live Windows signing and Authenticode verification could not run because the environment is missing the Windows runner service and Windows PowerShell/Authenticode tools. Control-flow and ordering checks were executed instead. Configure VMs

Confidence Score: 4/5

The hosted Windows release workflow is protected, but the local prerelease publishing route can expose an unsigned installer.

Executable ordering and cross-script reachability checks verified all investigated release paths. Native Windows signing and Authenticode validation could not run without a Windows environment, but the local publication bypass is directly established by the release scripts.

Files Needing Attention: scripts/publish_prerelease_local.ps1, scripts/release_desktop.ps1, and scripts/build_desktop_release.ps1 need a mandatory signing-validation gate or publication restriction.

Security Review

Do not merge until local prerelease publication is protected. scripts/publish_prerelease_local.ps1 enables Pages publication through the shared PowerShell release path, which does not perform Azure signing or validate Authenticode status before placing the installer in the public prerelease downloads location. The GitHub-hosted release workflow correctly signs release binaries before packaging, rejects invalid signatures before publication, and blocks non-main runs before Azure login.

T-Rex T-Rex Logs

What T-Rex did

  • T-Rex compared the former archive path with the changed workflow and verified that release-binary signing occurs before package creation and that the signed release snapshot is copied before updater hashes are generated.
  • T-Rex compared the former direct publication route with the changed workflow and performed a workflow control-flow assertion that binary and installer signing precede signature rejection and publication; a live Authenticode check could not run because Windows PowerShell and Windows artifacts are unavailable in this environment.
  • T-Rex compared the main-branch baseline workflow with the changed branch gate and executed the non-main dispatch predicate for refs/heads/release-candidate; the predicate fails before Azure login and before either signing action can run.
  • T-Rex described the release flow changes, noting that the Sign Windows Release Binaries step precedes the Build Signed Updater Archive And Installer step and that the Release snapshot is copied before updater hash generation; the after-check confirmed these two ordering truths.
  • T-Rex captured the Windows signing gate runtime blocker logs and related excerpts and produced proofs for posted P1 findings (see review comments).

View all artifacts

T-Rex Ran code and verified through T-Rex

Comments Outside Diff (2)

  1. scripts/publish_prerelease_local.ps1, line 15-35 (link)

    P1securityLocal prerelease publisher bypasses signing verification

    The local prerelease entry point enables Pages publication and reaches the shared release flow without the workflow-only Azure Artifact Signing actions or Get-AuthenticodeSignature check. The shared build path only checks that the installer exists before copying it into the publishable downloads directory, so an unsigned installer can be force-published to the public prerelease channel.

    T-Rex Ran code and verified through T-Rex

  2. General comment

    P1Local prerelease publisher bypasses Azure signing and Authenticode verification

    • Bug
      • Running scripts/publish_prerelease_local.ps1 invokes the full desktop release flow with Pages publishing enabled. It can build an installer, stage it, and force-push downloads/windows/prerelease to GitHub Pages without passing through the workflow-only Azure signing actions or the workflow-only Get-AuthenticodeSignature verification. This allows an unsigned installer to be publicly published to the prerelease channel.
    • Cause
      • Signing and verification were added exclusively to .github/workflows/release-desktop.yml:85-163. The reusable/local PowerShell release path has no equivalent signing or validation gate: scripts/publish_prerelease_local.ps1:15-35 forces publication, scripts/release_desktop.ps1:83-124 invokes the build and publisher, and scripts/build_desktop_release.ps1:207-231 tests only installer presence before copying it to publishable paths.
    • Fix
      • Restrict publication to the signed GitHub Actions workflow, or add a mandatory signature-validation gate to the shared PowerShell release flow immediately before staging/copying the installer and before publish_pages_branch.ps1 is invoked. The gate must fail when every publishable EXE does not have Authenticode status Valid.

    T-Rex Ran code and verified through T-Rex

Reviews (1): Last reviewed commit: "feat(release): sign Windows artifacts wi..." | Re-trigger Greptile

Sign up for freeto 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.

1 participant

@SunkenInTime
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(release): sign Windows artifacts with Azure - #141

Open
SunkenInTime wants to merge 1 commit into
mainfrom
codex/windows-artifact-signing
Open

feat(release): sign Windows artifacts with Azure#141
SunkenInTime wants to merge 1 commit into
mainfrom
codex/windows-artifact-signing

Conversation

@SunkenInTime

@SunkenInTimeSunkenInTime commented Aug 30, 2026

Copy link
Copy Markdown
Owner

Summary

  • authenticate GitHub Actions to Azure through OIDC
  • sign the Windows app, bundled FFmpeg/runtime DLLs, and installer with Artifact Signing
  • hash the updater archive only after signing, then verify every Authenticode signature before publication
  • parse all release PowerShell scripts in Windows CI

Verification

  • workflow YAML parsing and release-step ordering checks pass locally
  • fvm flutter analyze --no-fatal-infos passes with one pre-existing deprecation info
  • Windows CI analysis and PowerShell parsing pass
  • Windows CI reaches 429 passing tests and 1 skipped test; its two failures are the same migration-version assertions already failing on current main: https://github.com/SunkenInTime/icarus/actions/runs/31983055496

The release workflow is intentionally restricted to manual dispatches from main, matching the federated credential.

@coderabbitai

coderabbitaiBot commented Aug 30, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 02bd000a-b45a-4184-bc54-67c21ae580a6

📥 Commits

Reviewing files that changed from the base of the PR and between d7354a4 and 366c9fb.

📒 Files selected for processing (4)
  • .github/workflows/ci.yml
  • .github/workflows/release-desktop.yml
  • scripts/build_desktop_release.ps1
  • scripts/release_desktop.ps1

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

The desktop release now uses separate build, package, and stage phases. The workflow signs Windows binaries and the installer with Azure-based Authenticode signing, verifies signatures, and publishes only from main. CI validates PowerShell syntax.

Changes

Desktop release pipeline

Layer / File(s)Summary
Phase-aware release scripts
scripts/build_desktop_release.ps1, scripts/release_desktop.ps1
The scripts support all, build, package, and stage phases. Package validation checks archives, FFmpeg hashes, and size limits. Staging requires the signed installer and copies it to release paths.
Signed Windows release workflow
.github/workflows/release-desktop.yml
The workflow enforces the main branch, authenticates with Azure OIDC, signs release files and the installer, verifies Authenticode signatures, and runs phased release commands.
PowerShell script validation
.github/workflows/ci.yml
CI parses PowerShell files under scripts and installer and fails when parse errors exist.

Estimated code review effort: 4 (Complex) | ~45 minutes

Merge Risk:⚪ Minimal · up to 366c9

The release changes are merge-ready after normal checks and review; no actionable merge-blocking risk remains.

Sequence Diagram(s)

sequenceDiagram
participant GitHubActions
participant release_desktop.ps1
participant AzureOIDC
participant ArtifactSigning
participant AuthenticodeVerification
GitHubActions->>release_desktop.ps1: Run build phase
GitHubActions->>AzureOIDC: Authenticate with OIDC
GitHubActions->>ArtifactSigning: Sign release binaries
GitHubActions->>release_desktop.ps1: Run package phase
GitHubActions->>ArtifactSigning: Sign installer
GitHubActions->>AuthenticodeVerification: Verify signatures
GitHubActions->>release_desktop.ps1: Run stage phase
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check nameStatusExplanation
Docstring Coverage✅ PassedNo functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 0…
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title clearly and concisely describes the primary change: signing Windows release artifacts with Azure Artifact Signing.
Full details: Docstring Coverage

Explanation

No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 0 files. (4 skipped: 4 unsupported.)

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/windows-artifact-signing

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@greptile-apps

greptile-appsBot commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This change adds Azure OIDC-based signing to the Windows desktop release workflow. Release executables and DLLs are signed before updater hashes are generated, installers are signed and checked before the workflow publishes them, and releases started from non-main branches stop before Azure login.

The hosted release path has the intended protections, but the local prerelease publishing script can still publish an installer without Azure signing or Authenticode validation.

T-Rex validation blocked

Live Windows signing and Authenticode verification could not run because the environment is missing the Windows runner service and Windows PowerShell/Authenticode tools. Control-flow and ordering checks were executed instead. Configure VMs

Confidence Score: 4/5

The hosted Windows release workflow is protected, but the local prerelease publishing route can expose an unsigned installer.

Executable ordering and cross-script reachability checks verified all investigated release paths. Native Windows signing and Authenticode validation could not run without a Windows environment, but the local publication bypass is directly established by the release scripts.

Files Needing Attention: scripts/publish_prerelease_local.ps1, scripts/release_desktop.ps1, and scripts/build_desktop_release.ps1 need a mandatory signing-validation gate or publication restriction.

Security Review

Do not merge until local prerelease publication is protected. scripts/publish_prerelease_local.ps1 enables Pages publication through the shared PowerShell release path, which does not perform Azure signing or validate Authenticode status before placing the installer in the public prerelease downloads location. The GitHub-hosted release workflow correctly signs release binaries before packaging, rejects invalid signatures before publication, and blocks non-main runs before Azure login.

T-Rex T-Rex Logs

What T-Rex did

  • T-Rex compared the former archive path with the changed workflow and verified that release-binary signing occurs before package creation and that the signed release snapshot is copied before updater hashes are generated.
  • T-Rex compared the former direct publication route with the changed workflow and performed a workflow control-flow assertion that binary and installer signing precede signature rejection and publication; a live Authenticode check could not run because Windows PowerShell and Windows artifacts are unavailable in this environment.
  • T-Rex compared the main-branch baseline workflow with the changed branch gate and executed the non-main dispatch predicate for refs/heads/release-candidate; the predicate fails before Azure login and before either signing action can run.
  • T-Rex described the release flow changes, noting that the Sign Windows Release Binaries step precedes the Build Signed Updater Archive And Installer step and that the Release snapshot is copied before updater hash generation; the after-check confirmed these two ordering truths.
  • T-Rex captured the Windows signing gate runtime blocker logs and related excerpts and produced proofs for posted P1 findings (see review comments).

View all artifacts

T-Rex Ran code and verified through T-Rex

Comments Outside Diff (2)

  1. scripts/publish_prerelease_local.ps1, line 15-35 (link)

    P1securityLocal prerelease publisher bypasses signing verification

    The local prerelease entry point enables Pages publication and reaches the shared release flow without the workflow-only Azure Artifact Signing actions or Get-AuthenticodeSignature check. The shared build path only checks that the installer exists before copying it into the publishable downloads directory, so an unsigned installer can be force-published to the public prerelease channel.

    T-Rex Ran code and verified through T-Rex

  2. General comment

    P1Local prerelease publisher bypasses Azure signing and Authenticode verification

    • Bug
      • Running scripts/publish_prerelease_local.ps1 invokes the full desktop release flow with Pages publishing enabled. It can build an installer, stage it, and force-push downloads/windows/prerelease to GitHub Pages without passing through the workflow-only Azure signing actions or the workflow-only Get-AuthenticodeSignature verification. This allows an unsigned installer to be publicly published to the prerelease channel.
    • Cause
      • Signing and verification were added exclusively to .github/workflows/release-desktop.yml:85-163. The reusable/local PowerShell release path has no equivalent signing or validation gate: scripts/publish_prerelease_local.ps1:15-35 forces publication, scripts/release_desktop.ps1:83-124 invokes the build and publisher, and scripts/build_desktop_release.ps1:207-231 tests only installer presence before copying it to publishable paths.
    • Fix
      • Restrict publication to the signed GitHub Actions workflow, or add a mandatory signature-validation gate to the shared PowerShell release flow immediately before staging/copying the installer and before publish_pages_branch.ps1 is invoked. The gate must fail when every publishable EXE does not have Authenticode status Valid.

    T-Rex Ran code and verified through T-Rex

Reviews (1): Last reviewed commit: "feat(release): sign Windows artifacts wi..." | Re-trigger Greptile

Sign up for freeto 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.

1 participant

@SunkenInTime
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

feat(release): sign Windows artifacts with Azure - #141

Open
SunkenInTime wants to merge 1 commit into
mainfrom
codex/windows-artifact-signing
Open

feat(release): sign Windows artifacts with Azure#141
SunkenInTime wants to merge 1 commit into
mainfrom
codex/windows-artifact-signing

Conversation

@SunkenInTime

@SunkenInTimeSunkenInTime commented Aug 30, 2026

Copy link
Copy Markdown
Owner

Summary

  • authenticate GitHub Actions to Azure through OIDC
  • sign the Windows app, bundled FFmpeg/runtime DLLs, and installer with Artifact Signing
  • hash the updater archive only after signing, then verify every Authenticode signature before publication
  • parse all release PowerShell scripts in Windows CI

Verification

  • workflow YAML parsing and release-step ordering checks pass locally
  • fvm flutter analyze --no-fatal-infos passes with one pre-existing deprecation info
  • Windows CI analysis and PowerShell parsing pass
  • Windows CI reaches 429 passing tests and 1 skipped test; its two failures are the same migration-version assertions already failing on current main: https://github.com/SunkenInTime/icarus/actions/runs/31983055496

The release workflow is intentionally restricted to manual dispatches from main, matching the federated credential.

@coderabbitai

coderabbitaiBot commented Aug 30, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 02bd000a-b45a-4184-bc54-67c21ae580a6

📥 Commits

Reviewing files that changed from the base of the PR and between d7354a4 and 366c9fb.

📒 Files selected for processing (4)
  • .github/workflows/ci.yml
  • .github/workflows/release-desktop.yml
  • scripts/build_desktop_release.ps1
  • scripts/release_desktop.ps1

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

The desktop release now uses separate build, package, and stage phases. The workflow signs Windows binaries and the installer with Azure-based Authenticode signing, verifies signatures, and publishes only from main. CI validates PowerShell syntax.

Changes

Desktop release pipeline

Layer / File(s)Summary
Phase-aware release scripts
scripts/build_desktop_release.ps1, scripts/release_desktop.ps1
The scripts support all, build, package, and stage phases. Package validation checks archives, FFmpeg hashes, and size limits. Staging requires the signed installer and copies it to release paths.
Signed Windows release workflow
.github/workflows/release-desktop.yml
The workflow enforces the main branch, authenticates with Azure OIDC, signs release files and the installer, verifies Authenticode signatures, and runs phased release commands.
PowerShell script validation
.github/workflows/ci.yml
CI parses PowerShell files under scripts and installer and fails when parse errors exist.

Estimated code review effort: 4 (Complex) | ~45 minutes

Merge Risk:⚪ Minimal · up to 366c9

The release changes are merge-ready after normal checks and review; no actionable merge-blocking risk remains.

Sequence Diagram(s)

sequenceDiagram
participant GitHubActions
participant release_desktop.ps1
participant AzureOIDC
participant ArtifactSigning
participant AuthenticodeVerification
GitHubActions->>release_desktop.ps1: Run build phase
GitHubActions->>AzureOIDC: Authenticate with OIDC
GitHubActions->>ArtifactSigning: Sign release binaries
GitHubActions->>release_desktop.ps1: Run package phase
GitHubActions->>ArtifactSigning: Sign installer
GitHubActions->>AuthenticodeVerification: Verify signatures
GitHubActions->>release_desktop.ps1: Run stage phase
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check nameStatusExplanation
Docstring Coverage✅ PassedNo functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 0…
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title clearly and concisely describes the primary change: signing Windows release artifacts with Azure Artifact Signing.
Full details: Docstring Coverage

Explanation

No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 0 files. (4 skipped: 4 unsupported.)

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/windows-artifact-signing

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@greptile-apps

greptile-appsBot commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This change adds Azure OIDC-based signing to the Windows desktop release workflow. Release executables and DLLs are signed before updater hashes are generated, installers are signed and checked before the workflow publishes them, and releases started from non-main branches stop before Azure login.

The hosted release path has the intended protections, but the local prerelease publishing script can still publish an installer without Azure signing or Authenticode validation.

T-Rex validation blocked

Live Windows signing and Authenticode verification could not run because the environment is missing the Windows runner service and Windows PowerShell/Authenticode tools. Control-flow and ordering checks were executed instead. Configure VMs

Confidence Score: 4/5

The hosted Windows release workflow is protected, but the local prerelease publishing route can expose an unsigned installer.

Executable ordering and cross-script reachability checks verified all investigated release paths. Native Windows signing and Authenticode validation could not run without a Windows environment, but the local publication bypass is directly established by the release scripts.

Files Needing Attention: scripts/publish_prerelease_local.ps1, scripts/release_desktop.ps1, and scripts/build_desktop_release.ps1 need a mandatory signing-validation gate or publication restriction.

Security Review

Do not merge until local prerelease publication is protected. scripts/publish_prerelease_local.ps1 enables Pages publication through the shared PowerShell release path, which does not perform Azure signing or validate Authenticode status before placing the installer in the public prerelease downloads location. The GitHub-hosted release workflow correctly signs release binaries before packaging, rejects invalid signatures before publication, and blocks non-main runs before Azure login.

T-Rex T-Rex Logs

What T-Rex did

  • T-Rex compared the former archive path with the changed workflow and verified that release-binary signing occurs before package creation and that the signed release snapshot is copied before updater hashes are generated.
  • T-Rex compared the former direct publication route with the changed workflow and performed a workflow control-flow assertion that binary and installer signing precede signature rejection and publication; a live Authenticode check could not run because Windows PowerShell and Windows artifacts are unavailable in this environment.
  • T-Rex compared the main-branch baseline workflow with the changed branch gate and executed the non-main dispatch predicate for refs/heads/release-candidate; the predicate fails before Azure login and before either signing action can run.
  • T-Rex described the release flow changes, noting that the Sign Windows Release Binaries step precedes the Build Signed Updater Archive And Installer step and that the Release snapshot is copied before updater hash generation; the after-check confirmed these two ordering truths.
  • T-Rex captured the Windows signing gate runtime blocker logs and related excerpts and produced proofs for posted P1 findings (see review comments).

View all artifacts

T-Rex Ran code and verified through T-Rex

Comments Outside Diff (2)

  1. scripts/publish_prerelease_local.ps1, line 15-35 (link)

    P1securityLocal prerelease publisher bypasses signing verification

    The local prerelease entry point enables Pages publication and reaches the shared release flow without the workflow-only Azure Artifact Signing actions or Get-AuthenticodeSignature check. The shared build path only checks that the installer exists before copying it into the publishable downloads directory, so an unsigned installer can be force-published to the public prerelease channel.

    T-Rex Ran code and verified through T-Rex

  2. General comment

    P1Local prerelease publisher bypasses Azure signing and Authenticode verification

    • Bug
      • Running scripts/publish_prerelease_local.ps1 invokes the full desktop release flow with Pages publishing enabled. It can build an installer, stage it, and force-push downloads/windows/prerelease to GitHub Pages without passing through the workflow-only Azure signing actions or the workflow-only Get-AuthenticodeSignature verification. This allows an unsigned installer to be publicly published to the prerelease channel.
    • Cause
      • Signing and verification were added exclusively to .github/workflows/release-desktop.yml:85-163. The reusable/local PowerShell release path has no equivalent signing or validation gate: scripts/publish_prerelease_local.ps1:15-35 forces publication, scripts/release_desktop.ps1:83-124 invokes the build and publisher, and scripts/build_desktop_release.ps1:207-231 tests only installer presence before copying it to publishable paths.
    • Fix
      • Restrict publication to the signed GitHub Actions workflow, or add a mandatory signature-validation gate to the shared PowerShell release flow immediately before staging/copying the installer and before publish_pages_branch.ps1 is invoked. The gate must fail when every publishable EXE does not have Authenticode status Valid.

    T-Rex Ran code and verified through T-Rex

Reviews (1): Last reviewed commit: "feat(release): sign Windows artifacts wi..." | Re-trigger Greptile

Sign up for freeto 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.

1 participant

@SunkenInTime
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(release): sign Windows artifacts with Azure - #141

Open
SunkenInTime wants to merge 1 commit into
mainfrom
codex/windows-artifact-signing
Open

feat(release): sign Windows artifacts with Azure#141
SunkenInTime wants to merge 1 commit into
mainfrom
codex/windows-artifact-signing

Conversation

@SunkenInTime

@SunkenInTimeSunkenInTime commented Aug 30, 2026

Copy link
Copy Markdown
Owner

Summary

  • authenticate GitHub Actions to Azure through OIDC
  • sign the Windows app, bundled FFmpeg/runtime DLLs, and installer with Artifact Signing
  • hash the updater archive only after signing, then verify every Authenticode signature before publication
  • parse all release PowerShell scripts in Windows CI

Verification

  • workflow YAML parsing and release-step ordering checks pass locally
  • fvm flutter analyze --no-fatal-infos passes with one pre-existing deprecation info
  • Windows CI analysis and PowerShell parsing pass
  • Windows CI reaches 429 passing tests and 1 skipped test; its two failures are the same migration-version assertions already failing on current main: https://github.com/SunkenInTime/icarus/actions/runs/31983055496

The release workflow is intentionally restricted to manual dispatches from main, matching the federated credential.

@coderabbitai

coderabbitaiBot commented Aug 30, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 02bd000a-b45a-4184-bc54-67c21ae580a6

📥 Commits

Reviewing files that changed from the base of the PR and between d7354a4 and 366c9fb.

📒 Files selected for processing (4)
  • .github/workflows/ci.yml
  • .github/workflows/release-desktop.yml
  • scripts/build_desktop_release.ps1
  • scripts/release_desktop.ps1

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

The desktop release now uses separate build, package, and stage phases. The workflow signs Windows binaries and the installer with Azure-based Authenticode signing, verifies signatures, and publishes only from main. CI validates PowerShell syntax.

Changes

Desktop release pipeline

Layer / File(s)Summary
Phase-aware release scripts
scripts/build_desktop_release.ps1, scripts/release_desktop.ps1
The scripts support all, build, package, and stage phases. Package validation checks archives, FFmpeg hashes, and size limits. Staging requires the signed installer and copies it to release paths.
Signed Windows release workflow
.github/workflows/release-desktop.yml
The workflow enforces the main branch, authenticates with Azure OIDC, signs release files and the installer, verifies Authenticode signatures, and runs phased release commands.
PowerShell script validation
.github/workflows/ci.yml
CI parses PowerShell files under scripts and installer and fails when parse errors exist.

Estimated code review effort: 4 (Complex) | ~45 minutes

Merge Risk:⚪ Minimal · up to 366c9

The release changes are merge-ready after normal checks and review; no actionable merge-blocking risk remains.

Sequence Diagram(s)

sequenceDiagram
participant GitHubActions
participant release_desktop.ps1
participant AzureOIDC
participant ArtifactSigning
participant AuthenticodeVerification
GitHubActions->>release_desktop.ps1: Run build phase
GitHubActions->>AzureOIDC: Authenticate with OIDC
GitHubActions->>ArtifactSigning: Sign release binaries
GitHubActions->>release_desktop.ps1: Run package phase
GitHubActions->>ArtifactSigning: Sign installer
GitHubActions->>AuthenticodeVerification: Verify signatures
GitHubActions->>release_desktop.ps1: Run stage phase
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check nameStatusExplanation
Docstring Coverage✅ PassedNo functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 0…
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title clearly and concisely describes the primary change: signing Windows release artifacts with Azure Artifact Signing.
Full details: Docstring Coverage

Explanation

No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 0 files. (4 skipped: 4 unsupported.)

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/windows-artifact-signing

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@greptile-apps

greptile-appsBot commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This change adds Azure OIDC-based signing to the Windows desktop release workflow. Release executables and DLLs are signed before updater hashes are generated, installers are signed and checked before the workflow publishes them, and releases started from non-main branches stop before Azure login.

The hosted release path has the intended protections, but the local prerelease publishing script can still publish an installer without Azure signing or Authenticode validation.

T-Rex validation blocked

Live Windows signing and Authenticode verification could not run because the environment is missing the Windows runner service and Windows PowerShell/Authenticode tools. Control-flow and ordering checks were executed instead. Configure VMs

Confidence Score: 4/5

The hosted Windows release workflow is protected, but the local prerelease publishing route can expose an unsigned installer.

Executable ordering and cross-script reachability checks verified all investigated release paths. Native Windows signing and Authenticode validation could not run without a Windows environment, but the local publication bypass is directly established by the release scripts.

Files Needing Attention: scripts/publish_prerelease_local.ps1, scripts/release_desktop.ps1, and scripts/build_desktop_release.ps1 need a mandatory signing-validation gate or publication restriction.

Security Review

Do not merge until local prerelease publication is protected. scripts/publish_prerelease_local.ps1 enables Pages publication through the shared PowerShell release path, which does not perform Azure signing or validate Authenticode status before placing the installer in the public prerelease downloads location. The GitHub-hosted release workflow correctly signs release binaries before packaging, rejects invalid signatures before publication, and blocks non-main runs before Azure login.

T-Rex T-Rex Logs

What T-Rex did

  • T-Rex compared the former archive path with the changed workflow and verified that release-binary signing occurs before package creation and that the signed release snapshot is copied before updater hashes are generated.
  • T-Rex compared the former direct publication route with the changed workflow and performed a workflow control-flow assertion that binary and installer signing precede signature rejection and publication; a live Authenticode check could not run because Windows PowerShell and Windows artifacts are unavailable in this environment.
  • T-Rex compared the main-branch baseline workflow with the changed branch gate and executed the non-main dispatch predicate for refs/heads/release-candidate; the predicate fails before Azure login and before either signing action can run.
  • T-Rex described the release flow changes, noting that the Sign Windows Release Binaries step precedes the Build Signed Updater Archive And Installer step and that the Release snapshot is copied before updater hash generation; the after-check confirmed these two ordering truths.
  • T-Rex captured the Windows signing gate runtime blocker logs and related excerpts and produced proofs for posted P1 findings (see review comments).

View all artifacts

T-Rex Ran code and verified through T-Rex

Comments Outside Diff (2)

  1. scripts/publish_prerelease_local.ps1, line 15-35 (link)

    P1securityLocal prerelease publisher bypasses signing verification

    The local prerelease entry point enables Pages publication and reaches the shared release flow without the workflow-only Azure Artifact Signing actions or Get-AuthenticodeSignature check. The shared build path only checks that the installer exists before copying it into the publishable downloads directory, so an unsigned installer can be force-published to the public prerelease channel.

    T-Rex Ran code and verified through T-Rex

  2. General comment

    P1Local prerelease publisher bypasses Azure signing and Authenticode verification

    • Bug
      • Running scripts/publish_prerelease_local.ps1 invokes the full desktop release flow with Pages publishing enabled. It can build an installer, stage it, and force-push downloads/windows/prerelease to GitHub Pages without passing through the workflow-only Azure signing actions or the workflow-only Get-AuthenticodeSignature verification. This allows an unsigned installer to be publicly published to the prerelease channel.
    • Cause
      • Signing and verification were added exclusively to .github/workflows/release-desktop.yml:85-163. The reusable/local PowerShell release path has no equivalent signing or validation gate: scripts/publish_prerelease_local.ps1:15-35 forces publication, scripts/release_desktop.ps1:83-124 invokes the build and publisher, and scripts/build_desktop_release.ps1:207-231 tests only installer presence before copying it to publishable paths.
    • Fix
      • Restrict publication to the signed GitHub Actions workflow, or add a mandatory signature-validation gate to the shared PowerShell release flow immediately before staging/copying the installer and before publish_pages_branch.ps1 is invoked. The gate must fail when every publishable EXE does not have Authenticode status Valid.

    T-Rex Ran code and verified through T-Rex

Reviews (1): Last reviewed commit: "feat(release): sign Windows artifacts wi..." | Re-trigger Greptile

Sign up for freeto 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.

1 participant

@SunkenInTime
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(release): sign Windows artifacts with Azure - #141

Open
SunkenInTime wants to merge 1 commit into
mainfrom
codex/windows-artifact-signing
Open

feat(release): sign Windows artifacts with Azure#141
SunkenInTime wants to merge 1 commit into
mainfrom
codex/windows-artifact-signing

Conversation

@SunkenInTime

@SunkenInTimeSunkenInTime commented Aug 30, 2026

Copy link
Copy Markdown
Owner

Summary

  • authenticate GitHub Actions to Azure through OIDC
  • sign the Windows app, bundled FFmpeg/runtime DLLs, and installer with Artifact Signing
  • hash the updater archive only after signing, then verify every Authenticode signature before publication
  • parse all release PowerShell scripts in Windows CI

Verification

  • workflow YAML parsing and release-step ordering checks pass locally
  • fvm flutter analyze --no-fatal-infos passes with one pre-existing deprecation info
  • Windows CI analysis and PowerShell parsing pass
  • Windows CI reaches 429 passing tests and 1 skipped test; its two failures are the same migration-version assertions already failing on current main: https://github.com/SunkenInTime/icarus/actions/runs/31983055496

The release workflow is intentionally restricted to manual dispatches from main, matching the federated credential.

@coderabbitai

coderabbitaiBot commented Aug 30, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 02bd000a-b45a-4184-bc54-67c21ae580a6

📥 Commits

Reviewing files that changed from the base of the PR and between d7354a4 and 366c9fb.

📒 Files selected for processing (4)
  • .github/workflows/ci.yml
  • .github/workflows/release-desktop.yml
  • scripts/build_desktop_release.ps1
  • scripts/release_desktop.ps1

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

The desktop release now uses separate build, package, and stage phases. The workflow signs Windows binaries and the installer with Azure-based Authenticode signing, verifies signatures, and publishes only from main. CI validates PowerShell syntax.

Changes

Desktop release pipeline

Layer / File(s)Summary
Phase-aware release scripts
scripts/build_desktop_release.ps1, scripts/release_desktop.ps1
The scripts support all, build, package, and stage phases. Package validation checks archives, FFmpeg hashes, and size limits. Staging requires the signed installer and copies it to release paths.
Signed Windows release workflow
.github/workflows/release-desktop.yml
The workflow enforces the main branch, authenticates with Azure OIDC, signs release files and the installer, verifies Authenticode signatures, and runs phased release commands.
PowerShell script validation
.github/workflows/ci.yml
CI parses PowerShell files under scripts and installer and fails when parse errors exist.

Estimated code review effort: 4 (Complex) | ~45 minutes

Merge Risk:⚪ Minimal · up to 366c9

The release changes are merge-ready after normal checks and review; no actionable merge-blocking risk remains.

Sequence Diagram(s)

sequenceDiagram
participant GitHubActions
participant release_desktop.ps1
participant AzureOIDC
participant ArtifactSigning
participant AuthenticodeVerification
GitHubActions->>release_desktop.ps1: Run build phase
GitHubActions->>AzureOIDC: Authenticate with OIDC
GitHubActions->>ArtifactSigning: Sign release binaries
GitHubActions->>release_desktop.ps1: Run package phase
GitHubActions->>ArtifactSigning: Sign installer
GitHubActions->>AuthenticodeVerification: Verify signatures
GitHubActions->>release_desktop.ps1: Run stage phase
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check nameStatusExplanation
Docstring Coverage✅ PassedNo functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 0…
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title clearly and concisely describes the primary change: signing Windows release artifacts with Azure Artifact Signing.
Full details: Docstring Coverage

Explanation

No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 0 files. (4 skipped: 4 unsupported.)

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/windows-artifact-signing

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@greptile-apps

greptile-appsBot commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This change adds Azure OIDC-based signing to the Windows desktop release workflow. Release executables and DLLs are signed before updater hashes are generated, installers are signed and checked before the workflow publishes them, and releases started from non-main branches stop before Azure login.

The hosted release path has the intended protections, but the local prerelease publishing script can still publish an installer without Azure signing or Authenticode validation.

T-Rex validation blocked

Live Windows signing and Authenticode verification could not run because the environment is missing the Windows runner service and Windows PowerShell/Authenticode tools. Control-flow and ordering checks were executed instead. Configure VMs

Confidence Score: 4/5

The hosted Windows release workflow is protected, but the local prerelease publishing route can expose an unsigned installer.

Executable ordering and cross-script reachability checks verified all investigated release paths. Native Windows signing and Authenticode validation could not run without a Windows environment, but the local publication bypass is directly established by the release scripts.

Files Needing Attention: scripts/publish_prerelease_local.ps1, scripts/release_desktop.ps1, and scripts/build_desktop_release.ps1 need a mandatory signing-validation gate or publication restriction.

Security Review

Do not merge until local prerelease publication is protected. scripts/publish_prerelease_local.ps1 enables Pages publication through the shared PowerShell release path, which does not perform Azure signing or validate Authenticode status before placing the installer in the public prerelease downloads location. The GitHub-hosted release workflow correctly signs release binaries before packaging, rejects invalid signatures before publication, and blocks non-main runs before Azure login.

T-Rex T-Rex Logs

What T-Rex did

  • T-Rex compared the former archive path with the changed workflow and verified that release-binary signing occurs before package creation and that the signed release snapshot is copied before updater hashes are generated.
  • T-Rex compared the former direct publication route with the changed workflow and performed a workflow control-flow assertion that binary and installer signing precede signature rejection and publication; a live Authenticode check could not run because Windows PowerShell and Windows artifacts are unavailable in this environment.
  • T-Rex compared the main-branch baseline workflow with the changed branch gate and executed the non-main dispatch predicate for refs/heads/release-candidate; the predicate fails before Azure login and before either signing action can run.
  • T-Rex described the release flow changes, noting that the Sign Windows Release Binaries step precedes the Build Signed Updater Archive And Installer step and that the Release snapshot is copied before updater hash generation; the after-check confirmed these two ordering truths.
  • T-Rex captured the Windows signing gate runtime blocker logs and related excerpts and produced proofs for posted P1 findings (see review comments).

View all artifacts

T-Rex Ran code and verified through T-Rex

Comments Outside Diff (2)

  1. scripts/publish_prerelease_local.ps1, line 15-35 (link)

    P1securityLocal prerelease publisher bypasses signing verification

    The local prerelease entry point enables Pages publication and reaches the shared release flow without the workflow-only Azure Artifact Signing actions or Get-AuthenticodeSignature check. The shared build path only checks that the installer exists before copying it into the publishable downloads directory, so an unsigned installer can be force-published to the public prerelease channel.

    T-Rex Ran code and verified through T-Rex

  2. General comment

    P1Local prerelease publisher bypasses Azure signing and Authenticode verification

    • Bug
      • Running scripts/publish_prerelease_local.ps1 invokes the full desktop release flow with Pages publishing enabled. It can build an installer, stage it, and force-push downloads/windows/prerelease to GitHub Pages without passing through the workflow-only Azure signing actions or the workflow-only Get-AuthenticodeSignature verification. This allows an unsigned installer to be publicly published to the prerelease channel.
    • Cause
      • Signing and verification were added exclusively to .github/workflows/release-desktop.yml:85-163. The reusable/local PowerShell release path has no equivalent signing or validation gate: scripts/publish_prerelease_local.ps1:15-35 forces publication, scripts/release_desktop.ps1:83-124 invokes the build and publisher, and scripts/build_desktop_release.ps1:207-231 tests only installer presence before copying it to publishable paths.
    • Fix
      • Restrict publication to the signed GitHub Actions workflow, or add a mandatory signature-validation gate to the shared PowerShell release flow immediately before staging/copying the installer and before publish_pages_branch.ps1 is invoked. The gate must fail when every publishable EXE does not have Authenticode status Valid.

    T-Rex Ran code and verified through T-Rex

Reviews (1): Last reviewed commit: "feat(release): sign Windows artifacts wi..." | Re-trigger Greptile

Sign up for freeto 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.

1 participant

@SunkenInTime
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

feat(release): sign Windows artifacts with Azure - #141

Open
SunkenInTime wants to merge 1 commit into
mainfrom
codex/windows-artifact-signing
Open

feat(release): sign Windows artifacts with Azure#141
SunkenInTime wants to merge 1 commit into
mainfrom
codex/windows-artifact-signing

Conversation

@SunkenInTime

@SunkenInTimeSunkenInTime commented Aug 30, 2026

Copy link
Copy Markdown
Owner

Summary

  • authenticate GitHub Actions to Azure through OIDC
  • sign the Windows app, bundled FFmpeg/runtime DLLs, and installer with Artifact Signing
  • hash the updater archive only after signing, then verify every Authenticode signature before publication
  • parse all release PowerShell scripts in Windows CI

Verification

  • workflow YAML parsing and release-step ordering checks pass locally
  • fvm flutter analyze --no-fatal-infos passes with one pre-existing deprecation info
  • Windows CI analysis and PowerShell parsing pass
  • Windows CI reaches 429 passing tests and 1 skipped test; its two failures are the same migration-version assertions already failing on current main: https://github.com/SunkenInTime/icarus/actions/runs/31983055496

The release workflow is intentionally restricted to manual dispatches from main, matching the federated credential.

@coderabbitai

coderabbitaiBot commented Aug 30, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 02bd000a-b45a-4184-bc54-67c21ae580a6

📥 Commits

Reviewing files that changed from the base of the PR and between d7354a4 and 366c9fb.

📒 Files selected for processing (4)
  • .github/workflows/ci.yml
  • .github/workflows/release-desktop.yml
  • scripts/build_desktop_release.ps1
  • scripts/release_desktop.ps1

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

The desktop release now uses separate build, package, and stage phases. The workflow signs Windows binaries and the installer with Azure-based Authenticode signing, verifies signatures, and publishes only from main. CI validates PowerShell syntax.

Changes

Desktop release pipeline

Layer / File(s)Summary
Phase-aware release scripts
scripts/build_desktop_release.ps1, scripts/release_desktop.ps1
The scripts support all, build, package, and stage phases. Package validation checks archives, FFmpeg hashes, and size limits. Staging requires the signed installer and copies it to release paths.
Signed Windows release workflow
.github/workflows/release-desktop.yml
The workflow enforces the main branch, authenticates with Azure OIDC, signs release files and the installer, verifies Authenticode signatures, and runs phased release commands.
PowerShell script validation
.github/workflows/ci.yml
CI parses PowerShell files under scripts and installer and fails when parse errors exist.

Estimated code review effort: 4 (Complex) | ~45 minutes

Merge Risk:⚪ Minimal · up to 366c9

The release changes are merge-ready after normal checks and review; no actionable merge-blocking risk remains.

Sequence Diagram(s)

sequenceDiagram
participant GitHubActions
participant release_desktop.ps1
participant AzureOIDC
participant ArtifactSigning
participant AuthenticodeVerification
GitHubActions->>release_desktop.ps1: Run build phase
GitHubActions->>AzureOIDC: Authenticate with OIDC
GitHubActions->>ArtifactSigning: Sign release binaries
GitHubActions->>release_desktop.ps1: Run package phase
GitHubActions->>ArtifactSigning: Sign installer
GitHubActions->>AuthenticodeVerification: Verify signatures
GitHubActions->>release_desktop.ps1: Run stage phase
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check nameStatusExplanation
Docstring Coverage✅ PassedNo functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 0…
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title clearly and concisely describes the primary change: signing Windows release artifacts with Azure Artifact Signing.
Full details: Docstring Coverage

Explanation

No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 0 files. (4 skipped: 4 unsupported.)

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/windows-artifact-signing

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@greptile-apps

greptile-appsBot commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This change adds Azure OIDC-based signing to the Windows desktop release workflow. Release executables and DLLs are signed before updater hashes are generated, installers are signed and checked before the workflow publishes them, and releases started from non-main branches stop before Azure login.

The hosted release path has the intended protections, but the local prerelease publishing script can still publish an installer without Azure signing or Authenticode validation.

T-Rex validation blocked

Live Windows signing and Authenticode verification could not run because the environment is missing the Windows runner service and Windows PowerShell/Authenticode tools. Control-flow and ordering checks were executed instead. Configure VMs

Confidence Score: 4/5

The hosted Windows release workflow is protected, but the local prerelease publishing route can expose an unsigned installer.

Executable ordering and cross-script reachability checks verified all investigated release paths. Native Windows signing and Authenticode validation could not run without a Windows environment, but the local publication bypass is directly established by the release scripts.

Files Needing Attention: scripts/publish_prerelease_local.ps1, scripts/release_desktop.ps1, and scripts/build_desktop_release.ps1 need a mandatory signing-validation gate or publication restriction.

Security Review

Do not merge until local prerelease publication is protected. scripts/publish_prerelease_local.ps1 enables Pages publication through the shared PowerShell release path, which does not perform Azure signing or validate Authenticode status before placing the installer in the public prerelease downloads location. The GitHub-hosted release workflow correctly signs release binaries before packaging, rejects invalid signatures before publication, and blocks non-main runs before Azure login.

T-Rex T-Rex Logs

What T-Rex did

  • T-Rex compared the former archive path with the changed workflow and verified that release-binary signing occurs before package creation and that the signed release snapshot is copied before updater hashes are generated.
  • T-Rex compared the former direct publication route with the changed workflow and performed a workflow control-flow assertion that binary and installer signing precede signature rejection and publication; a live Authenticode check could not run because Windows PowerShell and Windows artifacts are unavailable in this environment.
  • T-Rex compared the main-branch baseline workflow with the changed branch gate and executed the non-main dispatch predicate for refs/heads/release-candidate; the predicate fails before Azure login and before either signing action can run.
  • T-Rex described the release flow changes, noting that the Sign Windows Release Binaries step precedes the Build Signed Updater Archive And Installer step and that the Release snapshot is copied before updater hash generation; the after-check confirmed these two ordering truths.
  • T-Rex captured the Windows signing gate runtime blocker logs and related excerpts and produced proofs for posted P1 findings (see review comments).

View all artifacts

T-Rex Ran code and verified through T-Rex

Comments Outside Diff (2)

  1. scripts/publish_prerelease_local.ps1, line 15-35 (link)

    P1securityLocal prerelease publisher bypasses signing verification

    The local prerelease entry point enables Pages publication and reaches the shared release flow without the workflow-only Azure Artifact Signing actions or Get-AuthenticodeSignature check. The shared build path only checks that the installer exists before copying it into the publishable downloads directory, so an unsigned installer can be force-published to the public prerelease channel.

    T-Rex Ran code and verified through T-Rex

  2. General comment

    P1Local prerelease publisher bypasses Azure signing and Authenticode verification

    • Bug
      • Running scripts/publish_prerelease_local.ps1 invokes the full desktop release flow with Pages publishing enabled. It can build an installer, stage it, and force-push downloads/windows/prerelease to GitHub Pages without passing through the workflow-only Azure signing actions or the workflow-only Get-AuthenticodeSignature verification. This allows an unsigned installer to be publicly published to the prerelease channel.
    • Cause
      • Signing and verification were added exclusively to .github/workflows/release-desktop.yml:85-163. The reusable/local PowerShell release path has no equivalent signing or validation gate: scripts/publish_prerelease_local.ps1:15-35 forces publication, scripts/release_desktop.ps1:83-124 invokes the build and publisher, and scripts/build_desktop_release.ps1:207-231 tests only installer presence before copying it to publishable paths.
    • Fix
      • Restrict publication to the signed GitHub Actions workflow, or add a mandatory signature-validation gate to the shared PowerShell release flow immediately before staging/copying the installer and before publish_pages_branch.ps1 is invoked. The gate must fail when every publishable EXE does not have Authenticode status Valid.

    T-Rex Ran code and verified through T-Rex

Reviews (1): Last reviewed commit: "feat(release): sign Windows artifacts wi..." | Re-trigger Greptile

Sign up for freeto 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.

1 participant

@SunkenInTime