notarytool is Apple's command-line client for the notary service. You hand it a zip, dmg, or pkg, it uploads the build for notarization, and it reports back the verdict. It ships with Xcode 13 and later, and since November 2023 it is the only supported CLI path: the old altool notarization workflow was switched off entirely.
The submit, wait, staple flow
- 1
Sign the build first
Notarization checks an existing signature; it does not create one. Sign with a Developer ID Application certificate, hardened runtime enabled, and a secure timestamp before submitting.
- 2
Submit and wait
xcrun notarytool submit uploads the artifact. The --wait flag blocks until Apple returns Accepted or Invalid, which usually takes a few minutes.
- 3
Staple the ticket
xcrun stapler staple attaches the notarization ticket to the app or disk image, so Gatekeeper can verify it even when the user's Mac is offline.
# Submit with an App Store Connect API key and wait for the verdict xcrun notarytool submit MyApp.zip \ --key AuthKey_ABC123DEFG.p8 \ --key-id ABC123DEFG \ --issuer 12345678-aaaa-bbbb-cccc-1234567890ab \ --wait # Attach the ticket to the .app (staple the .dmg/.pkg too if you ship one) xcrun stapler staple MyApp.app # When a submission comes back Invalid, read the reasons xcrun notarytool log <submission-id> --key ... --key-id ... --issuer ...
Authentication options
- An App Store Connect API key (.p8 plus Key ID and Issuer ID). The right choice for CI: no Apple ID, no 2FA prompt.
- An Apple ID with an app-specific password, passed with --apple-id, --password, and --team-id. Works, but ties automation to a person's account.
- A stored keychain profile: run notarytool store-credentials once on a machine, then reference it with --keychain-profile in every later call.
Reading a rejection
When the verdict is Invalid, the submission log lists every issue with a path and a reason. The recurring ones: a binary inside the bundle is unsigned or signed without hardened runtime, the signature has no secure timestamp, or an embedded framework was signed ad hoc by a build tool. Fix the signing, re-sign, resubmit.