This guide defines the practical path to distribute the issuer app as an installable desktop app for non-technical users on Windows, macOS, and Linux.
If you are the only maintainer and release from your own Mac:
- Set required non-secret env vars in your shell:
export APPLE_SIGNING_IDENTITY='Developer ID Application: YOUR NAME (TEAMID)'
export APPLE_ID='your-apple-id@example.com'
export APPLE_TEAM_ID='YOURTEAMID'- Save app-specific password in Keychain (recommended):
security add-generic-password \
-a "$APPLE_ID" \
-s "ampa-issuer-notarytool" \
-w '<app-specific-password>' \
-U- Run:
cd issuer
npm run desktop:release:macThis single command builds, signs, notarizes, staples, verifies, and writes checksums for the macOS installer.
Output location:
issuer/release/macos/*.dmgissuer/release/macos/SHA256SUMS.txt
Use a desktop wrapper around the existing issuer web app, with no UI/logic fork.
- Recommended stack: Tauri + current
issuer/React/Vite app - Goal: double-click installer, app icon in OS launcher, no Node/npm required for end users
Start simple, then harden:
- Build installers per OS (manual install, no auto-update).
- Add signing/notarization.
- Add checksums and release notes.
- Later: optional auto-update.
- Code signing certificate (OV or EV) issued to your organization.
- Private key available in secure store (or hardware token/HSM for EV).
- Windows signing toolchain (
signtoolfrom Windows SDK) in CI runner or signing machine.
- Build unsigned installer (
.exe/MSI). - Sign binaries and installer with SHA-256 digest.
- Timestamp signature using a trusted timestamp server.
- Verify signature before publishing.
signtool sign /fd SHA256 /tr <TIMESTAMP_URL> /td SHA256 /a <PATH_TO_ARTIFACT>
signtool verify /pa <PATH_TO_ARTIFACT>- EV certs improve SmartScreen reputation/bootstrap trust.
- Store cert material outside repo and inject via CI secrets or secure key vault.
- Apple Developer Program membership.
- Developer ID Application certificate.
- App-specific password and Team ID for notarization tooling.
- Build
.appand.dmg. - Sign app and installer with Developer ID.
- Submit to Apple notarization service.
- Wait for notarization success.
- Staple notarization ticket to final artifact.
- Verify Gatekeeper acceptance locally.
codesign --deep --force --options runtime --sign "Developer ID Application: <ORG>" <APP_PATH>
xcrun notarytool submit <DMG_OR_ZIP> --apple-id <APPLE_ID> --team-id <TEAM_ID> --password <APP_PASSWORD> --wait
xcrun stapler staple <DMG_OR_APP>
spctl --assess --type execute --verbose <APP_PATH>- Without notarization, many users will see security warnings/blocking.
- Keep signing identities and notarization credentials in secure CI secrets.
The repo includes an automated script:
cd issuer
npm run desktop:release:macIt executes this sequence automatically:
- Build DMG via Tauri.
- Sign
.appand.dmg. - Notarize DMG with
notarytool. - Staple tickets to
.appand.dmg. - Run Gatekeeper validation.
- Export artifact and checksums under
issuer/release/macos/.
Required env vars (from your shell/session):
APPLE_SIGNING_IDENTITYAPPLE_IDAPPLE_TEAM_ID
Password resolution order:
APPLE_APP_SPECIFIC_PASSWORDenv var (optional)- Keychain lookup item
ampa-issuer-notarytoolfor account$APPLE_ID - Secure terminal prompt (hidden input)
Linux app signing is less standardized than Windows/macOS.
Minimum recommended:
- Publish SHA-256 checksums for every installer artifact.
- Optionally sign checksums with GPG key.
- Document verification steps for admins.
Typical checksum generation:
shasum -a 256 <artifact> > <artifact>.sha256Optional GPG detached signature:
gpg --detach-sign --armor <artifact>.sha256Automated checksums command:
cd issuer
npm run desktop:checksumsNever commit signing material.
- Store certificates/keys in CI secret manager or dedicated key vault.
- Restrict permissions to release maintainers.
- Rotate credentials on ownership/staff changes.
- Keep audit trail for every signed release.
For each tagged release:
- Build desktop artifacts on OS-specific runners.
- Sign per platform.
- Run smoke install/launch checks.
- Generate checksums.
- Publish GitHub Release assets:
- Windows installer(s)
- macOS DMG
- Linux AppImage/DEB
- checksums (+ optional
.ascsignatures)
Current status in repo:
.github/workflows/desktop.ymlbuilds unsigned desktop bundles per OS and uploads artifacts.- Personal local macOS command handles signing/notarization end-to-end.
For non-technical users, provide a short release page checklist:
- Download installer for your OS.
- Verify signature/checksum only if instructed by admin.
- Install and launch app from OS search menu.
- If blocked by OS security prompt, follow documented trusted-publisher steps.
- Add desktop packaging workflow in
.github/workflows/. - Add release asset naming convention with version suffix.
- Link this guide from
README.mdanddocs/TODO.md. - Add recovery/runbook for expired certificates and failed notarization.