Notarization Notes (SaneBar)
July 2, 2026 · View on GitHub
What has caused Apple notarization to pass or fail for SaneBar.
TL;DR pattern
Notarization succeeds when every executable Apple can see is:
- signed with Developer ID Application (correct Team ID)
- signed with a secure timestamp
- free of debug-only entitlements (especially
com.apple.security.get-task-allow)
The core gotcha
codesign --verify --deep --strict SaneBar.app does not inspect executables embedded inside .zip resources — Apple's notarization service does. A locally "clean" bundle can still be rejected for a bad binary hiding inside a zip in Resources.
Historical note: a LaunchAtLogin helper app shipped inside a zip in Resources once caused a notarization rejection (unsigned, debug-entitled helper) that local verification missed. That dependency is long gone; the lesson — validate zip contents, not just the outer bundle — is what matters.
How to validate before submitting
- Run a release build locally (without notarizing):
./Scripts/SaneMaster.rb release --skip-notarize --version X.Y.Z
- Verify the exported app:
codesign --verify --deep --strict build/Export/SaneBar.appspctl -a -vvv build/Export/SaneBar.app
- Submit:
xcrun notarytool submit <archive> --keychain-profile notarytool --wait
- If rejected, download the log:
xcrun notarytool log <JOB_ID> --keychain-profile notarytool
Notes
- Apple's
notarytool logincludes asha256of the uploaded archive. If it doesn't match your local artifact, you are comparing against the wrong build. - If any zip in Resources ships executables, they must be Release builds signed with Developer ID + timestamp and without
get-task-allow.