How to Notarize Go binary for macOS

Starting with macOS Catalina (10.15), Apple requires downloaded binaries to be notarized, or the Gatekeeper service does not allow to run them.

If you plan on making prebuilt Go binaries available to macOS users, this guide can save you some time.

This workflow is tested on macOS Catalina (10.15.3), Xcode 11.3.1, Go 1.14rc1 and is based on the Customizing the Notarization Workflow developer documentation article.

Prerequisites:

  1. Apple Developer account. You can enroll with your Apple ID on https://developer.apple.com for $99/year.
  2. The developer account must be enrolled in the App Store Connect. Go to your account at https://developer.apple.com, pick "Overview" on the left, then "App Store Connect" on the main screen, proceed with terms of service.
  3. Xcode 11 installed (available from the App Store, setup can take a while).

Creating a developer certificate for app signing

Run Xcode 11. You don't need to create any new project; going up to its welcome screen is enough. Go to Xcode → Preferences (⌘, shortcut), select the "Accounts" tab. There add a new account with the plus sign button on the left bottom corner, chose "Apple ID," and enter your Apple ID credentials.

After you add Apple ID and see its details on the right side of the preferences window, pick the only record under the Team/Role table, then press the "Manage Certificates" button. There add a new certificate with the plus sign button on the left bottom corner, pick the Developer ID Application type.

Your new certificate should appear on this list. Switch to your terminal, and run the following command:

security find-identity -v

It shows you a list of installed certificates. Look for the "Developer ID Application" line, followed by your name. Note the 40-character hexadecimal identifier on this line — record it somewhere for later use, it is your certificate ID.

You can close Xcode now; you won't need its main window in this workflow anymore.

Sign your Go binary

Build your Go binary for distribution. Sign it with your certificate:

codesign -s <YOUR-CERTIFICATE-ID> -o runtime -v <YOUR-GO-BINARY>

The -o runtime flag preserves the hardened runtime version, which is a requirement for the Apple Notary service. Your binary is signed in place, keep it for later steps, it's the version you'll be distributing once it's successfully notarized.

Create separate credentials for your Apple ID

App Store Connect requires two-factor authentication on all accounts, so you'll need a separate set of credentials for your Apple ID to use with the tool on the next step.

Follow steps from the support article at https://support.apple.com/en-us/HT204397. To identify your new credentials, you can use the "altool" name. Copy generated password.

Set up altool to use your new credentials

Run the following command once to save your newly created password in a specific Keychain entry:

xcrun altool --store-password-in-keychain-item altool \
    -u <APPLE-ID-EMAIL> \
    -p <YOUR-NEW-PASSWORD>

This command saves credentials under "altool" Keychain entry for later use. See man altool for more details.

Submit your binary for notarization

Now everything's ready to submit your binary for notarization. Run the following command:

xcrun altool --notarize-app \
    --primary-bundle-id <BUNDLE-ID> \
    --username <APPLE-ID-EMAIL> \
    --password "@keychain:altool" \
    --file <YOUR-SIGNED-GO-BINARY>

Here <BUNDLE-ID> is an arbitrary string that helps you identify specific submission. You can use something like "com.github.username.project" here. Note the --password "@keychain:altool" flag — it tells the program to fetch credentials from the Keychain "altool" entry created on the previous step.

This call may take a minute or a few to complete. When it succeeds, it shows the No errors uploading ... message and a unique identifier of your upload (RequestUUID). Keep that ID — you should use it to check notarization status.

Check notarization status

Notarization may take from a few minutes to a few hours. You can periodically poll the status of your submission using its ID:

xcrun altool --notarization-info <REQUEST-UUID> \
    -u <APPLE-ID-EMAIL> \
    -p "@keychain:altool"

Upon completion, the message displays notarization status. You're interested in Status Message: Package Approved. If there were any issues, see more details on the link under the LogFileURL output attribute.

Once you get Status Message: Package Approved, this means that Apple has successfully approved your binary, and you can distribute it.

Signing and notarizing more binaries

Having all setup in place, you only need to follow these steps to sign and notarize other binaries:

  1. Sign your Go binary;
  2. Submit your binary for notarization;
  3. Check notarization status.