Skip to content

Authenticode-sign the Windows stable-diffusion.cpp prebuilts - #13

Merged
danielhanchen merged 1 commit into
masterfrom
sign-windows-prebuilts
Sep 7, 2026
Merged

Authenticode-sign the Windows stable-diffusion.cpp prebuilts#13
danielhanchen merged 1 commit into
masterfrom
sign-windows-prebuilts

Conversation

@danielhanchen

Copy link
Copy Markdown
Member

Same fix as unslothai/whisper.cpp#27 for this repo: the Windows bundle we publish here is 100% unsigned, and Windows Smart App Control evaluates every binary as it loads.

What ships today

Measured on the published asset by parsing the PE certificate table directly:

bundle PE files signed
master-813-bfbef5b-uea65600 bin-win-cpu-x64 2 0

sd-cli.exe and sd-server.exe, neither signed. VirusTotal returns 404 for both, so they are not flagged files, they are unknown files, which is what Smart App Control blocks. A block surfaces as a "Bad Image" dialog with status 0xc0e90002 naming whichever file was refused.

This bundle is fetched by Unsloth Studio after its own signed installer has already run, so it sits outside that installer's Authenticode scope. Nothing else signs it. Its only current gate is the SHA-256 manifest, which proves integrity but establishes no trust.

What this does

  • .github/actions/sign-windows (composite): gates on the Azure credentials, installs trusted-signing-cli pinned by SHA-256, verifies that the binary PATH resolves to is the digest-checked copy, then signs. On unslothai/* a missing secret is a hard error, because a skip that looks like a pass is exactly how the Defender scan in Scan Windows bundles with MpCmdRun when the Defender cmdlets are down unsloth#8358 went missing for five releases. On a fork it is a warning, since a contributor cannot fix it.
  • .github/scripts/sign-windows-tree.ps1: signs every PE in the build tree in one batched Azure round trip, retrying only genuine auth flakiness, and leaving any file that already carries a valid signature alone.
  • .github/scripts/assert-windows-bundle-signed.ps1: the release gate, run against the finished zip rather than the build tree. package_bundle.py copies files in after signing, so the zip is the only thing that proves what ships. Without this the signing regresses silently.

Signing runs before Package bundle; the gate runs after it and before the upload.

Required before this can pass

Five repository secrets, the same set unslothai/unsloth's release-desktop.yml already uses:

AZURE_CLIENT_ID
AZURE_CLIENT_SECRET
AZURE_TENANT_ID
AZURE_TRUSTED_SIGNING_ACCOUNT_NAME
AZURE_CERTIFICATE_PROFILE_NAME

TAURI_SIGNING_PRIVATE_KEY and the APPLE_* set are not needed here. build-windows declares environment: release-signing so the job that can read them is named explicitly.

Until those secrets exist, build-windows will fail at the gate step with a message saying which ones are missing. That is deliberate: assemble skips if any CPU leg fails, so nothing gets published half-signed.

How to test

gh workflow run unsloth-sd-prebuilt.yml --repo unslothai/stable-diffusion.cpp --ref sign-windows-prebuilts
gh run watch --repo unslothai/stable-diffusion.cpp

Then verify the artifact on a Windows box:

Expand-Archive sd-<tag>-bin-win-cpu-x64.zip -DestinationPath bundle
Get-ChildItem bundle -Recurse -Include *.exe,*.dll |
  ForEach-Object { Get-AuthenticodeSignature $_.FullName } |
  Format-Table Status, @{n='Signer';e={$_.SignerCertificate.Subject}}, Path

Both rows should read Valid with signer Unsloth AI Inc.. Two files is a small tree, so this leg should cost well under a minute.

Note on the license header

The scripts here carry this repository's MIT header rather than the AGPL header they have in unslothai/llama.cpp, matching scripts/unsloth/package_bundle.py.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for security reviews. Please try again later.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 7, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-07T04:36:46.946829Z fc81df7 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: fc81df7c59

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

# The gate, run on the finished zip rather than the build tree: packaging
# copies files in after signing, so the zip is the only thing that proves
# what ships.
- name: Verify every PE in the bundle is signed

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Skip verification when fork signing is skipped

On a fork without Azure secrets, the composite action deliberately returns signed=false and leaves the binaries unsigned, but this verification step still runs unconditionally and rejects that bundle. Consequently, every manually dispatched or scheduled fork build fails before artifact upload, contradicting the action's stated fork behavior; give the signing step an ID and condition this gate on its signed output (or otherwise exempt the unsigned-fork path).

Useful? React with 👍 / 👎.

@danielhanchen
danielhanchen merged commit 2c4df9b into master Sep 7, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant