Pragmatism in the real world

Notarising a macOS standalone binary

I’ve been writing a simple Swift command line tool called QuickSS. It’s a single file swift file, that I compile to a standalone binaryusing:

swiftc quickss.swift -o quickss

To distribute it on modern Macs, I need to sign it and then get Apple to notarise it.

Signing the binary

To sign the binary, you need a “Developer ID Application” certificate from your paid developer account. If you don’t have one there already create a new one, which requires a CSR from Keychain. Fortunately, the info on what to do is clear.

Download your Developer ID Application certificate and add to Keychain Access.

Next you need its name. This is done using security find-identity -v -p codesigning which gives you a list of certs. You want the text between the " that starts “Developer ID Application:”. The easiest way to get this if you are scripting it is:

IDENTITY=$(security find-identity -v -p codesigning | grep "Developer ID Application" | grep -m 1 -oE '"[^"]+"' | tr -d '"')

To actually sign the binary, use the codesign utility:

codesign --timestamp --options runtime --sign "$IDENTITY" quickss

Notarising

To notarise the binary, you use the notarytool utility within xcrun. This expects a zip or pkg file, so zip up the binary first. You also need to know your Apple developer account’s Team ID, your Apple ID and you need an app-specific password from account.apple.com.

Submit your app for notarising with:

zip -q quickss.zip quickss

xcrun notarytool submit  --wait --no-progress -f json \
    --team-id "$TEAM_ID" \
    --apple-id "$APPLE_ID" \
    --password "$APP_SPECIFIC_PASSWORD" \
    quickss.zip

rm quickss.zip

If it fails, use the submission ID to query the log:

xcrun notarytool log \
    --team-id "$TEAM_ID" \
    --apple-id "$APPLE_ID" \
    --password "$APP_SPECIFIC_PASSWORD" \
    "<submission ID>"

Apple has now notarised your app.

Note: No need to staple

For a standard Mac applications (.app bundles), you can “staple” the notarisation into it. This makes things more efficient for the GateKeeper technology. However, for a standalone binary, this cannot be done as there is no directory into which to store the notarisation file.

If you try to staple, you’ll get The staple and validate action failed! Error 73 with no further information which is not entirely helpful.

For standalone binaries GateKeeper checks directly with Apple’s servers the first time they are run, so stapling is unnecessary.

That’s it

That’s it. You now have a notarised standalone binary that can be easily distributed.

Thoughts? Leave a reply

Your email address will not be published. Required fields are marked *