← All documentation · English | 繁體中文
The installer is not yet code signed
The MSI, and the executable it installs, carry no Authenticode signature today. A certificate through one of the code-signing programmes for open-source projects is planned, and once it is in place the warnings described below stop appearing. Until then, this page covers what you will see and how to get past it safely.
An Authenticode signature does two things: it proves the file came from a named publisher, and it proves the bytes have not been altered since. This project answers the second with a published SHA-256 for every release asset. The first is what the certificate will supply.
1. What you will actually see
| Where | What appears | What to do |
|---|---|---|
| Browser download | Edge or Chrome may warn that the file “isn’t commonly downloaded” | Keep the file, then verify the SHA-256 (§2) |
| Double-clicking the MSI | Microsoft Defender SmartScreen: “Windows protected your PC” | More info → Run anyway, once the hash matches |
| The UAC elevation prompt | Publisher shown as Unknown, on the yellow banner rather than the blue verified one | Expected. Confirm you are elevating for the file you just verified |
msiexec /qn from an elevated console |
Nothing — SmartScreen only intercepts interactive launches | Nothing |
| GPO software deployment | Nothing — the installation runs as SYSTEM with no interactive session | Nothing. Host the MSI on an internal share (§3) |
| WDAC or AppLocker enforced | Blocked. No publisher rule can match an unsigned file | Add a hash rule (§4), or sign it yourself (§6) |
| Microsoft Defender | PyInstaller output has a history of heuristic false positives | If it is quarantined, submit the sample and add an exclusion (§6) |
None of these are errors in the installer. They are Windows correctly reporting that it cannot identify who produced the file.
2. Verify the download — this is the important step
The hash is the integrity check that a signature would otherwise have given you
at install time. Every release attaches <msi-name>.sha256 alongside the MSI.
# CLI - run in the folder containing both files
Get-FileHash .\jt-snmpd-1.1.3-x64.msi -Algorithm SHA256
Get-Content .\jt-snmpd-1.1.3-x64.msi.sha256
The two values must match, ignoring case. If they do not, stop — do not install, and re-download from the release page.
Fetch the .sha256 file from the GitHub release itself, not from a mirror or a
copy someone forwarded you. A hash that travelled with the file it is supposed
to protect proves nothing.
3. Clear the Mark of the Web
Files downloaded through a browser carry a zone marker in an alternate data stream, and that marker is what triggers SmartScreen. Once you have verified the hash, remove it:
# CLI
Unblock-File .\jt-snmpd-1.1.3-x64.msi
The graphical equivalent is right-click → Properties → tick Unblock at the bottom of the General tab.
Copying the MSI to an internal file share and installing from there avoids the marker entirely, which is why GPO deployment never encounters it.
4. Trusting the installer manually
An unsigned file has no certificate to trust, so “trusting it manually” really means one of two things: allowing it on a single machine, or settling the question across the whole domain at once.
On a single machine
| What stops you | How to allow it |
|---|---|
| SmartScreen’s “Windows protected your PC” | Click More info, then Run anyway |
| The file’s Mark of the Web | Right-click the file → Properties → tick Unblock, or run Unblock-File |
| Defender quarantining the file | Open Windows Security → Virus & threat protection → Protection history, find the entry and choose Allow on device |
Do all three only after checking the SHA-256 (§2). The order matters: establish that the file is the right one, then decide whether to let it through. The other way round is opening the door before knowing what is behind it.
Across a domain
Clicking “Run anyway” on each of several hundred machines is not a procedure. Two routes actually work:
One: deploy from an internal file share. The Mark of the Web is applied only to files downloaded through a browser. Put the MSI on a domain file share and install it through GPO software deployment, and neither SmartScreen nor the unblock step ever arises, because the installation runs as SYSTEM with no interactive session. This is the least effort of anything on this page.
Two: sign with your own certificate and push it as a trusted publisher. If your organisation runs an internal PKI, sign the MSI (§6) and then use Group Policy to place that certificate in the clients’ Trusted Publishers store:
Computer Configuration → Windows Settings → Security Settings → Public Key Policies
→ Trusted Publishers <- import your code-signing certificate
→ Trusted Root Certification Authorities <- also import, if an internal CA issued it
Once that is deployed, the UAC prompt names your organisation instead of showing an unknown publisher, SmartScreen does not intervene, and your existing WDAC and AppLocker publisher rules apply directly. This one route settles everything else on this page.
Do not “solve” this by adding jt-snmpd to a global SmartScreen or Defender exclusion list. Exclusions apply to a path rather than to a file, they stay there indefinitely, and anything later placed in that directory is skipped along with it.
5. WDAC and AppLocker: add a hash rule
In an environment with Windows Defender Application Control or AppLocker in enforcement, an unsigned file cannot be allowed by publisher — there is no publisher. A file hash rule is the supported alternative, and it is genuinely strict: it permits exactly the bytes you approved and nothing else.
Two files need covering: the MSI itself, and the service executable it installs.
# CLI - the paths a rule has to cover
.\jt-snmpd-1.1.3-x64.msi
C:\Program Files\jt-snmpd\jt-snmpd.exe
For WDAC, generate a policy fragment from the installed folder and merge it into your existing policy:
# CLI
New-CIPolicy -Level Hash -FilePath .\jt-snmpd.xml `
-ScanPath 'C:\Program Files\jt-snmpd' -UserPEs
Merge-CIPolicy -PolicyPaths .\existing.xml,.\jt-snmpd.xml -OutputFilePath .\merged.xml
Because the rule is bound to the hash, it has to be regenerated on every upgrade. Treat that as part of the upgrade procedure, not as an afterthought: a merged policy that still names the previous version will block the new service from starting.
6. Sign it yourself
If your organisation runs an internal PKI with a code-signing template — common in government agencies and hospitals — signing the MSI with your own certificate is more useful than a public signature would be. The full procedure, including building from source first so that the service executable inside the package is signed as well, is in Building and signing it yourself. It makes the file match the WDAC and AppLocker publisher rules you already maintain, and it puts your own name in the UAC prompt, which is a more meaningful statement to your operators than a third party’s name.
# CLI
signtool sign /fd SHA256 /tr http://timestamp.digicert.com /td SHA256 `
/f your-code-signing.pfx /p <password> `
.\jt-snmpd-1.1.3-x64.msi
signtool verify /pa /v .\jt-snmpd-1.1.3-x64.msi
Verify the SHA-256 against the published value before signing. Signing overwrites the file, so the published hash no longer applies afterwards — record your own hash of the signed artefact for your internal records.
7. If Defender quarantines the file
PyInstaller-produced executables are periodically flagged by heuristics, not by signature matches. If that happens:
- Verify the SHA-256 first, so you know you are defending the file you meant to.
- Submit it at Microsoft Security Intelligence as a suspected false positive. Submissions are usually resolved within a few days and the fix reaches every Defender installation.
- As an interim measure, add a path exclusion for
C:\Program Files\jt-snmpd\— and remove it once the submission is resolved, since a permanent exclusion on a directory is itself a weakness.
Do not disable real-time protection as a workaround.
8. Deciding whether this is acceptable
It may not be, and that is a legitimate conclusion. Some points to weigh:
- The source is public and the build can be repeated from it. Releases are built by GitHub Actions from a tagged commit, and the workflow that produced each artefact is visible in the Actions log. The build is not byte-reproducible — PyInstaller stamps a build time into the executables it produces — so a local build will not match the published hash.
- The hash chain is complete from the release page to the installed file, as long as you fetch the hash from the release page.
- What is missing is publisher identity, and no amount of hashing supplies it. If your controls require a named, certificate-backed publisher, §6 is the route that satisfies them.
- Building from source is supported. If you would rather not trust a binary
at all,
packaging/build-exe.ps1andpackaging/build-msi.ps1produce an installer from the same source on your own machine; see Building and signing it yourself.