MacOS Code Signing & Notarization for Electron Apps
Contents
Apparently, I cannot get Kairos running (without some magic) or even auto-update on MacOS. There is an entrance fee. I don’t want to go through this again. So here is a complete guide for signing and notarizing Electron apps for distribution outside the Mac App Store.
Prerequisites
- Apple Developer account (USD$99/year)
- Electron app with electron-builder
1. Create Developer ID Application Certificate
- Go to https://developer.apple.com/account/resources/certificates/list
- Click + to create new certificate
- Select Developer ID Application (last option under Software)
- Select G2 Sub-CA (Xcode 11.4.1 or later)
- Upload a Certificate Signing Request (CSR)
Creating the CSR
- Open Keychain Access
- Menu → Keychain Access → Certificate Assistant → Request a Certificate From a Certificate Authority…
- Fill in:
- User Email: your Apple ID email
- Common Name: your name
- CA Email Address: leave blank
- Request is: Saved to disk
- Save the
.certSigningRequestfile - Upload to Apple Developer portal
Download and Install
- Download the generated
.cerfile - Double-click to install
- Select login keychain when prompted
2. Fix “Certificate Not Trusted” Error
If you see “certificate is not trusted” in red:
- Go to https://www.apple.com/certificateauthority/
- Download Developer ID - G2 (under “Subordinate Certification Authority”)
- Double-click to install to login keychain
Your certificate should now show as valid.
3. Configure electron-builder
Add to electron-builder.yml:
1mac:
2 category: public.app-category.productivity
3 target:
4 - dmg
5 - zip
6 icon: build/icon.icns
7 hardenedRuntime: true # Required for notarization
8 gatekeeperAssess: false
9 notarize: true # Enable automatic notarization
electron-builder automatically finds Developer ID Application certificates in your keychain.
4. Create App-Specific Password
Required for notarization:
- Go to https://appleid.apple.com → Sign In
- App-Specific Passwords → Generate
- Name it (e.g., “Electron Notarization”)
- Save the password (format:
xxxx-xxxx-xxxx-xxxx)
5. Local Build with Signing
Set environment variables and build:
1export APPLE_ID="[email protected]"
2export APPLE_APP_SPECIFIC_PASSWORD="xxxx-xxxx-xxxx-xxxx"
3export APPLE_TEAM_ID="XXXXXXXXXX" # 10-char code from certificate
4
5npm run build:mac
You should see:
signing file=dist/mac-arm64/YourApp.app identityName=...
notarizing file=dist/mac-arm64/YourApp.app
notarization successful
6. Verify Signing & Notarization
1# Check code signature
2codesign -dv --verbose=4 dist/mac-arm64/YourApp.app
3
4# Check notarization (should say "source=Notarized Developer ID")
5spctl -a -vvv -t install dist/mac-arm64/YourApp.app
7. CI/CD Setup (GitHub Actions)
Export Certificate as .p12
- Open Keychain Access
- Find Developer ID Application: Your Name certificate
- Right-click → Export → save as
.p12 - Set a strong password
Base64 Encode
1base64 -i ~/Desktop/Certificates.p12 | pbcopy
GitHub Secrets
Go to repo → Settings → Secrets and variables → Actions → Repository secrets
Add these secrets:
| Secret Name | Value |
|---|---|
CSC_LINK | Base64-encoded .p12 (from clipboard) |
CSC_KEY_PASSWORD | Password you set for .p12 |
APPLE_ID | [email protected] |
APPLE_APP_SPECIFIC_PASSWORD | xxxx-xxxx-xxxx-xxxx |
APPLE_TEAM_ID | 10-character team ID |
Workflow Configuration
1- name: Build Electron app
2 run: npm run build:mac
3 env:
4 GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
5 CSC_LINK: ${{ secrets.CSC_LINK }}
6 CSC_KEY_PASSWORD: ${{ secrets.CSC_KEY_PASSWORD }}
7 APPLE_ID: ${{ secrets.APPLE_ID }}
8 APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_APP_SPECIFIC_PASSWORD }}
9 APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
Finding Your Team ID
Look at your certificate in Keychain Access:
Developer ID Application: Your Name (XXXXXXXXXX)
^^^^^^^^^^
This is your Team ID
Or find it at https://developer.apple.com/account → Membership Details.
Notarization Time
Notarization uploads your app to Apple for automated malware scanning:
- Usually takes 10-40 minutes (sometimes longer than build time)
- Fully automated (no human review like App Store)
- Happens on every build
Troubleshooting
“Certificate not trusted”
Install Apple’s intermediate certificate from https://www.apple.com/certificateauthority/
Notarization fails with “team ID” error
Ensure APPLE_TEAM_ID is set and matches your certificate.
CI build fails to find certificate
Verify CSC_LINK is properly base64 encoded and CSC_KEY_PASSWORD is correct.
“No signing identity found”
The certificate must have the private key attached. When exporting to .p12, make sure to export from “My Certificates” category which includes the private key.