notarize
notaryjerk notarize lets you submit signed binaries to Apple's notarization service.
Prerequisites
In order to be able to use Apple's notarization service, you must have signed up with Apple (about 100,-€/p.a.) and created an API-Key to access the "App Store Connect API".
In the webinterface, you need create a new Developer key and obtain the following data:
| name | variable | (non-working) example values |
|---|---|---|
| Apple Issuer ID | APPLE_ISSUER_ID |
57246542-96fe-1a63-e053-0824d011072a |
| Apple Key ID | APPLE_KEY_ID |
2X9R4HXF34 |
| Apple Private Key file | APPLE_KEY_FILE |
private_key.pem |
(I'll use the names in the variable column to reference these requirements in the scripts below)
Preparation
You can only notarize signed applications and binaries.
Also, the notarization service accepts only .zip archives and .dmg disk images.
If you want to notarize a single binary, you have to wrap it into a zip file first.
zip mybin.zip coolcmdlineutility
zip -r myapp.zip MyApp.app
Notarization
Once you have your credentials and the archive file(s), you can simply notarize the latter with:
notaryjerk notarize \
--issuer-id "${APPLE_ISSUER_ID}" \
--key-id "${APPLE_KEY_ID}" \
--private-keyfile "${APPLE_KEY_FILE}" \
myapp.zip myapp.zip
This will upload the archive(s) to the cloud and submit it to the notarization service. The script will return immediately.
The notarization process takes a short while (seconds, minutes... depending on Apple's resources), and might fail (e.g. if invalid or harmful content was detected)... or because your key is currently unusable (mostly this is because Apple keeps updating their Terms and Conditions and you have to accept them again and again and again).
Status-File
If you want to catch the result of the notarization process (so you know that everything went well),
pass the --wait option, which will make notaryjerk wait until it receives a status notification
from the service (or a configurable timeout has been reached).
notaryjerk notarize \
--issuer-id "${APPLE_ISSUER_ID}" \
--key-id "${APPLE_KEY_ID}" \
--private-keyfile "${APPLE_KEY_FILE}" \
--wait \
--status-file notarize.json \
mybin.zip
The above also uses the --status-file argument, which will output the result of the notarization
into a machine raedable file, that might look like this:
{
"5ea058bf-f80e-4e73-b02b-8d84fca3b24a": [
true,
{
"logFormatVersion": 1,
"jobId": "5ea058bf-f80e-4e73-b02b-8d84fca3b24a",
"status": "Accepted",
"statusSummary": "Ready for distribution",
"statusCode": 0,
"archiveFilename": "mybin.zip",
"uploadDate": "1970-01-01T00:00:01.102Z",
"sha256": "5dd6ddbf653e7c5ab57607220ecb41b6a1d55bd123fe8cd15c8dfc4efede8d31",
"ticketContents": [
{
"path": "coolcmdlineutility",
"digestAlgorithm": "SHA-256",
"cdhash": "625d1bc6c2fe6b34845b26615b3ab54c5ec6acf0",
"arch": "x86_64"
},
{
"path": "coolcmdlineutility",
"digestAlgorithm": "SHA-256",
"cdhash": "8227e9f1fa9a8c6015eaf2f777cca324cbbfa154",
"arch": "arm64"
}
],
"issues": null
}
]
}
Status-Webhook
Alternatively (e.g. if you don't want to wait until the notarization process has completed), you can specify a webhook that will be called (by the Apple service) on finishing the process:
notaryjerk notarize \
--issuer-id "${APPLE_ISSUER_ID}" \
--key-id "${APPLE_KEY_ID}" \
--private-keyfile "${APPLE_KEY_FILE}" \
--webhook https://example.com/notariz \
mybin.zip myapp.zip
The webhook will have a payload like so:
{
"signature": "J8uPBwO2...",
"cert_chain": "pjZljv/o...",
"payload": "{\"completed_time\": \"1970-01-01T00:12:20.624Z\", \"event\": \"processing-complete\", \"start_time\": \"1970-01-01T00:00:04.379Z\", \"submission_id\": \"5ea058bf-f80e-4e73-b02b-8d84fca3b24a\", \"team_id\": \"UWO5Z8GT3G\"}"
}