Notarization made a bit simpler

As of Mojave 10.14.5 and in Catalina, notarization of apps and other executable code becomes a requirement for developers. Although notarizing a simple app within Apple’s Xcode development system is both straightforward and very well documented, a week ago I drew attention to the fact that notarizing other types of code, such as command tools, is a complex if not byzantine process which – as far as I can see – is essentially undocumented.

This wouldn’t have become so rapidly important had it not been for a surprise sprung on us at WWDC 2019, shortly after the first beta-release of Catalina was being installed by developers: notarization rules are not just going to apply to apps and kernel extensions, but also to all types of executable code, including command tools. This was a surprise because, when Apple first detailed notarization in WWDC 2018, it only made mention of the requirement for apps. So over the last year, many developers have been busy getting their apps notarized, but no one had started similar preparations on command tools, it appears.

Although I’m a fan of Apple’s Notary Service, and have only had good experiences with it over that year, and I’m a strong supporter of notarization for improved security, I hate being given no notice, and hate trying to perform critical tasks without any useful documentation. Thankfully, in response to those articles, Rosyna Keller @rosyna has been kind enough to provide more specific advice. Here I’m going to pass that on, as far as I understand it.

1. An Info.plist isn’t required

The opening step of my process to notarize a command tool is to add an Info.plist containing three key items: a Bundle Identifier, Bundle Name, and Bundle Versions String, Short. This isn’t apparently necessary for signing or for notarization to be successful.

My information had come from Apple’s now-archived Code Signing Guide, which includes a section describing how to add an Info.plist to a single-file tool. This has been widely cited by others as a required step before trying to sign a Mach-O file such as a command tool. In recent versions of Xcode, and with modern signatures, an Info.plist isn’t apparently needed any more.

However, you may still wish to add one, as the information which it adds to a Mach-O executable is useful even though no longer essential. The time saved by omitting that first step, and its relative simplicity, don’t have any major impact on the overall process, in my experience.

2. A more useful check of the completed tool

At the end of the Xcode phase, an even more useful command to use when checking your signed and hardened tool is
codesign -dvvvr - toolname
which returns additional detail such as
Format=Mach-O thin (x86_64)
CodeDirectory v=20500 size=549 flags=0x10000(runtime) hashes=8+5 location=embedded
Hash type=sha256 size=32
CandidateCDHash sha256=202118773aad83a1f492f55a7be0b24170126d7a
Hash choices=sha256
Signature size=8926
Authority=Developer ID Application: Howard Oakley (QWY4LRW926)
Authority=Developer ID Certification Authority
Authority=Apple Root CA
Timestamp=11 Jun 2019 at 09:22:57
Info.plist entries=12
Runtime Version=10.14.0
Sealed Resources=none
designated => anchor apple generic and identifier "co.eclecticlight.blowhole" and (certificate leaf[field.1.2.840.113635.] /* exists */ or certificate 1[field.1.2.840.113635.] /* exists */ and certificate leaf[field.1.2.840.113635.] /* exists */ and certificate leaf[subject.OU] = QWY4LRW926)

If you haven’t added an Info.plist file, you may prefer using that command.

3. Consider submitting tools together

If you have more than one tool or other item which needs to be notarized, then rather than submitting them individually to the Notary Service, you can Zip them together and submit the single archive. This is most obviously a wise choice when they’re going to be delivered together to the user. I don’t know whether it would be appropriate for several separate tools which are distributed separately: in that case, there seem many good reasons for getting them notarized individually in any case.

4. Thing will improve

One of the current limitations in notarization, in case you hadn’t noticed, is that there’s no means of stapling a ticket to a standalone Mach-O binary like a command tool. This means that, to staple its ticket, you have to put it into something like an Installer package, and processing that fills the second stage in my flowchart.

It is expected that at some time in the near future, it will be possible to staple the notarization ticket to standalone Mach-O files, which will simplify the whole process and add greater flexibility. Apple hasn’t released any information about this yet, and there’s no indication as to when this might change.

That said, I prefer to deliver my command tools in Installer packages, so that users can easily install them. In those cases, you may still find it best to follow the process I have detailed.

5. If you can’t notarize at all

I’m delighted to report that Matt has finally figured out why he has been unable to notarize at all: included in his Xcode configuration was membership of two old development ‘teams’, which hadn’t accepted the latest developer agreement. It appears that their presence was marking all his developer accounts as not having accepted the agreement, thus preventing notarization.

If you are having problems with notarizing anything, check your developer accounts and teams configured in Xcode, and clear out old ones which might cause similar problems.

Michael Tsai and I, and no doubt many other developers, have implored Apple to provide both conceptual documentation, so that we can understand what we’re trying to achieve, and explicit workflows for other common tasks such as notarizing command tools. I hope that Apple does this very soon.

Thank you again to Rosyna Keller and others who have helped so far.