Apple Developer Certificate Setup
This guide explains how to set up Apple Developer certificates for signing and notarizing Fleet packages.
Prerequisites
- Apple Developer Program membership ($99/year)
- macOS with Xcode installed
- Access to developer.apple.com
Certificate Types Needed
For Fleet package distribution, you need two certificates:
- Developer ID Application - Signs the
.appbundle - Developer ID Installer - Signs the
.pkginstaller
Step 1: Create Certificates in Xcode
- Open Xcode
- Go to Xcode > Settings (or Preferences)
- Select the Accounts tab
- Click your Apple ID, then click Manage Certificates
- Click the + button and select:
- Developer ID Application
- Developer ID Installer
Both certificates will be created and stored in your keychain.
Step 2: Find Your Signing Identities
Run this command to list your signing identities:
security find-identity -v -p codesigningYou should see output like:
1) ABCD1234... "Developer ID Application: Your Company (TEAMID)"
2) EFGH5678... "Developer ID Installer: Your Company (TEAMID)"Note the full identity strings - you'll need these for signing.
Step 3: Create an App-Specific Password
Notarization requires an app-specific password (not your Apple ID password).
- Go to appleid.apple.com
- Sign in and go to Sign-In and Security > App-Specific Passwords
- Click Generate an app-specific password
- Name it something like "Fleet Package Notarization"
- Copy the generated password (you won't see it again)
Step 4: Find Your Team ID
- Go to developer.apple.com/account
- Click Membership in the sidebar
- Your Team ID is listed there (10-character alphanumeric)
Step 5: Export Certificates for CI (GitHub Actions)
For automated builds, you need to export your certificates as a .p12 file.
Export from Keychain Access
- Open Keychain Access
- Select login keychain, My Certificates category
- Find your "Developer ID Application" certificate
- Right-click > Export
- Choose Personal Information Exchange (.p12)
- Set a strong password (you'll need this in CI)
- Repeat for "Developer ID Installer" if needed separately
Combine Certificates (Optional)
If you need both certificates in one file:
# Export each certificate, then combine
cat developer-id-application.p12 developer-id-installer.p12 > combined.p12Base64 Encode for GitHub Secrets
base64 -i combined.p12 | pbcopyThe base64 string is now in your clipboard.
Step 6: Configure GitHub Actions Secrets
Go to your repository's Settings > Secrets and variables > Actions and add:
| Secret Name | Value |
|---|---|
APPLE_CERTIFICATE_P12 | Base64-encoded .p12 file contents |
APPLE_CERTIFICATE_PASSWORD | Password you set when exporting |
APPLE_SIGNING_IDENTITY | Full identity string, e.g., Developer ID Application: Your Company (TEAMID) |
APPLE_INSTALLER_IDENTITY | Full installer identity, e.g., Developer ID Installer: Your Company (TEAMID) |
APPLE_ID | Your Apple ID email |
APPLE_APP_SPECIFIC_PASSWORD | App-specific password from Step 3 |
APPLE_TEAM_ID | Your 10-character Team ID |
Local Development
For local builds, set environment variables:
export APPLE_SIGNING_IDENTITY="Developer ID Application: Your Company (TEAMID)"
export APPLE_ID="your@email.com"
export APPLE_APP_SPECIFIC_PASSWORD="xxxx-xxxx-xxxx-xxxx"
export APPLE_TEAM_ID="TEAMID"Or add them to a .env file (don't commit this!):
# .env (add to .gitignore!)
APPLE_SIGNING_IDENTITY="Developer ID Application: Your Company (TEAMID)"
APPLE_ID="your@email.com"
APPLE_APP_SPECIFIC_PASSWORD="xxxx-xxxx-xxxx-xxxx"
APPLE_TEAM_ID="TEAMID"Then source it before building:
source .env
./packages/cursor-carlyle/build.shTesting Without Certificates
For local testing, you can skip signing:
./packages/cursor-carlyle/build.sh --skip-signThe resulting package won't be notarized and may trigger Gatekeeper warnings, but it's useful for development.
To allow running unsigned apps locally:
xattr -cr "/Applications/Cursor Carlyle.app"Troubleshooting
"errSecInternalComponent" during signing
Your certificate may not have the private key. Re-export from Keychain Access ensuring you export the certificate with its private key.
"The signature is invalid" during notarization
Ensure you're using --options runtime when signing. The hardened runtime is required for notarization.
Notarization timeout
Notarization can take 5-15 minutes. If it times out, check status manually:
xcrun notarytool history \
--apple-id "$APPLE_ID" \
--password "$APPLE_APP_SPECIFIC_PASSWORD" \
--team-id "$APPLE_TEAM_ID""The application is damaged" on install
The app wasn't properly signed or notarized. Check:
- All nested binaries are signed
- Notarization completed successfully
- Ticket was stapled with
xcrun stapler staple
Security Notes
- Never commit certificates or passwords to the repository
- Use GitHub's encrypted secrets for CI
- Rotate app-specific passwords periodically
- Consider using a dedicated Apple ID for CI operations