monorepo/native/desktop/maplefile/docs/CODE_SIGNING.md

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:

  1. Integrity Verification: Ensures the binary hasn't been tampered with since signing
  2. Publisher Authentication: Confirms the software comes from MapleFile/Maple Open Technologies
  3. User Trust: Operating systems trust signed applications more readily
  4. 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 .pkg installers

Requirements:

  1. Apple Developer Program membership ($99/year)
  2. Developer ID certificates from Apple Developer portal
  3. 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:

  1. Code signing certificate from a trusted CA (DigiCert, Sectigo, GlobalSign, etc.)
  2. Hardware token (required for EV certificates)
  3. 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:

  1. GPG Signing: Sign release artifacts with GPG

    gpg --armor --detach-sign MapleFile.tar.gz
    
  2. AppImage Signing: Sign AppImage files

    # Import your signing key
    ./appimagetool --sign MapleFile.AppImage
    
  3. 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.

  1. Update Server: Host update manifests with signed checksums
  2. Version Checking: Application checks for updates on startup (optional)
  3. Download Verification: Verify signature before applying update
  4. 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

References