you're reading...


What’s New with Xcode 13 Notarization

WWDC 2021 has ended. Now it’s time to look at all those developer tools Apple delivered and see how it can improve our work as software engineers.

One notable change for macOS developers is a new notarization tool called notarytool. For one, the new tool promises faster uploads thanks to S3 transport optimizations. To clarify, it would upload your binary to one of Amazon Web Services’ many servers scattered throughout the globe, which would have a better chance of being nearer to you.

Changes in Notarization Workflow

Though more importantly notarytool has the ability to wait for notarization to complete. To put it differently, the feature removes the need in your custom notarization workflow have a polling loop which repeatedly checks for notarization status. Therefore reducing the amount of automation code that you need to write or maintain.

Furthermore there is a dedicated command to fetch notarization logs. To emphasize, previously you would need two steps to obtain those logs. Firstly to get notarization information which contains the log URL. Secondly another tool needs to fetch that URL.

Equally important is a set of commands for managing keychain entries for use with notarization. Both API key and app-specific password authentication methods can use the keychain. A point often overlooked is that you can swap authentication methods without any code change done to the notarization workflow. In essence, updating the keychain entry to the new authentication method would be sufficient.

By comparison, some workflow elements are unchanged. Chiefly steps surrounding stapling stays the same. Accordingly the following activity diagram shows the updated generic notarization workflow as per Xcode 13 Beta 3. To emphasize, there is only one polling loop—waiting for the notarization to be available for stapling. Given that notarytool would handle the task to poll the notarization status by itself.

Xcode 13 notarization workflow

Submitting Notarization

You initiate the workflow by submitting a notarizable artifact. As of Xcode 13, you would use notarytool submit to upload the package and optionally make it wait for the Notarization Service to finish processing the package. As a result you would get a UUID identifying your upload.

For example, the following snippet begins the notarization workflow by uploading MyGreatApp.zip using an API Key file and let the tool wait for the process to complete.

xcrun notarytool submit MyGreatApp.zip \
  --wait \
  --key ~/.appstoreconnect/private_keys/AuthKey_123456789A.p8 \
  --key-id 123456789A \
  --issuer 00000000-0000-0000-0000-000000000000

Stapling Results

Should notarization shows a successful result, you should staple the notarization ticket back to the original artifact. Presently stapling hasn’t change in Xcode 13. Thus it uses the same command as with previous Xcode versions and uses the same arguments.

Refer to the following snippet for an example on how to staple notarization ticket into an app bundle.

xcrun stapler staple MyGreatApp.app

To emphasize, stapling does not require authentication. A notarization ticket is public information; the same information as what Gatekeeper would try to obtain when the ticket is not embedded in the bundle.

Getting Logs

Should the notarization process completes with a failure result, you would want to know why. Correspondingly the notarization log would provide this information.

Run notarytool log to obtain the log information about a notarization request. Provide the command with the UUID of the notarization request along with the standard authentication information needed by notarytool.

xcrun notarytool log a5e801fe-96ae-4fe7-bbaa-aff532326471 \
  --key ~/.appstoreconnect/private_keys/AuthKey_123456789A.p8 \
  --key-id 123456789A \
  --issuer 00000000-0000-0000-0000-000000000000

In addition, notarization logs would always be available upon completion of the notarization process. In other words, you can obtain these logs even when notarization completes successfully. Then again, Apple have not provide any data retention guarantees for these logs; thus you should download and archive this as soon as possible.

Authentication and Authorization

Similar to Xcode 12, there are two ways to authenticate to the Notary Service—via app-specific password or an API key file. But this time you can place the API key file anywhere within the local file system. To clarify, you are no longer restricted to maintain API key files in certain pre-defined directories as what altool requires.

What’s more, notarytool is able to manage keychain entries for you. It can save either an API key file or an app-specific password into the keychain. Subsequent invocations of notarytool would refer to this credential name. This would be useful since the keychain is additionally encrypted with the user’s login password, making it less prone to leaks since even administrators won’t be able to access the keychain without knowledge of the logged-in password.

In contrast, the authorization flows remains the same. You would use the App Store Connect web application to assign roles to pre-existing Apple ID e-mail addresses or generate an API key in the same manner as before.

Authentication on the Command Line

The following is an example on how to get notarization history via an API key file. Markedly this file is now specified by a path. Nevertheless the example shows retrieval of the API key file in one of the pre-defined locations expected by altool.

xcrun notarytool history \
  --key ~/.appstoreconnect/private_keys/AuthKey_123456789A.p8 \
  --key-id 123456789A \
  --issuer 00000000-0000-0000-0000-000000000000

Whereas the following is an example on the same command but using an app-specific password to authenticate with the Notary Service.

xcrun notarytool history \
  --apple-id 'johnny.appleseed@example.com' \
  --password '99-apples-on-the-wall' \
  --team-id 123456789A

Authentication using the Keychain

The store-credentials sub-command of notarytool would store either an API key or an app-specific password into the Keychain. You would give this command a name for the keychain entry. Accordingly, use this name in subsequent invocations to notarytool as its authentication information.

The following snippet shows an example on how to store an API key into the Login Keychain and name the entry as “My-Notarization-Key”

xcrun notarytool store-credentials My-Notarization-Key \
  --key ~/.appstoreconnect/private_keys/AuthKey_123456789A.p8 \
  --key-id 123456789A \
  --issuer 00000000-0000-0000-0000-000000000000

In similar fashion the following snippet stores an app-specific password into the Keychain as “My-Notarization-Key”.

xcrun notarytool store-credentials My-Notarization-Key \
  --apple-id 'johnny.appleseed@example.com' \
  --password '99-apples-on-the-wall' \
  --team-id 123456789A

Given the above examples, storing a notarization credential would overwrite any pre-existing credential—should one with the same name is present in the Keychain. In effect, the last credential stored would prevail.

Correspondingly the notarytool would access a notarization credential through the --keychain-profile command-line argument. When this argument is present, you would not need to specify parameters pertaining to an API key file nor an app-specific password.

For example, the following snippet accesses notarization history through a credential stored in the Keychain.

xcrun notarytool history \
  --keychain-profile My-Notarization-Key

Next Steps

You should try out notarytool and see how it can simplify your notarization script. Despite that Xcode 13 is in beta, it can be considered ready for production use as far as notarization goes.

Unquestionably you would need to download Xcode beta and configure the command line tools to use it. To that end, use the xcode-select command to select the preferred copy of Xcode for use in the command line, as per the following example.

xcode-select -s /Applications/Xcode-beta.app

Markedly altool (the old notarization tool) is present and usable in Xcode 13 beta. Though when Xcode 13 comes out of beta, altool will be officially deprecated. To put it differently, you should update your custom notarization workflow scripts to use the new tool before Xcode 14 is released, otherwise risk breaking your delivery pipelines.

Avoid App Review rules by distributing outside the Mac App Store!

Get my FREE cheat sheets to help you distribute real macOS applications directly to power users.

* indicates required

When you subscribe you’ll also get programming tips, business advices, and career rants from the trenches about twice a month. I respect your e-mail privacy.


No comments yet.

Leave a Reply