macOS Code Signing Setup
This guide explains how to set up Apple Developer certificates for signing and notarizing Trial Submission Studio releases.
Prerequisites
- Active Apple Developer Program membership ($99/year)
- macOS with Xcode Command Line Tools installed
- Access to the GitHub repository settings (for adding secrets)
Step 1: Create Developer ID Application Certificate
1.1 Request Certificate from Apple
- Open Keychain Access (Applications → Utilities → Keychain Access)
- Go to Keychain Access → Certificate Assistant → Request a Certificate From a Certificate Authority
- Fill in:
- Email Address: Your Apple ID email
- Common Name: Your name
- Request is: Saved to disk
- Save the
.certSigningRequestfile
1.2 Create Certificate in Apple Developer Portal
- Go to Apple Developer Certificates
- Click + to create a new certificate
- Select Developer ID Application (NOT “Developer ID Installer”)
- Upload your
.certSigningRequestfile - Download the generated
.cerfile - Double-click the
.cerfile to install it in Keychain Access
1.3 Verify Certificate Installation
Run this command to verify the certificate is installed:
security find-identity -v -p codesigning
You should see output like:
1) ABCDEF1234567890... "Developer ID Application: Your Name (TEAM_ID)"
Step 2: Export Certificate for GitHub Actions
2.1 Export as .p12
- Open Keychain Access
- Find your certificate: “Developer ID Application: Your Name”
- Right-click → Export
- Choose .p12 format
- Set a strong password (you’ll need this later)
- Save the file
2.2 Convert to Base64
base64 -i YourCertificate.p12 | pbcopy
This copies the base64-encoded certificate to your clipboard.
Step 3: Create App-Specific Password
Apple requires an app-specific password for notarization (not your regular Apple ID password).
- Go to Apple ID Account
- Sign in with your Apple ID
- Navigate to App-Specific Passwords
- Click Generate an app-specific password
- Label: “GitHub Actions Notarization”
- Copy the generated password (format:
xxxx-xxxx-xxxx-xxxx)
Step 4: Find Your Team ID
- Go to Apple Developer Account
- Click Membership in the left sidebar
- Copy your Team ID (10-character alphanumeric string)
Step 5: Configure GitHub Secrets
Go to your repository’s Settings → Secrets and variables → Actions and add these 7 secrets:
| Secret Name | Description | How to Get |
|---|---|---|
APPLE_DEVELOPER_CERTIFICATE_P12_BASE64 | Base64-encoded .p12 certificate | Step 2.2 output |
APPLE_DEVELOPER_CERTIFICATE_PASSWORD | Password you set when exporting .p12 | Step 2.1 |
APPLE_CODESIGN_IDENTITY | Full certificate name | security find-identity -v -p codesigning output |
APPLE_NOTARIZATION_APPLE_ID | Your Apple ID email | Your Apple Developer email |
APPLE_NOTARIZATION_APP_PASSWORD | App-specific password | Step 3 output |
APPLE_DEVELOPER_TEAM_ID | 10-character Team ID | Step 4 |
CI_KEYCHAIN_PASSWORD | Random secure password | Generate any secure string |
Example Values
APPLE_CODESIGN_IDENTITY: Developer ID Application: Ruben Talstra (ABCD1234EF)
APPLE_DEVELOPER_TEAM_ID: ABCD1234EF
APPLE_NOTARIZATION_APPLE_ID: your.email@example.com
Local Development
Create App Bundle
cargo build --release
./scripts/macos/create-bundle.sh
Sign Locally (for testing)
./scripts/macos/sign-local.sh
Verify Bundle
./scripts/macos/verify-bundle.sh
Test Gatekeeper
./scripts/macos/test-gatekeeper.sh
open "Trial Submission Studio.app"
Troubleshooting
“No Developer ID Application certificate found”
Ensure the certificate is in your login keychain and not expired:
security find-identity -v -p codesigning
“The signature is invalid”
Re-sign with the --force flag:
codesign --force --options runtime --sign "Developer ID Application: ..." "Trial Submission Studio.app"
“Notarization failed”
Check the notarization log:
xcrun notarytool log <submission-id> --apple-id "..." --password "..." --team-id "..."
Common issues:
- Missing hardened runtime (
--options runtime) - Problematic entitlements (JIT, unsigned memory)
- Unsigned nested code
Security Notes
- Never commit certificates or passwords to the repository
- Use GitHub’s encrypted secrets for all sensitive values
- The app-specific password is NOT your Apple ID password
- Rotate credentials if you suspect they’ve been compromised