feat: introduce sign mode for driver packaging, allowing skipping of signing steps#649
feat: introduce sign mode for driver packaging, allowing skipping of signing steps#649svasista-ms wants to merge 5 commits intomicrosoft:mainfrom
Conversation
There was a problem hiding this comment.
Pull request overview
Adds a new build-time signing mode to cargo-wdk so production packaging can skip test-signing (and associated certificate generation/verification), aligning with the request in #588 to produce unsigned driver binaries for external signing.
Changes:
- Introduces
SignMode(testdefault,off) and wires it through CLI →BuildAction→PackageTask. - Updates packaging flow to conditionally skip certificate generation, signtool signing, and signature verification when
--sign-mode=off. - Adds unit + integration tests covering
--sign-mode=off, CLI validation, and help-surface expectations.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| crates/cargo-wdk/tests/build_command_test.rs | Adds integration tests for --sign-mode=off, including “not Authenticode signed” validation. |
| crates/cargo-wdk/src/cli.rs | Adds --sign-mode flag, passes it into build params, and rejects --verify-signature with --sign-mode=off. |
| crates/cargo-wdk/src/actions/mod.rs | Defines the SignMode enum with parsing/display behavior. |
| crates/cargo-wdk/src/actions/build/tests.rs | Extends build action tests/mocks to cover sign-mode off behavior and propagation. |
| crates/cargo-wdk/src/actions/build/package_task.rs | Implements sign-mode branching in packaging, skipping signing steps when off. |
| crates/cargo-wdk/src/actions/build/mod.rs | Threads sign_mode from build action into package task params. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #649 +/- ##
==========================================
+ Coverage 78.69% 78.74% +0.05%
==========================================
Files 25 25
Lines 5234 5275 +41
Branches 5234 5275 +41
==========================================
+ Hits 4119 4154 +35
- Misses 995 1001 +6
Partials 120 120 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Co-authored-by: Copilot <copilot@github.com>
…ification enabled Co-authored-by: Copilot <copilot@github.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| )?; | ||
| } | ||
| SignMode::Off => { | ||
| info!("Sign mode is 'Off'; skipping certificate generation and signing"); |
There was a problem hiding this comment.
When --sign-mode=off, the package directory is not cleaned (it’s only created if missing). If a previous build ran in Test mode, WDRLocalTestCert.cer may already exist in the package folder and will be left behind because the copy step is skipped, which can defeat the goal of producing a package without the test cert artifact. Consider explicitly removing any existing cert file(s) (both in the package folder and staged under target) when SignMode::Off is selected, or recreate/clean the package directory before copying artifacts (may require adding a remove_file/remove_dir_all method to the Fs provider so this is testable).
| info!("Sign mode is 'Off'; skipping certificate generation and signing"); | |
| info!("Sign mode is 'Off'; skipping certificate generation and signing"); | |
| for cert_path in [&self.dest_cert_file_path, &self.src_cert_file_path] { | |
| match std::fs::remove_file(cert_path) { | |
| Ok(()) => { | |
| info!( | |
| "Removed stale certificate artifact: {}", | |
| cert_path.to_string_lossy() | |
| ); | |
| } | |
| Err(err) if err.kind() == std::io::ErrorKind::NotFound => {} | |
| Err(err) => return Err(err.into()), | |
| } | |
| } |
There was a problem hiding this comment.
Checked how MSBuild/WDK handles this in WindowsDriver.Common.targets (10.0.26100.0): all signing targets are gated on SignMode == TestSign|ProductionSign, same as this PR. There's no mode-switch cleanup. I think we should let cleanup be handled by cargo wdk clean similar to MSBuild's Clean. If this UX becomes an issue, I can revisit it and implement something to ensure the final package is not stale.
There was a problem hiding this comment.
Why are we adding the cert to the package? Is that something Visual Studio does too?
There was a problem hiding this comment.
Good question! cargo-wdk actually follows the cargo-make based approach in rust-driver-makefile.toml:452-468, which in turn was derived from WDK's MSBuild targets. Shipping the cert for "Test-Signing" workflows makes sense because the cert needs to be installed on the target (test) machine. I need to re-verify the behavior for C++ drivers in Visual Studio.
There was a problem hiding this comment.
Okay.
Yeah, let's verify the C++ behaviour.
| /// * `Test` - Use test-signing, which currently auto-generates a self-signed | ||
| /// certificate (`WDRLocalTestCert` in the `WDRTestCertStore` store) and signs | ||
| /// the driver binary and catalog file with it. | ||
| #[derive(Debug, Clone, Copy, PartialEq, Eq, Default)] |
There was a problem hiding this comment.
| #[derive(Debug, Clone, Copy, PartialEq, Eq, Default)] | |
| #[derive(Debug, Clone, Copy, PartialEq, Eq, Default)] | |
| #[value(rename_all = "lower")] |
In help etc. we want to say "test" and "off" instead of "Test" and "Off" as typing the former is easier for users.
| )?; | ||
| } | ||
| SignMode::Off => { | ||
| info!("Sign mode is 'Off'; skipping certificate generation and signing"); |
There was a problem hiding this comment.
| info!("Sign mode is 'Off'; skipping certificate generation and signing"); | |
| info!("Sign mode is 'off'; skipping certificate generation and signing"); |
We want to use and promote lower case values of sign mode everywhere since they are easier to type.
| self.run_signtool_verify(&self.dest_driver_binary_path)?; | ||
| self.run_signtool_verify(&self.dest_cat_file_path)?; | ||
| if matches!(self.sign_mode, SignMode::Off) { | ||
| warn!("Skipping signature verification because sign mode is 'Off'"); |
There was a problem hiding this comment.
| warn!("Skipping signature verification because sign mode is 'Off'"); | |
| warn!("Skipping signature verification because sign mode is 'off'"); |
| // Given: A driver project | ||
| // When: --sign-mode=off is provided | ||
| // Then: It builds successfully and skips all certificate generation and | ||
| // signing steps (no makecert / certmgr / signtool sign calls). |
There was a problem hiding this comment.
Remove these comments for all the new tests for consistency because we don't use them on existing tests either. The function names themselves are super verbose so no need for comments.
| //////////////////////////////////////////////////////////////////////////////// | ||
| /// Sign-mode integration tests | ||
| //////////////////////////////////////////////////////////////////////////////// | ||
|
|
There was a problem hiding this comment.
Remove this header comment as we don't use such comments anywhere else in this file

This PR adds a
--sign-modeoption to thecargo wdk buildcommand that lets you turn off test signing which is useful for production/HLK scenarios.Resolves #588
Functionality
--sign-modetakes two values:test: generates a self-signed cert and signs artifacts with it. Same behavior as todayoff: skips all signing including cert generationtestis the default so if--sign-modeis omitted the command behaves exactly as today and thus remains backwards compatible.An error is returned if you try to use
--verify-signaturewith--sign-mode=offbecause verification does not make sense when nothing is signed.Future Direction
This PR is part of a broader goal to replicate Visual Studio's
SignModesetting incargo-wdk. In the future we plan to:--sign-modevalue calledprodto enable a production signing mode that will not generate a test cert and will instead require a user-specified certChanges
sign_modefield inBuildArgs[1]--verify-signaturewith--sign-mode=off[2]SignModeenum withTestandOffvariants [3].SignModefromBuildActionthroughPackageTaskPackageTask::run(), gatedgenerate_certificate, the certificate copy andsigntoolinvocations onSignMode::Test[4]Screenshots
cargo wdk build --helpshowing--sign-mode:Building with

--sign-mode=off:Building with

--sign-mode=test:Building without the

--sign-modeoption -- falls back to the default (test) behavior:Error when using

--verify-signaturewith--sign-mode=off: