7 KiB
7 KiB
Code Signing Guide for MapleFile Desktop
This document outlines the code signing requirements and procedures for MapleFile desktop application releases.
Why Code Signing is Important
Code signing provides:
- Integrity Verification: Ensures the binary hasn't been tampered with since signing
- Publisher Authentication: Confirms the software comes from MapleFile/Maple Open Technologies
- User Trust: Operating systems trust signed applications more readily
- Malware Protection: Unsigned apps trigger security warnings that users may ignore
Platform Requirements
macOS
Certificate Types:
- Developer ID Application: Required for distribution outside the Mac App Store
- Developer ID Installer: Required for signed
.pkginstallers
Requirements:
- Apple Developer Program membership ($99/year)
- Developer ID certificates from Apple Developer portal
- Notarization through Apple's notary service
Signing Process:
# Sign the application
codesign --force --options runtime --sign "Developer ID Application: Your Name (TEAM_ID)" \
--timestamp MapleFile.app
# Create a signed DMG
hdiutil create -volname "MapleFile" -srcfolder MapleFile.app -ov -format UDZO MapleFile.dmg
codesign --sign "Developer ID Application: Your Name (TEAM_ID)" MapleFile.dmg
# Notarize (required for macOS 10.15+)
xcrun notarytool submit MapleFile.dmg --apple-id your@email.com --team-id TEAM_ID --wait
xcrun stapler staple MapleFile.dmg
Wails Build Integration:
# Wails supports code signing via environment variables
export MACOS_SIGNING_IDENTITY="Developer ID Application: Your Name (TEAM_ID)"
export MACOS_NOTARIZATION_TEAM_ID="TEAM_ID"
export MACOS_NOTARIZATION_APPLE_ID="your@email.com"
export MACOS_NOTARIZATION_PASSWORD="@keychain:AC_PASSWORD"
wails build -platform darwin/universal
Windows
Certificate Types:
- EV Code Signing Certificate: Extended Validation - highest trust, required for SmartScreen reputation
- Standard Code Signing Certificate: Basic signing, builds reputation over time
Requirements:
- Code signing certificate from a trusted CA (DigiCert, Sectigo, GlobalSign, etc.)
- Hardware token (required for EV certificates)
- SignTool from Windows SDK
Signing Process:
# Sign with timestamp (important for validity after certificate expiry)
signtool sign /tr http://timestamp.digicert.com /td sha256 /fd sha256 ^
/a /n "Maple Open Technologies" MapleFile.exe
# Verify signature
signtool verify /pa /v MapleFile.exe
Wails Build Integration:
# Set environment variables before build
$env:WINDOWS_SIGNING_CERTIFICATE = "path/to/certificate.pfx"
$env:WINDOWS_SIGNING_PASSWORD = "certificate_password"
wails build -platform windows/amd64
Linux
Linux doesn't have a universal code signing requirement, but you can:
-
GPG Signing: Sign release artifacts with GPG
gpg --armor --detach-sign MapleFile.tar.gz -
AppImage Signing: Sign AppImage files
# Import your signing key ./appimagetool --sign MapleFile.AppImage -
Package Signatures: Use distribution-specific signing
.deb:dpkg-sig --sign builder package.deb.rpm:rpm --addsign package.rpm
Secure Update Mechanism
Current State
MapleFile currently does not include automatic updates.
Recommended Implementation
- Update Server: Host update manifests with signed checksums
- Version Checking: Application checks for updates on startup (optional)
- Download Verification: Verify signature before applying update
- Rollback Support: Keep previous version for rollback on failure
Update Manifest Format:
{
"version": "1.2.3",
"release_date": "2025-01-15",
"platforms": {
"darwin-arm64": {
"url": "https://releases.maplefile.com/v1.2.3/MapleFile-darwin-arm64.dmg",
"sha256": "abc123...",
"signature": "base64-encoded-signature"
},
"darwin-amd64": {
"url": "https://releases.maplefile.com/v1.2.3/MapleFile-darwin-amd64.dmg",
"sha256": "def456...",
"signature": "base64-encoded-signature"
},
"windows-amd64": {
"url": "https://releases.maplefile.com/v1.2.3/MapleFile-windows-amd64.exe",
"sha256": "ghi789...",
"signature": "base64-encoded-signature"
}
}
}
Verification Process:
// Pseudocode for update verification
func verifyUpdate(downloadPath, expectedSHA256, signature string) error {
// 1. Verify SHA256 hash
actualHash := sha256sum(downloadPath)
if actualHash != expectedSHA256 {
return errors.New("hash mismatch")
}
// 2. Verify signature (using embedded public key)
if !verifySignature(downloadPath, signature, publicKey) {
return errors.New("signature verification failed")
}
return nil
}
Certificate Management
Storage
- Never commit private keys to version control
- Store certificates in secure vault (e.g., HashiCorp Vault, AWS Secrets Manager)
- Use CI/CD secrets for automated builds
Rotation
- Set calendar reminders for certificate expiry (typically 1-3 years)
- Plan for certificate rotation before expiry
- Test signing process after certificate renewal
Revocation
- Maintain list of compromised certificates
- Have incident response plan for key compromise
- Document process for certificate revocation
Build Pipeline Integration
GitHub Actions Example
name: Release Build
on:
push:
tags:
- 'v*'
jobs:
build-macos:
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
- name: Import Code Signing Certificate
env:
CERTIFICATE_BASE64: ${{ secrets.MACOS_CERTIFICATE }}
CERTIFICATE_PASSWORD: ${{ secrets.MACOS_CERTIFICATE_PASSWORD }}
run: |
echo $CERTIFICATE_BASE64 | base64 --decode > certificate.p12
security create-keychain -p "" build.keychain
security import certificate.p12 -k build.keychain -P "$CERTIFICATE_PASSWORD" -T /usr/bin/codesign
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "" build.keychain
- name: Build and Sign
env:
MACOS_SIGNING_IDENTITY: ${{ secrets.MACOS_SIGNING_IDENTITY }}
run: |
wails build -platform darwin/universal
# Notarize here...
Verification Commands
macOS
# Check signature
codesign -dvv MapleFile.app
# Verify notarization
spctl -a -vv MapleFile.app
Windows
# Check signature
signtool verify /pa /v MapleFile.exe
# PowerShell alternative
Get-AuthenticodeSignature MapleFile.exe