Code Signing
Postlane binaries are signed and notarized before release. This page explains what that means on each platform, how to verify a download, and how to set up signing if you are building from source.
macOS
What Postlane does
Every macOS release is signed with a Developer ID Application certificate and notarized by Apple. Notarization means Apple has scanned the binary for malware and issued a ticket that is stapled to the .dmg. When you open a notarized .dmg, macOS Gatekeeper reads the ticket without contacting Apple's servers, so it works offline.
The signing identity is:
Developer ID Application: Hugo Elliott (RNUCP3LV48)
Verifying a download
To confirm the .dmg you downloaded is genuine, run:
# Check the notarization ticket is stapled
xcrun stapler validate Postlane.dmg
# Check the app bundle signature
codesign --verify --deep --strict --verbose=2 /Applications/Postlane.app
# Check Gatekeeper accepts it
spctl --assess --verbose /Applications/Postlane.app
Expected output from spctl:
/Applications/Postlane.app: accepted
source=Notarized Developer ID
Building from source (local)
Without a code signature, macOS identifies the app by its binary hash. Every recompile produces a new hash, which resets all "Always Allow" keychain permissions — triggering constant password prompts during development. Signing local builds with your own Developer ID prevents this.
Add to ~/.zshrc:
export APPLE_SIGNING_IDENTITY="Developer ID Application: Your Name (TEAMID)"
Then source ~/.zshrc. Tauri picks this up automatically for both cargo tauri dev and cargo tauri build. Run the app once, click "Always Allow" on each keychain prompt — that is the last time you will see them, because macOS now identifies the app by developer identity rather than binary hash.
Release CI setup (maintainers)
The release workflow signs on every tagged push. Required GitHub repository secrets:
| Secret | What it holds |
|---|---|
APPLE_CERTIFICATE | Base64-encoded .p12 file exported from Keychain |
APPLE_CERTIFICATE_PASSWORD | Password you set when exporting the .p12 |
TAURI_SIGNING_PRIVATE_KEY | Tauri updater private key (generated by cargo tauri signer generate) |
TAURI_SIGNING_PRIVATE_KEY_PASSWORD | Password for the updater key |
APPLE_ID | Apple account email (for notarization) |
APPLE_PASSWORD | App-specific password from appleid.apple.com |
APPLE_TEAM_ID | Team ID from the Apple Developer account membership page |
APPLE_SIGNING_IDENTITY is a public string (the certificate common name) and is hardcoded in release.yml — it does not need to be a secret.
Exporting the certificate:
- Open Keychain Access
- Find Developer ID Application: Hugo Elliott (RNUCP3LV48) under My Certificates
- Right-click → Export → choose
.p12format, set a password - Base64-encode:
base64 -i certificate.p12 | pbcopy - Paste the result as the
APPLE_CERTIFICATEsecret
Two-phase notarization:
Apple's review queue can take hours on a new developer account. The release workflow submits to Apple immediately and exits, saving submission IDs alongside the .dmg artifacts. Once Apple approves, run the Notarize — finalize and publish release workflow manually:
- Go to Actions → Notarize — finalize and publish release → Run workflow
- Enter the release tag (e.g.
v0.4.2) and the run ID of the build job (visible in the Actions URL) - The workflow waits for Apple, staples the notarization ticket, uploads the stapled
.dmgfiles, and publishes the draft release
Prerequisites for a new Apple Developer account:
- Apple Developer Program membership ($99/year) — developer.apple.com
- A Developer ID Application certificate issued from the account (not a Mac App Distribution certificate)
- Hardened runtime enabled — already set in
tauri.conf.json:
"bundle": {
"macOS": {
"hardenedRuntime": true,
"entitlements": "../Entitlements.plist",
"signingIdentity": "Developer ID Application: Your Name (TEAMID)"
}
}
Windows
What Postlane does
Windows builds are signed with Tauri's updater key (TAURI_SIGNING_PRIVATE_KEY), which protects the auto-update mechanism. The installer itself does not currently carry a Windows Authenticode certificate, so Windows SmartScreen will show a warning on first run.
To proceed past the SmartScreen warning:
- Click More info
- Click Run anyway
SmartScreen warnings diminish automatically as more users run the installer — Microsoft's reputation system learns over time.
A commercial EV (Extended Validation) code signing certificate removes the SmartScreen warning immediately but costs $200–500/year. This will be evaluated before the v1.0 commercial release.
Verifying a download
Verify the updater signature using the Tauri public key published in tauri.conf.json:
dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IDNENzBERjNEMzdCMjdFQjIKUldTeWZySTNQZDl3UFh2SEhNZ3JFMnRNbXZwWWRJQTZjcmF2cENkY0xHTkFvOFA3aWZEVUs0WmsK
Linux
What Postlane does
Linux builds are signed two ways:
-
GPG signature —
.AppImageand.debfiles are signed with the Postlane releases GPG key. A.ascdetached signature file is published alongside each artifact. -
cosign signature —
.AppImagefiles are additionally signed with Sigstore cosign using keyless signing (OIDC-bound to the GitHub Actions workflow identity). A.cosign.bundlefile is published alongside each.AppImage.
GPG public key
The releases key is published at postlane.dev/pgp.
Key UID: releases@postlane.dev
Import and verify:
# Import the key
curl https://postlane.dev/pgp.asc | gpg --import
# Verify the AppImage
gpg --verify Postlane.AppImage.asc Postlane.AppImage
# Verify the .deb
gpg --verify Postlane.deb.asc Postlane.deb
Expected output:
gpg: Good signature from "PostLane Releases <releases@postlane.dev>"
cosign verification
# Install cosign
brew install cosign # or: go install github.com/sigstore/cosign/v2/cmd/cosign@latest
# Verify the AppImage
cosign verify-blob Postlane.AppImage \
--bundle Postlane.AppImage.cosign.bundle \
--certificate-identity-regexp 'https://github.com/postlane/desktop' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com
Installing on Ubuntu without a GUI package manager
# Make the AppImage executable
chmod +x Postlane.AppImage
# Run it
./Postlane.AppImage
If you see a FUSE error, install the FUSE library:
sudo apt-get install libfuse2
Reporting signature issues
If a Postlane binary fails signature verification or a release appears tampered with, report it privately before publishing:
- Email: security@postlane.dev
- Response within 48 hours