Configure Windows signing with SignPath
ReShiki has SignPath Open Source Code Signing access. Production Windows signing is not active yet: the Foundation release certificate is pending, the release certificate pin must be configured, and the production signing path must pass a manual run. The two artifact configurations and GitHub environment are configured, including the CI token and test certificate pin. Nightly-version test signing passed on x64 and ARM64, and internal test signing is enabled for daily nightlies. Existing Windows downloads remain unsigned. This record describes the configuration inspected on 2026-10-09 and the remaining setup.
Certificate status rechecked on 2026-10-15
Section titled “Certificate status rechecked on 2026-10-15”The live portal still shows Release certificate 2026 as CSR PENDING and
release-signing as INVALID. The certificate has no validity dates yet.
SIGNPATH_ENABLED and SIGNPATH_NIGHTLY_ENABLED remain false; internal
nightly test signing remains enabled. Test signatures are not publicly trusted.
The Windows security investigation records
the current installer detections and the separate proposed inner-executable
signing extension, which is not part of the nightly startup fix.
Confirm the SignPath project
Section titled “Confirm the SignPath project”Open SignPath using the maintainer account with MFA. The inspected settings are:
| Setting | Value |
|---|---|
| Organization ID | c91a089d-e2bc-458e-8453-0d11619e584e |
| Project slug | ReShiki |
| Repository | https://github.com/Ameyanagi/ReShiki.git |
| Trusted build system | GitHub.com, active and linked to ReShiki |
| Release policy | release-signing, currently invalid while its certificate is pending |
| Release certificate | Release certificate 2026, HSM key, CSR pending |
| Release submitter | CI builds |
| Release approver | Project maintainer, one approval required |
| Release verification | Trusted build system and origin verification required |
| Release allowed branches | ** at inspection; review before activation |
| Test policy | test-signing, valid; no approval, trusted-build-system or origin-verification requirement |
The valid test policy does not establish production readiness. Its certificate is not publicly trusted. See SignPath’s test and release certificate documentation.
The official SignPath App was installed on
2026-10-09 with Only select repositories → ReShiki. Its installation ID is
169339604. GitHub confirmed read access to Actions, code and metadata, plus
read/write access to repository administration. The maintainer approved those
permissions and completed GitHub re-authentication. When checking or restoring
this integration, inspect Settings → Applications → Installed GitHub Apps
and verify that the App is active, limited to ReShiki, and the project remains
linked to the active GitHub.com trusted build system. SignPath documents the App and GitHub-hosted
runner requirements in its GitHub integration
guide.
Review the current ** branch allowance with the Foundation before enabling
production. Restrict the policy to the reviewed release origins accepted by
SignPath. Check the origin shown for both a main build and a release-tag build;
do not assume that a tag pattern is a branch name. The workflow also restricts
production signing to main and version tags whose commits belong to main.
Keep one manual approval, trusted-build-system verification and origin
verification enabled for release-signing.
Register the artifact configurations
Section titled “Register the artifact configurations”In the project’s Artifact configurations, create configurations using these exact slugs and copy the corresponding checked-in XML:
| Slug | XML | Required request parameters | Signed file inside the uploaded ZIP |
|---|---|---|---|
windows-app |
windows-app.xml | version |
reshiki.exe |
windows-installer |
windows-installer.xml | version, architecture |
reshiki-${version}-windows-${architecture}-setup.exe |
Both enforce ProductName=ReShiki and exact ProductVersion and FileVersion
strings matching the supplied package version. For a nightly, supply the entire
VERSION-nightly.DATE.RUN_ID.ATTEMPT string. Numeric VERSIONINFO values remain the
three-component base version plus a zero fourth component; they do not contain
GitHub’s run ID. The installer request’s architecture is supplied by the workflow
and validated as x64 or arm64 before submission. XML parameters themselves do
not define an architecture enumeration.
Inno Setup 6.7.3 writes these text fields into fixed placeholders: shorter values retain padding spaces, and a full nightly file version exceeds its 20-character placeholder. The packager writes exact, terminated product-name and version strings into the existing VERSIONINFO allocation before signing, then recomputes the PE checksum. It preserves file offsets, other resources and the installer payload, and rejects a version block that cannot fit. This keeps the strict SignPath identity checks intact and avoids truncating nightly version strings. The pinned compiler’s behavior is defined in its version-resource updater.
Both configurations were registered and reported VALID during setup. Their
signing directives specify SHA-256 and preserve the Open Source account’s
required signature watermark; custom signature descriptions or description URLs
are rejected by this account.
The root is <zip-file> because actions/upload-artifact@v7 creates a ZIP around
the single staged executable. Upload that executable directly at the archive
root. Do not upload the already-packaged portable ZIP for the windows-app
request; that would add another archive level. Keep the normal ZIP behavior and
the signing action’s normal decompression behavior. Each configuration signs one
explicit PE file and does not sign other files added to an upload. Required
parameters, nested paths and match counts follow SignPath’s artifact syntax
documentation; metadata
restrictions follow its artifact reference.
The project’s initial default configuration signs an unrestricted PE file.
Retire or replace it with the same restrictions after registering and validating
the new configurations. Release requests must explicitly select windows-app or
windows-installer; do not leave an unrestricted configuration available for
production signing. Compare the portal XML with the repository when changing
either configuration. Use a new slug for an incompatible artifact layout, as
recommended by SignPath’s project configuration
guide.
Configure GitHub credentials
Section titled “Configure GitHub credentials”Create the windows-signing GitHub environment in
ReShiki’s repository settings.
Add the following secret and environment variables. The signing switches are
repository variables, so publication and the reusable release workflow can
read them outside the signing environment.
| Location | Name | Value |
|---|---|---|
| Environment secret | SIGNPATH_API_TOKEN |
API token for the CI builds submitter |
| Environment variable | SIGNPATH_ORGANIZATION_ID |
c91a089d-e2bc-458e-8453-0d11619e584e |
| Environment variable | SIGNPATH_PROJECT_SLUG |
ReShiki |
| Environment variable | SIGNPATH_TEST_CERTIFICATE_SHA256 |
SHA-256 of the test policy’s DER-encoded public certificate |
| Environment variable | SIGNPATH_RELEASE_CERTIFICATE_SHA256 |
SHA-256 of the issued release policy’s DER-encoded public certificate |
| Repository variable | SIGNPATH_ENABLED |
false until production validation completes |
| Repository variable | SIGNPATH_NIGHTLY_ENABLED |
false; enable separately to require signed nightlies |
| Repository variable | SIGNPATH_NIGHTLY_TEST_ENABLED |
true; the manual nightly-version test-signing run passed, enabling internal CI artifacts only |
In SignPath’s Users and Groups, open the existing CI builds CI user and
reuse its previously saved API token, or regenerate it if it was not saved. Verify that this user is a submitter for the two intended
ReShiki policies and has no unnecessary administrator permissions. Store the
token directly in GitHub’s environment-secret field; do not place it in source
files, commands, logs or chat. SignPath displays a token only when generated;
regenerating it can invalidate an existing integration. See its CI user
documentation.
Download each policy’s public X.509 certificate from SignPath to calculate its
pin. Do not use a CSR, a private-key export, or the portal’s SHA-1 thumbprint. In
PowerShell 7, for a downloaded .cer file:
$certificate = [System.Security.Cryptography.X509Certificates.X509Certificate2]::new((Resolve-Path '.\signpath-test.cer').Path)$certificate.GetCertHashString([System.Security.Cryptography.HashAlgorithmName]::SHA256)The method hashes the certificate’s DER bytes, even when the downloaded file uses another supported encoding. Store the resulting 64 hexadecimal characters in the matching variable. Repeat for the issued release certificate when it becomes available. Pin the certificate used by the policy, and update the pin deliberately when that certificate is rotated. CI checks returned signatures against these pins; it does not trust a publisher name alone.
The active windows-signing environment permits main only. The temporary
signing/signpath-windows validation-branch allowance was removed after merging
the integration. Add a v* release-tag policy when activating production signing;
retain the main branch policy. The workflow has its own origin gates as well.
The nightly reusable call must
retain secrets: inherit, and signing jobs need actions: read and
contents: read permissions. The integration uses
signpath/github-action-submit-signing-request@v3, explicitly passes each artifact
configuration slug and downloads the completed signed artifact. See the
SignPath action inputs.
Validate with the test policy
Section titled “Validate with the test policy”Keep both publication switches false. On main, dispatch Release builds
with Sign Windows test packages enabled and windows_signing_policy set to
test-signing:
gh workflow run release.yml --ref main -f sign_windows=true -f windows_signing_policy=test-signingThis manual run does not publish a release. Repeat with -f nightly=true to
exercise the full nightly version string. The workflow also permits internal
test-policy dispatches on a feature branch; the signing environment must allow
that branch before such a run can access its credentials. Both x64 and ARM64 must
complete the
following sequence:
- Check the qualified unsigned archive’s checksum, source commit, version,
architecture and expected contents, then stage its
reshiki.exe. - Upload and sign the application using
windows-app; verify the returned executable’s version metadata, timestamped Authenticode signature and test-certificate pin. - Put that signed executable in the portable package and build Inno Setup from the same package contents.
- Upload and sign the final setup executable using
windows-installer; verify its metadata, signature and pin. - Retest the final portable package and installed application, including upgrades and uninstallation, and generate package checksum sidecars from the final bytes.
Review both architectures’ SignPath request records and workflow logs. Test signatures lack public trust. After matching the DER SHA-256 pin, the verification helper temporarily trusts that test certificate on the disposable GitHub-hosted Windows runner to validate Authenticode and its timestamp, and removes that trust in its cleanup path. Do not install the test certificate on users’ computers. Do not publish test-signed packages or describe them as trusted Windows releases. Passing this run also does not exercise the release policy’s approval and origin requirements.
Only the application and final setup executable are signed. Inno Setup’s generated uninstaller remains unsigned; signing the outer setup program does not sign it. The installer privacy disclosure and update-check opt-out requirements must also be reviewed with SignPath Foundation before production activation.
Run internal test-signed nightlies
Section titled “Run internal test-signed nightlies”The manual nightly-version validation
completed successfully on 2026-10-09, at commit
29bd9cfc65befe4f46b8a985bdbe33e5f3d9f00f, using package version
0.11.0-nightly.20261008.37822934801.1. All six platform builds passed, and
SignPath completed the application and installer requests for both Windows
architectures. Both native signing jobs passed certificate-pin, timestamp,
metadata, content-integrity, final installation/upgrade/uninstallation, chemistry
and packaged MCP checks. One initial ARM64 PowerShell startup timeout passed on
an unchanged failed-job retry; the other five qualified builds were reused.
PR #270 is merged, and repository
variable SIGNPATH_NIGHTLY_TEST_ENABLED is now true. Daily nightlies are
scheduled for 03:37 Japan time; GitHub may start scheduled runs later. Both
production switches remain false, and the release certificate remains CSR
pending.
After the manual test-policy run passes for both architectures, repeat it with
-f nightly=true and verify the full nightly version in the signed packages.
Then set repository variable SIGNPATH_NIGHTLY_TEST_ENABLED=true to add test
signing to scheduled and manually dispatched Nightly builds on main. Keep
SIGNPATH_ENABLED=false and SIGNPATH_NIGHTLY_ENABLED=false while the release
certificate is pending. The updated workflows must be merged to main before
the scheduled run can use this path.
Each nightly reuses the qualified Windows artifacts from its existing six-target
build; it does not start a second full build. It submits four test-signing
requests: one application and one setup program for each of x64 and ARM64. These
requests use the configured test-certificate pin and require no manual SignPath
approval. The completed packages remain workflow artifacts named
test-signed-windows-x64 and test-signed-windows-arm64 for internal validation.
They are untrusted on ordinary Windows installations.
The public nightly release still downloads the original unsigned Windows
artifacts, labels Windows downloads as unsigned, and calculates SHA256SUMS from
those published bytes. It never downloads the test-signed artifacts. A failing
internal signing job prevents that nightly run from publishing; review the
failure before starting another run.
The reusable release workflow accepts and validates windows_signing_policy and
exports the selected policy alongside windows_signing_enabled. The nightly
publisher treats Windows packages as release-signed only when signing is enabled
and the selected policy is release-signing. If
SIGNPATH_NIGHTLY_ENABLED=true, production signing takes precedence over the
internal test switch and requires the issued release certificate and manual
approvals described below.
Activate production signing
Section titled “Activate production signing”The inspected Release certificate 2026 entry is still a pending CSR and has no
validity dates. A CSR is not an issued certificate and cannot supply the release
certificate pin. Wait for the Foundation’s certificate-issuance process. If the
entry remains pending, contact the Foundation through the existing approval
correspondence with the organization ID, project slug and pending certificate
name; ask what remains to complete issuance. Do not generate a replacement key or
buy/upload an unrelated certificate as a workaround. SignPath explains its HSM
CSR flow in Managing certificates.
After the certificate is issued, confirm that release-signing is valid, download
its public certificate and set SIGNPATH_RELEASE_CERTIFICATE_SHA256. Dispatch the
same manual workflow using -f windows_signing_policy=release-signing. For each
architecture, the approver must review and approve the application request before
the installer request can be built and submitted, then review and approve that
installer request. Check the commit, version, artifact configuration and verified
origin for every request. Keep the workflow running while completing its approvals.
Before activation, both architectures must pass public-trust verification with a
timestamp, the release-certificate pin, final package tests, install/upgrade and
uninstall checks. Record the run and request URLs in the release validation
record. Only then set repository variable SIGNPATH_ENABLED=true. Stable tag
publication now requires the signed Windows artifacts and fails if signing or
verification fails; it does not substitute unsigned packages.
Nightly signing remains a separate choice. Set SIGNPATH_NIGHTLY_ENABLED=true
only after validating a nightly-version release-signing run and arranging manual
approvals for each daily build. Leave it false to continue clearly labelled
unsigned Windows nightlies. Test signing is never used for public nightlies.
The final Windows ZIP and setup checksums are generated after signing and package
verification. Publication generates SHA256SUMS from those final packages. An
unsigned build’s checksums cannot be reused because signing changes file bytes.
See the code signing policy, release process
and Foundation conditions.