Skip to content

Migrate Windows release signing to DigiCert STM keypair-alias#14729

Draft
cderv wants to merge 7 commits into
mainfrom
test/digicert-stm-2026-signing
Draft

Migrate Windows release signing to DigiCert STM keypair-alias#14729
cderv wants to merge 7 commits into
mainfrom
test/digicert-stm-2026-signing

Conversation

@cderv

@cderv cderv commented Jul 24, 2026

Copy link
Copy Markdown
Member

The DigiCert code-signing certificate used for Windows release signing expires 2026-08-19. IT/Security team provided a new credential set (_2026-suffixed secrets) alongside the existing one, so the workflow can be migrated to the new certificate ahead of expiry while the old set stays available for rollback during the transition.

Change

sign-files/action.yml now signs via smctl sign --keypair-alias directly against DigiCert, instead of smctl windows certsync + signtool.exe sign /sha1 <fingerprint>. Signature/timestamp are pinned explicitly (--digalg SHA256 --sigalg SHA256 --timestamp=true) rather than relying on tool defaults, and verification uses smctl sign verify in place of signtool.exe verify /v /pa.

create-release.yml's make-installer-win job now sources SM_HOST_2026 / SM_API_KEY_2026 / SM_CLIENT_CERT_FILE_B64_2026 / SM_CLIENT_CERT_PASSWORD_2026 / SM_KEYPAIR_ALIAS_2026, mapped to the unsuffixed env var names the tooling reads.

The signtools-extra-args input (used to pass /d "Quarto CLI" to the MSI signing step) is removed — smctl sign has no description/subject-name equivalent flag, so the input had no way to keep working. Manually checked the currently-released MSI's signature (Explorer > Digital Signatures > Details > Additional Information): the description text isn't visible there either, so this has no observable user-facing effect either way.

Also added a workflow_dispatch os input (all/linux/windows/macos, default all) that gates the per-platform build/test jobs, so validating this signing change doesn't require running the full multi-platform release pipeline. A guard step fails fast if publish-release is requested together with a non-all os, since a partial-platform run can't produce a coherent release.

Decisions

Stayed on the same job and runner (windows-latest), rather than moving signing to a separate Linux job with osslsigncode + a PKCS11 engine — smctl sign talks to DigiCert directly and doesn't need the Windows cert-store sync step, so no job split is needed. smctl still delegates the actual Windows signing to signtool.exe internally, so the existing "add signtool to PATH" step stays in place.

Considered adding --tsa-url to restore explicit timestamp-server pinning (dropped the previous /tr http://timestamp.digicert.com), but DigiCert's docs confirm the flag only records the URL in signature metadata — it doesn't select which TSA is actually used — so it was left out as a no-op.

Test Plan

create-release.yml doesn't run on pull request events, so the signing path needs a manual workflow_dispatch run before this is ready to merge:

  • Trigger workflow_dispatch on this branch with publish-release=false, os=windows
  • Confirm smctl sign and smctl sign verify succeed in the make-installer-win job
  • Inspect the resulting signed quarto.exe/MSI with Get-AuthenticodeSignature: Status=Valid, HashAlgorithm=sha256, timestamp present from a DigiCert TSA

Opened as draft until the above passes.

@posit-snyk-bot

posit-snyk-bot commented Jul 24, 2026

Copy link
Copy Markdown
Collaborator

Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues
Licenses 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

cderv added 7 commits July 24, 2026 23:15
Windows signing certificate expires 2026-08-19; security provisioned
a new credential set (_2026-suffixed secrets, keypair-alias based).
This is a spike to test whether smctl's own sign/verify subcommands
work directly against the new credentials, without signtool.exe or
smctl windows certsync, before deciding on a target architecture.

Also adds an `os` workflow_dispatch input (all/linux/windows/macos,
default all) so a single-platform signing test doesn't require
running the full multi-platform release pipeline.
smctl sign --keypair-alias has no equivalent flag (per DigiCert's docs),
and the new sign command never consumed this input, so the MSI
description arg was being silently dropped. Remove the now-unused
input and its caller rather than imply it's still honored.
smctl's --sigalg/--digalg default to "whatever the signing tool used
supports" per DigiCert docs, unlike the old signtool.exe invocation
which pinned /td SHA256 /fd SHA256 explicitly. Pin both rather than
rely on an undocumented default. Also use --timestamp=true instead of
the bare --timestamp flag, since DigiCert's docs only show the
--timestamp=false boolean form.
The new os selector could skip Linux/macOS installer jobs while
configure still bumped version.txt and pushed a tag (gated only on
publish-release, not os). publish-release itself then auto-skips
since its skipped needs aren't successes, but cleanup-when-failure
only fires on failure()/cancelled(), not skipped -- leaving an
orphaned version/tag commit with no corresponding release. Fail
fast instead of publishing partial-platform releases.
llm-docs/code-signing-installers.md still described the old
certsync/signtool.exe/CERT_FINGERPRINT flow, which would mislead
anyone rotating DigiCert credentials or debugging signing into
configuring the old secret set.
Reword the sign-step env comment now that this is the production path,
not a spike ("testing" was accurate pre-merge, misleading after).
Bump llm-docs frontmatter to the actual merge-base/date and drop an
unverified SM_HOST value claim traced to a second-hand doc handoff.
These are the two facts other maintainers will want next time this
file needs touching: smctl's verify step turns out to shell out to
signtool internally (confirmed from CI logs, not just docs), and the
dropped MSI description flag was already invisible everywhere before
removal, so its loss isn't a regression.
@cderv
cderv force-pushed the test/digicert-stm-2026-signing branch from bc833e4 to 28b145a Compare July 24, 2026 21:15
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.

2 participants