Skip to content

chore(python): sign Windows release wheels with Authenticode - #2799

Merged
chaliy merged 4 commits into
mainfrom
feat/windows-authenticode
Oct 30, 2026
Merged

chaliy merged 4 commits into
mainfrom
feat/windows-authenticode

Conversation

@chaliy

@chaliy chaliy commented Oct 30, 2026 •

Copy link
Copy Markdown
Contributor

What changed

Windows Python releases now require timestamped Authenticode signatures on native files before the wheel can enter the PyPI upload set. A shared Azure OIDC signer runs on a separate Windows runner, rejects refs outside immutable main-reachable release/test tags, repacks with fresh RECORD hashes, and verifies the signatures extracted from the final archive. Build and smoke jobs never receive the signing identity.

A manual signing-only workflow uses the same production signer on a hash-checked copy of the published 0.20.1 Windows wheel. It installs the resulting validation wheel on a separate Windows runner and tests native import during pytest plugin loading plus sandbox execution. It publishes no registry package or GitHub release. Public Azure identifiers are configuration; no private key or client secret is stored in GitHub.

Why

PondGuard reported SAC blocking Bashkit 0.20.1's native module while 0.20.0 loaded. Both published Windows modules lack embedded signatures. This implements the signing path following #2793 while retaining the reported pin until a new signed production release passes the SAC-On check.

Before / After

Before: the unsigned Windows build artifact matched the PyPI upload glob directly.
After: it remains under pypi_unsigned-; only the successfully signed, verified, repacked wheel becomes pypi_files-windows-. Any signing, timestamp, RECORD, or native-integrity failure blocks publication.

Validation: all PR checks passed before squash merge. 204 local script tests ran (4 skipped); Windows native signature/packaging tests and both hash-pinned published-wheel import/execution baselines passed. Real Git fixtures reject branch refs and tags outside main. Source/documentation checks passed, including parity of all 396 threat IDs. Local Rust/just checks were unavailable; repository CI passed.

The post-merge production signing-only run passed end to end: https://github.com/everruns/bashkit/actions/runs/41125599754. It exercised Azure OIDC, Public Trust signing, RFC3161 timestamps, regenerated RECORD verification, final-wheel signature validation, installation, native import during pytest plugin loading, and Bashkit execution (1 passed). Windows reported _bashkit.pyd: Valid; publisher=CN=Mykhailo Chalyi, O=Mykhailo Chalyi, L=Austin, S=tx, C=US; timestamped.

The controlled signed 0.20.1 validation copy is artifact windows-signing-validation, ZIP digest sha256:170798025f72b9dfe4d0ff5852043c5e50dd8c2271a529019a38b5aec80a5fb8. It was not published to PyPI. No actual SAC enforcement result is claimed.

Risk

  • Medium: missing or invalid signing prerequisites intentionally block PyPI publication.
  • Azure Individual publisher verification, Active bashkit-public Public Trust profile, v*-tag-only GitHub environment, and profile-scoped OIDC signer permission are configured.
  • Hosted Windows Server checks do not establish Windows 11 SAC enforcement. Validate the final signed artifact there before claiming compatibility.

Checklist

  • Tests for wheel hash repair, metadata tampering, artifact routing, credential isolation, real Windows signatures, and immutable source/tag checks
  • Backward compatibility considered; Python runtime API unchanged
  • Publisher identity validated; bashkit-public Public Trust profile Active
  • release-windows-signing environment accepts only v* tags
  • Certificate Profile Signer scoped to that single profile
  • Latest CI green
  • Post-merge production signing-only workflow passes Azure OIDC, signing, timestamp and pytest checks
  • SAC-On native import/execution and affected project pytest collection validated before declaring a production signed release fixed

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Oct 30, 2026 •

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
bashkit a4574b5 Commit Preview URL

Branch Preview URL
Oct 30 2026, 08:17 PM

@chaliy chaliy changed the title chore(python): prepare Authenticode signing for Windows wheels chore(python): sign Windows release wheels with Authenticode Oct 30, 2026
@chaliy
chaliy marked this pull request as ready for review October 30, 2026 20:38
@codecov

codecov Bot commented Oct 30, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@chaliy
chaliy merged commit 9e6dd97 into main Oct 30, 2026
44 checks passed
@chaliy
chaliy deleted the feat/windows-authenticode branch October 30, 2026 20:43
@chaliy chaliy mentioned this pull request Oct 30, 2026
2 tasks done
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