Mastering macOS Notarization: Secure Your Apps for Gatekeeper
macOS Notarization is a crucial step for distributing your applications outside the Mac App Store. It ensures users can trust your software, as Gatekeeper performs security checks on notarized apps. This article provides a comprehensive guide to understanding and implementing notarization for your macOS projects.

What is macOS Notarization and Why is it Essential?
macOS Notarization is an automated Apple service that scans your macOS software for malicious content, identifies code-signing issues, and then issues a 'ticket' to indicate that the software is safe. When users attempt to open your notarized application, macOS Gatekeeper can verify this ticket, assuring users that your software doesn't contain known malware and hasn't been tampered with.
Since macOS Catalina (10.15) and later, notarization is a mandatory requirement for all Mac software distributed outside the Mac App Store. If you distribute an unnotarized application, users will encounter a warning preventing them from launching your app without manually overriding security settings, which is a poor user experience and significantly impacts trust. Understanding and integrating notarization into your development workflow is therefore crucial for successful macOS app distribution.
Prerequisites for Notarization
Before you can notarize your macOS application, ensure you have the following prerequisites in place:
- Apple Developer Program Membership: Notarization requires an Apple Developer Program membership. This gives you access to the code-signing certificates necessary for the process.
- Xcode: You'll need Xcode (version 10.1 or later, but using the latest stable version is highly recommended) installed on your development machine. Xcode includes the command-line tools for signing and notarizing.
- App-Specific Password: While you can use your Apple ID password for notarization, Apple strongly recommends using an app-specific password for enhanced security. You can generate one from your Apple ID account page on appleid.apple.com.
- Code Signing Identity: Your application must be correctly code-signed with a Developer ID Application certificate. This is different from the Mac App Store Distribution certificate. Ensure your project's build settings in Xcode are configured to use the correct Developer ID identity.
- Hardened Runtime: Your executable must be built with the Hardened Runtime capability enabled. This is a security measure that protects your app against certain classes of attacks. You enable this in Xcode's Signing & Capabilities tab.
Configuring Your Xcode Project for Notarization
Proper Xcode project configuration is the first step towards successful notarization. Here's what you need to check and enable:
1. Code Signing Identity
Ensure your target's 'Signing & Capabilities' tab uses your 'Developer ID Application' certificate for distribution builds. Xcode usually handles this automatically if you've added your Developer ID account.
2. Hardened Runtime
You must enable Hardened Runtime for your primary executable and any helper executables or bundles. In Xcode, go to your target's 'Signing & Capabilities' tab, click the '+' button, and search for 'Hardened Runtime'. Add it, and ensure it's checked.
3. Entitlements
Sometimes, you might need specific entitlements that Hardened Runtime restricts by default. If your app requires access to cameras, microphones, or certain file system locations, you'll need to explicitly add those entitlements. For example, to allow JIT compilation (if your app uses JavaScriptCore or other JIT engines), you would add com.apple.security.cs.allow-jit.
Here's how you might add an entitlement in your .entitlements file:
Note: Use entitlements sparingly and only when absolutely necessary, as they can reduce the security posture of your application. Always refer to Apple's documentation for the most current entitlement keys and their implications.
4. Remove Unnecessary Bundles
Ensure your application bundle doesn't contain debug symbols (.dSYM files) or other development-only content that shouldn't be shipped to users. These can bloat your app and sometimes cause notarization failures.
Step-by-Step Notarization Process (Xcode Archive)
The easiest way to notarize your application is often directly through Xcode's Organizer.
-
Archive Your Application: In Xcode, select
Product > Archive. This will build your application for distribution and open the Organizer window. -
Distribute App: In the Organizer window, select your archived app and click 'Distribute App'.
-
Choose Distribution Method: Select 'Developer ID' as the distribution method, then click 'Next'.
-
Choose Destination: Select 'Notarize' as the destination, then click 'Next'. Ensure 'Upload your app's archive to the Apple notarization service' is selected.
-
Review and Upload: Xcode will prompt you to authenticate with your Apple ID and an app-specific password. Review the summary, then click 'Notarize'. Xcode will then upload your archive to Apple's notarization service.
It's crucial to use an app-specific password here, not your primary Apple ID password.
-
Monitor Notarization Status: After uploading, you'll see a message indicating that the upload was successful and that Apple is processing your request. You can monitor the status in Xcode's Organizer or using the
notarytoolcommand-line utility (see next section). -
Staple the Ticket: Once notarization is complete (you'll receive an email from Apple), you need to 'staple' the notarization ticket to your application. This embedding allows Gatekeeper to confirm notarization even when offline. Xcode often handles this automatically when you export your notarized app. To export, go back to the Organizer, select the notarized archive, click 'Distribute App' -> 'Developer ID' -> 'Export'. Xcode will then export a notarized and stapled
.appor.pkg.
Notarization via Command Line (notarytool)
For automation scripts or when you need more control, notarytool (available with Xcode 13 and later) is the preferred command-line tool. It replaces the older altool.
1. Build Your Application
First, build your application and package it into a .dmg, .pkg, or .zip file. For a simple app, you might zip the .app bundle:
Your exportOptions.plist would look something like this:
2. Upload for Notarization
Use notarytool to upload your zipped app for notarization. Replace YOUR_APPLE_ID and YOUR_APP_SPECIFIC_PASSWORD with your credentials:
--apple-id: Your Apple ID email.--password: Your app-specific password.--team-id: Your 10-character Developer Team ID (found in your Apple Developer account).--wait: This flag makes the command wait until the notarization process is complete, which is very useful for scripting. Without it, you'd have to poll the status.
3. Staple the Notarization Ticket
Once notarytool reports success, you need to staple the notarization ticket to your original application bundle. This is crucial for offline Gatekeeper verification.
- Replace
"build/export/YourApp.app"with the actual path to your.appbundle.
4. Verify Stapling
You can verify that your app is properly stapled and notarized using the spctl command:
A successful output will include accepted and source=Notarized Developer ID.
build/export/YourApp.app: accepted
source=Notarized Developer ID
Now your YourApp.app (or .dmg/.pkg if you notarized those) is ready for distribution!
Troubleshooting Common Notarization Issues
Notarization can sometimes be finicky. Here are common issues and their solutions:
- Invalid Signature Issues: This is usually due to incorrect code signing. Ensure all embedded executables, frameworks, and bundles are signed with your Developer ID certificate and that the Hardened Runtime is enabled globally for all executables. Use
codesign --verify -vvv YourApp.appandspctl -a -vvv YourApp.app. - Missing Hardened Runtime: Your notarization submission will fail if Hardened Runtime isn't enabled for all executables. Double-check your Xcode build settings and
.entitlements. - Network Issues: Notarization requires an active internet connection to communicate with Apple's servers. Proxy settings or firewalls can sometimes interfere.
- App-Specific Password Problems: Ensure you're using a correct app-specific password, not your primary Apple ID password. Revoke and generate a new one if unsure.
- Conflicting Entitlements: If you've added entitlements, ensure they are correctly formatted and genuinely required. Misconfigured entitlements can cause validation failures.
- Older macOS/Xcode Versions: Always use the latest stable Xcode version for notarization. Apple may introduce new requirements or update their services that older versions don't support.
- Monitoring Submission Logs: If notarization fails, Apple sends an email with a log file URL. Download and analyze this log carefully; it often contains specific reasons for rejection.
Common Interview Questions
Do I need to notarize my app if it's distributed via the Mac App Store?
No, if your application is distributed exclusively through the Mac App Store, it does not require separate notarization. The App Store submission process includes its own security checks and validation, which covers the requirements. Notarization is specifically for macOS applications distributed outside the Mac App Store.
What happens if I try to distribute an unnotarized app on macOS Catalina or later?
If you distribute an unnotarized application on macOS Catalina (10.15) or later, users will encounter a Gatekeeper warning stating, '"YourApp" cannot be opened because the developer cannot be verified.' They will then have to manually override their security preferences (by right-clicking the app and choosing 'Open', or via System Settings/Security & Privacy) to launch the app, which is a significant deterrent and a poor user experience. Notarization is essential for user trust and smooth distribution.
Can I notarize a macOS installer package (.pkg) or a disk image (.dmg)?
Yes, absolutely. You can notarize `.pkg` installer packages and `.dmg` disk images directly. When notarizing a `.dmg` or `.pkg`, the `notarytool` command works the same way. When stapling, you would apply `stapler staple` to the `.dmg` or `.pkg` file itself. This means that when a user downloads your disk image or runs your installer, Gatekeeper can verify its notarization status before allowing it to proceed.