Since MacOS 10.15, all software distributed with Developer ID (not in the App Store) must be notarized by Apple. Essentially, the software must be sent to Apple who will scan the software and perform security checks. They will then issue a "notarization" which can be "stapled" (attached) to the distributed software. When MacOS executes the software, it will query Apple for whether there is a notarization, or validate the stapled notarization, and if no notarization is present, refuse the run the software.
Apple's notary service requires software to be:
- Code signed with a "Developer ID" certificate
- Have the Hardened Runtime capability enabled
- Have the code signature include a timestamp issued by Apple's timestamp service
- Link against the MacOS 10.9 or later SDK
- Have properly formatted XML entitlements
- Cannot include the
com.apple.security.get-task-allow
entitlement set totrue
.
Using signapple sign --hardened-runtime
will cover requirements 2, and 3.
Using a "Developer ID" certificate when doing so will cover requirement 1.
It is up to the developer to ensure that the other requirements are met prior to code signing.
Notarizing an app requires communicated with Apple's notary service. This requires having an App Store Connect API key and knowing the "issuer ID" for the API key to generate an API token to communicate with Apple.
To create an App Store Connect API Key:
- Log in to App Store Connect
- Choose "Users and Access"
- Choose "Integrations" in the bar near the top of the page
- Choose "App Store Connect API" in the left sidebar
- Click the "+" button next to "Active".
- In the popup titled "Generate API Key", enter a name, and enter at least "Developer" in "Access". Then click "Generate".
- Click on the "Download" link to download the private key. Note that you can only download the key once.
To get the issuer ID:
- Log in to App Store Connect
- Choose "Users and Access"
- Choose "Integrations" in the bar near the top of the page
- Choose "App Store Connect API" in the left sidebar
- Click the "Copy" link next to the UUID under the heading "Issuer ID".
signapple notarize
takes 3 arguments: the path to the App Store Connect API Private Key, the Issuer ID UUID string, and the path to the bundle to notarize.
signapple
notarizes applications with the process described in https://developer.apple.com/documentation/NotaryAPI/submitting-software-for-notarization-over-the-web
Stapling is the downloading and attachment of the notarization.
Once Apple has accepted the application and issued a notarization, it can be retrieved from their CloudKit API.
Fortunately, this does not require any particular API keys.
The notarization itself is downloaded from the API, decoded, and placed into the file in the bundle Contents/CodeResources
.