|
| 1 | +# Code Signing Setup Guide |
| 2 | + |
| 3 | +This guide explains how to set up code signing for Local Lens releases to ensure authenticity and build trust with users. |
| 4 | + |
| 5 | +## Why Code Signing? |
| 6 | + |
| 7 | +Code signing provides: |
| 8 | +- **Authenticity**: Proves the software comes from you |
| 9 | +- **Integrity**: Ensures the software hasn't been tampered with |
| 10 | +- **Trust**: Windows Defender and other security software trust signed code |
| 11 | +- **Professional appearance**: Removes "Unknown Publisher" warnings |
| 12 | + |
| 13 | +## Windows Code Signing |
| 14 | + |
| 15 | +### Option 1: Commercial Certificate (Recommended for production) |
| 16 | + |
| 17 | +1. **Purchase a Code Signing Certificate** |
| 18 | + - Recommended providers: DigiCert, Sectigo, GlobalSign |
| 19 | + - Cost: ~$100-400/year |
| 20 | + - Requires identity verification |
| 21 | + |
| 22 | +2. **Install Certificate** |
| 23 | + ```powershell |
| 24 | + # Import certificate to local machine |
| 25 | + certlm.msc |
| 26 | + # Or use PowerShell |
| 27 | + Import-PfxCertificate -FilePath "certificate.pfx" -CertStoreLocation "Cert:\LocalMachine\My" |
| 28 | + ``` |
| 29 | + |
| 30 | +3. **Configure GitHub Secrets** |
| 31 | + - Convert certificate to base64: |
| 32 | + ```powershell |
| 33 | + [Convert]::ToBase64String([IO.File]::ReadAllBytes("certificate.pfx")) |
| 34 | + ``` |
| 35 | + - Add these secrets to your GitHub repository: |
| 36 | + - `WINDOWS_CERTIFICATE`: Base64 encoded certificate |
| 37 | + - `WINDOWS_CERTIFICATE_PASSWORD`: Certificate password |
| 38 | + |
| 39 | +4. **Update GitHub Actions** |
| 40 | + Add to your `release.yml` workflow: |
| 41 | + ```yaml |
| 42 | + - name: Import Code-Signing Certificate |
| 43 | + run: | |
| 44 | + echo "${{ secrets.WINDOWS_CERTIFICATE }}" | base64 --decode > certificate.pfx |
| 45 | + Import-PfxCertificate -FilePath certificate.pfx -CertStoreLocation Cert:\CurrentUser\My -Password (ConvertTo-SecureString -String "${{ secrets.WINDOWS_CERTIFICATE_PASSWORD }}" -AsPlainText -Force) |
| 46 | + |
| 47 | + - name: Build Tauri app (with signing) |
| 48 | + env: |
| 49 | + TAURI_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }} |
| 50 | + TAURI_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }} |
| 51 | + run: | |
| 52 | + cd frontend |
| 53 | + npm run tauri build |
| 54 | + ``` |
| 55 | +
|
| 56 | +### Option 2: Self-Signed Certificate (For testing/development) |
| 57 | +
|
| 58 | +1. **Create Self-Signed Certificate** |
| 59 | + ```powershell |
| 60 | + # Create certificate |
| 61 | + $cert = New-SelfSignedCertificate -Subject "CN=Local Lens" -Type CodeSigning -CertStoreLocation Cert:\CurrentUser\My |
| 62 | + |
| 63 | + # Export certificate |
| 64 | + $password = ConvertTo-SecureString -String "YourPassword" -Force -AsPlainText |
| 65 | + Export-PfxCertificate -Cert $cert -FilePath "LocalLens.pfx" -Password $password |
| 66 | + ``` |
| 67 | + |
| 68 | +2. **Configure Tauri** |
| 69 | + Update `tauri.conf.json`: |
| 70 | + ```json |
| 71 | + { |
| 72 | + "tauri": { |
| 73 | + "bundle": { |
| 74 | + "windows": { |
| 75 | + "certificateThumbprint": "YOUR_CERT_THUMBPRINT", |
| 76 | + "digestAlgorithm": "sha256", |
| 77 | + "timestampUrl": "http://timestamp.digicert.com" |
| 78 | + } |
| 79 | + } |
| 80 | + } |
| 81 | + } |
| 82 | + ``` |
| 83 | + |
| 84 | +## macOS Code Signing |
| 85 | + |
| 86 | +### Apple Developer Account Setup |
| 87 | + |
| 88 | +1. **Join Apple Developer Program** ($99/year) |
| 89 | +2. **Create Certificates** |
| 90 | + - Developer ID Application Certificate |
| 91 | + - Developer ID Installer Certificate |
| 92 | + |
| 93 | +3. **Configure GitHub Secrets** |
| 94 | + ```bash |
| 95 | + # Export certificates |
| 96 | + security export -t certs -f pkcs12 -k login.keychain -P "password" -o certificate.p12 |
| 97 | + |
| 98 | + # Convert to base64 |
| 99 | + base64 certificate.p12 |
| 100 | + ``` |
| 101 | + |
| 102 | + Add secrets: |
| 103 | + - `APPLE_CERTIFICATE`: Base64 encoded certificate |
| 104 | + - `APPLE_CERTIFICATE_PASSWORD`: Certificate password |
| 105 | + - `APPLE_SIGNING_IDENTITY`: Certificate name |
| 106 | + |
| 107 | +4. **Notarization (Optional but recommended)** |
| 108 | + Add secrets: |
| 109 | + - `APPLE_ID`: Your Apple ID email |
| 110 | + - `APPLE_PASSWORD`: App-specific password |
| 111 | + |
| 112 | +## Linux Code Signing |
| 113 | + |
| 114 | +Linux doesn't have built-in code signing, but you can: |
| 115 | + |
| 116 | +1. **GPG Signing** |
| 117 | + ```bash |
| 118 | + # Create GPG key |
| 119 | + gpg --full-generate-key |
| 120 | + |
| 121 | + # Sign packages |
| 122 | + gpg --armor --detach-sign package.deb |
| 123 | + ``` |
| 124 | + |
| 125 | +2. **Package Repository Signing** |
| 126 | + - For Debian packages: Use `debsign` |
| 127 | + - For RPM packages: Use `rpm --addsign` |
| 128 | + |
| 129 | +## Verification Instructions for Users |
| 130 | + |
| 131 | +Add this section to your README: |
| 132 | + |
| 133 | +### Windows |
| 134 | +```powershell |
| 135 | +# Verify certificate |
| 136 | +Get-AuthenticodeSignature "Local_Lens_v1.0.0_x64-setup.exe" |
| 137 | +
|
| 138 | +# Check certificate details |
| 139 | +$sig = Get-AuthenticodeSignature "Local_Lens_v1.0.0_x64-setup.exe" |
| 140 | +$sig.SignerCertificate | Format-List Subject, Issuer, NotAfter |
| 141 | +``` |
| 142 | + |
| 143 | +### macOS |
| 144 | +```bash |
| 145 | +# Verify signature |
| 146 | +codesign -v Local_Lens_v1.0.0_x64.dmg |
| 147 | + |
| 148 | +# Check certificate details |
| 149 | +codesign -dv Local_Lens_v1.0.0_x64.dmg |
| 150 | +``` |
| 151 | + |
| 152 | +### Linux |
| 153 | +```bash |
| 154 | +# Verify GPG signature |
| 155 | +gpg --verify package.deb.sig package.deb |
| 156 | +``` |
| 157 | + |
| 158 | +## Security Best Practices |
| 159 | + |
| 160 | +1. **Protect Private Keys** |
| 161 | + - Never commit certificates to Git |
| 162 | + - Use GitHub Secrets for sensitive data |
| 163 | + - Rotate certificates before expiration |
| 164 | + |
| 165 | +2. **Timestamping** |
| 166 | + - Always use timestamp servers |
| 167 | + - Ensures signatures remain valid after certificate expires |
| 168 | + |
| 169 | +3. **Verification** |
| 170 | + - Test signed binaries before release |
| 171 | + - Document verification steps for users |
| 172 | + |
| 173 | +4. **Backup** |
| 174 | + - Keep secure backups of certificates |
| 175 | + - Document recovery procedures |
| 176 | + |
| 177 | +## Alternative: Reproducible Builds |
| 178 | + |
| 179 | +If code signing is not feasible, focus on reproducible builds: |
| 180 | + |
| 181 | +1. **Docker-based builds** |
| 182 | +2. **Deterministic compilation** |
| 183 | +3. **Source code transparency** |
| 184 | +4. **Community verification** |
| 185 | + |
| 186 | +This provides transparency even without traditional code signing. |
0 commit comments