LiveCode LessonsLiveCode LessonsHow To - Step-By-Step Guides To Tasks In LiveCodeSigning ApplicationsCode signing and notarizing your LC standalone for distribution outside the Mac Appstore with Xcode 13 and up

Code signing and notarizing your LC standalone for distribution outside the Mac Appstore with Xcode 13 and up

As of November 1, 2023 Apple notary service will not accept uploads from altool. Therefore this lesson covers the new Notarytool for uploading to the Apple notary service.

This tutorial describes the necessary tasks to get your app code signed and notarized for distribution outside the Mac Appstore.

- Code signing your app (including some necessary preparations)

- creating and code signing package installer (.pkg)

- creating and code signing a DMG using DropDMG or hdiutil  (optional)

- Notarizing and stapling your app, pkg or dmg

Most is done with shell commands.

 

Files

An overview how to notarize an app:

 

This lesson as PDF:

 

A Livecode stack  which should do all needed steps for you. See chapter 9.

Note: Please read at least chapter 9 before using the stack.

 

1. Prerequisites

Please make sure that you fullfil the following requirements before you continue

1.1. Apple ID

If you do not already own an Apple ID, you can create one here:  https://appleid.apple.com

 

1.2. Enable two factor authentication for your Apple ID

You need to have 2 factor authentication (2FA) enabled for your Apple ID. You can do this in your Apple ID Account  at https://appleid.apple.com

 

1.3. App-specific password

 

You´ll need an app-specific password. You can create one at https://appleid.apple.com

There is a blue link Generate Password...

 

In my given examples below I will use tic-tac-toe in places of app-specific password.

 

1.4. Developer ID

You´ll need a Developer  ID. Therefore you´ll need to be a member in the Apple Developer Programm. Join here https://developer.apple.com

In my examples i use [email protected] as Developer ID.

 

1.5. Creating Developer ID Application and Installer certificates

1.5.1. Create Developer ID Application certificate using Developer account

The certificate types for distribution outside the Apple "App Store” for Mac OS are:

- Developer ID Application   <- this is needed for signing .app and .dmg

This certificate is used to code sign your app for distribution outside of the Mac App Store.

- Developer ID Installer   <- this is needed for signing package installers (.pkg)

This certificate is used to sign your app’s "Installer Package" for distribution outside of the Mac App Store.

 

Note: If you are not distributing “Installer Packages”, the only certificate you need is “Developer ID Application”

 

You can create the certificates either in your Apple Developer account, see screenshot.

After you´ve created the certificate you can download the certificate. You can now add it to your Keychain by double clicking on the downloaded file.

1.5.2. CreateDeveloper ID Application certificate using Xcode

or directly in Xcode -> Preferences -> Accounts

1. press Manage Certificates -> a window pops up

2. press + sign

3. select the certificate you want to create

The certificate will automatically added to the Keychain.

1.5.3. Create a Developer ID Installer certificate

You'll need a Developer ID Installer certificate, if you plan to distribute your app as a package installer.

To create that certificate, follow steps 1.5.1 and 1.5.2, but select Developer ID Installer instead of Developer ID Application

1.6. Xcode 13 and up

For this tutorial Xcode 13 or 14  command line tools are used for code signing, notarizing and stapling.

1.7. Standalone with correct bundle identifier

The bundle identifier is set in the standalone settings -> Mac tab

You should use the following form for the bundle identifier com.<YourCompany>.YourAppname

or if you own a domain use <YourDomain>.YourAppname e.g. tk.rebbe.dropuploadx

 

Note: In my given examples below I will use tk.rebbe.dropuploadx in places of bundle identifier.

 

1.8. Some notes about how to add additional files or folders

It is important or better said mandatory that additional  files and folders are copied to the standalone using the Copy Files tab in the standalone settings. Please do not add those files or folders to the app bundle manually after standalone creation.

You have to use the Copy Files tab in the standalone settings!

2. Preparations for code signing

Before code signing an LC app, some changes must be done to the standalone (bundle)

2.1. Removing the extended attributes

Run the following command in terminal

sudo xattr -cr "<path_to_app_bundle>"

Replace <path_to_app_bundle> with the path to your standalone.

Put the path in quotes, this would avoid problems when the path contains spaces.

Or just drag and drop the standalone on terminal window. This will take care of spaces etc. as well

 

Example

sudo xattr -cr "/Users/matthias/Downloads/DropUpload/DropUpload.app"

To make sure all attributes are removed, run the following command in terminal

sudo xattr -lr "<path_to_app_bundle>"

Replace <path_to_app_bundle> with the path to your standalone.

Put the path in quotes, this would avoid problems when the path contains spaces.

Or just drag and drop the standalone on terminal window. This will take care of spaces etc. as well

 

Example

sudo xattr -lr "/Users/matthias/Downloads/DropUpload/DropUpload.app"

If you see your prompt and no other output, then all is fine and you can continue

 On macOS Ventura the xattr  -lr command still might list  the extended attribute  com.apple.provenance:

 You can ignore this and continue...

 

2.2. Renaming the localization folders

Right click on your app bundle and select "show package content".

open the folder Contens/Resources

you'll see .lproj folders. The names of all .lproj folders have to be Iso language codes. So

rename those folders that do not have the Iso language code in their names.

For example rename German.lproj to de.lproj, Dutch.lproj to nl.lproj and so on.

2.3. changing permissions

To make sure that you are the owner of all externals and other stuff you´ve included in your app bundle we need to change the permissions.

Run the following command in terminal

sudo chmod -R u+rw "<path_to_standalone_app_bundle>"

Example

sudo chmod -R u+rw "/Users/matthias/Downloads/DropUpload/DropUpload.app"

 

Put the path in quotes, this would avoid problems when the path contains spaces.

Or just drag and drop standalone on terminal window. This will take care of spaces etc. as well

 

3. Codesigning

To codesign .app, a .pkg or a .dmg you need your Developer ID certificates (see steep 1.4)

Signing .app and .dmg is done with the tool sign and the Developer ID Application certificate.

.pkg installers are signed using the tool productsign and the Developer ID Installer certificate

More detailed information comes here...

3.1. Codesigning standalone - get the exact name of your Developer ID for signing

To codesign your app and later the dmg  you´ll need the exact name of your Developer ID application.

Open Keychain Access

The name of the Developer ID begins with Developer ID Application: followed by your name and you your ID. See the yellow highlighted entry.

Remember: the Developer ID Installer is needed for signing a package installer .pkg. See the green highlighted entry

3.1.1. Code signing standalone - now codesign

Run the following command in Terminal

codesign --deep --force --verify --verbose --timestamp --sign "<your_developer_ID>" --options runtime "<path_to_app_bundle>"

Replace <your_developer_id_application> with the name  you investigated in the previous step. Keep the quotes.

Replace <path_to_app_bundle> with the path to your standalone. Put the path in quotes, this would avoid problems when the path contains spaces. Or just drag and drop the standalone on terminal window. This will take care of spaces etc. as well

Example

codesign --deep --force --verify --verbose --timestamp --sign "Developer ID Application: Matthias Rebbe (386687PEUL)" --options runtime "/Users/matthias/Downloads/DropUpload/DropUpload.app"

 

If code signing was successfull then you should see something like this

A special note about entitlements

If you want to include an entitlements file,  then please use this syntax

codesign --deep --force --verify --verbose --timestamp --sign "<your_developer_ID>" --options runtime  --entitlements "<path/to/entitlements.plist>" "<path_to_app_bundle>"

 Please see also lesson Entitlements for signed and notarized apps for more information

 

Important Note:
If you are using LC 9.6.1 or higher and make use of the revZip external in your standalone then it is currently mandatory to include an entitlements file with at least the com.apple.security.cs.disable-library-validation entitlement  set to true.

<key>com.apple.security.cs.disable-library-validation</key>

<true/>

 

 

4. Verifying the signed app (optional)

As the  command in the previous step returned  signed app bundle with Mach-0 universal (x86_64) [tk.rebbe.dropuploadx] there is no need to run this step. But you can, if you want. ;)

 

To verify we could enter the following command in Terminal

codesign --verify --verbose "<path_to_app_bundle>"

Replace <path_to_app_bundle> with the path to your standalone.

Put the path in quotes, this would avoid problems when the path contains spaces. Or just drag and drop the standalone on terminal window. This will take care of spaces etc. as well

 

Example

codesign --verify --verbose "/Users/matthias/Downloads/DropUpload/DropUpload.app"

 

This command is also usefull to find out if any app or DMG, not only yours, is code signed or not.

It the app is code signed, then you should see something like this

5. Create and code sign a package installer .pkg (optional)

Create a signed package installer in one step:

To create and sign a package installer from the standalone in just one step please run the following command in Terminal

productbuild --timestamp --sign "your_Developer_ID_installer" --component "<path_to_app>" /applications "<path_to_signed_pkg>" 

The above command creates a package installer from your app and signs it automatically after creation.  

Replace <path_to_app> with the path of the signed app

Replace <path_to_signed_pkg> with the path where the signed .pkg shall be written

Put the path in quotes, this would avoid problems when the path contains spaces. Or just drag and drop the PKG on terminal window. This will take care of spaces etc. as well

When running the above command macOS will show 2 dialogs asking for the password to get access the keychain.

If the creation/signing was  successful, you should see similar messages like the following ones:

productbuild: Adding component at /users/matthias/test.app
productbuild: Using timestamp authority for signature
productbuild: Signing product with identity "Developer ID Installer: Matthias Rebbe (xxxxxx)" from keychain /Users/matthias/Library/Keychains/login.keychain-db
productbuild: Adding certificate "Developer ID Certification Authority"
productbuild: Adding certificate "Apple Root CA"
productbuild: Wrote product to /Users/matthias/test.pkg
productbuild: Supported OS versions: [10.9, )

 

Create an unsigned package installer:

If you just want to create an unsigned package installer then run the following command in Terminal

productbuild --component "<path_to_app>" /applications "<path_to_signed_pkg>" 

 The above command creates just the package installer without signing it. Please follow step 5.1 to manually sign it.

5.1. Code signing the package installer

This step is only needed, if you 've created an unsigned package installer

Please note: To sign a package installer the tool productsign is needed, not codesign.

Run the following command in Terminal

productsign --timestamp --sign "<your_developer_id_installer>" "<path_to_pgk>" "<path_to_signed_pkg>"

Replace <path_to_pkg> with the path of the newly created .pkg.

Replace <path_to_signed_pkg> with the path where the signed .pkg shall be written

Put the path in quotes, this would avoid problems when the path contains spaces. Or just drag and drop the PKG on terminal window. This will take care of spaces etc. as well

 Example

productsign --timestamp --sign "Developer ID Installer: Matthias Rebbe (386687PEUL)"  "/users/matthias/name.pkg""/users/matthias/name_signed.pkg"

 If code signing was successful, then you should see something like this:

 productsign: using timestamp authority for signature
productsign: signing product with identity "Developer ID Installer: Matthias Rebbe (386687PEUL)" from keychain /Users/matthias/Library/Keychains/login.keychain-db
productsign: adding certificate "Developer ID Certification Authority"
productsign: adding certificate "Apple Root CA"
productsign: Wrote signed product archive to /users/matthias/name_signed.pkg

If you want to distribute the package installer directly, then go to step 7.2 Notarizing app (DMG/PKG method)

6. Creating DMG (optional)

If you want to distribute your app or package installer on DMG then follow the next steps.

 

Run the following command in Terminal to create the DMG

hdiutil create -volname "<Name_of_Volume>" -srcfolder "<path_to_your_app_or_pkg>" -ov -format UDZO "<Name_of_the_DMG>"

Replace <Name_of_Volumes> with the name the DMG volume shall show up with, when mounted. Keep the quotes.

Replace <path_to_your_app_or_pkg> with the path to your standalone or .pkg

Put the path in quotes, this would avoid problems when the path contains spaces. Or just drag and drop the standalone on terminal window. This will take care of spaces etc. as well

Replace <Name_of_the_DMG> with the filename the DMG file shall have, for example DropUpload.dmg.  Keep the quotes

 

Example for creating a .dmg  from an .app

hdiutil create -volname "DropUpload" -srcfolder "/Users/matthias/Downloads/DropUpload/DropUpload.app" -ov -format UDZO "DropUpload.dmg"

 

 Example for creating a .dmg  from an .pkg

hdiutil create -volname "DropUpload" -srcfolder "/Users/matthias/Downloads/DropUpload/DropUpload.pkg" -ov -format UDZO "DropUpload.dmg"

 

The above commands would create a DMG  with the name DropUpload.dmg and the volumename DropUpload, so when the DMG is mounted the volume name would be DropUpload.

 

6.1. Code signing the DMG

Run the following command in Terminal

codesign --deep --force --verify --verbose --sign "<your_developer_id_application>" --options runtime "<path_to_dmg>"

Replace <path_to_DMG> with the path of the newly created DMG.

Put the path in quotes, this would avoid problems when the path contains spaces. Or just drag and drop the DMG on terminal window. This will take care of spaces etc. as well

 

Example

codesign --deep --force --verify --verbose --sign "Developer ID Application: Matthias Rebbe (386687PEUL)" --options runtime "/users/matthias/name.dmg"

 

If code signing was successful, then you should see something like this

 

6.2. Verifying the code signing (optional)

As the  command in the previous step returned "signed" there is no need to run this step.

 

However,if you want to check, if a DMG is code signed, run the following command in Terminal

codesign --verify --verbose "<path_to_dmg>"

Replace <path_to_DMG> with the path of the newly created DMG.

Put the path in quotes, this would avoid problems when the path contains spaces. Or just drag and drop the DMG on terminal window. This will take care of spaces etc. as well

 

Example

codesign --verify --verbose "/users/matthias/name.dmg"

 

 

7. Notarizing your App, Package Installer (.pkg) or DMG

To get our app notarized by Apple we need to upload it to Apple. Apple does not allow an app to be uploaded directly. Only zip files, Installer packages or DMGs can be uploaded.

Please go to step 7.2, if you want to notarize a PKG or DMG, otherwise continue with the following step to notarize the app using the zip method.

 To submit the file to Apple's Notarization services you'll need the command line tool notarytool. It is part of Xcode's command line tools. Notarytool was introduced with Xcode 13.  Please make sure that you've selected the correct Xcode version whose command line tools you want to use.

This can be either done in Xcode ->Preferences ->Locations or in Terminal.app using the xcode-select command.

To submit to Apple you either need to specify your Apple-ID, AppSpecificPassaword and your DeveloperTeamID every time using this syntax:

xcrun notarytool submit --apple-id "<your_AppleID>" --password "<yourAppSpecificPassword>" --team-id <yourTeamID> --wait "<path_to_file>"

or with specifying just the name of a Keychain profile that contains the needed information (Apple-ID, AppSpecificPassword and DeveloperTeamID)

xcrun notarytool submit --keychain-profile "<NameOfTheProfileThatContainsTheNeededData>" --wait "<path_to_file>"

In this lesson we use the first syntax which contains the Apple-ID,Password and DeveloperTeamID.

Please see chapter 8 to find out how to setup a keychain-profile to use with notarytool.

7.1. Notarizing an app (zip method)

7.1.1. creating a zip file from app

Therefore we need to create a zip file from our app first.

The easiest way  to do this is to right click on our app and select compress. After the zip file was created we can upload it to Apple.

7.1.2. Uploading the zip file to Apple for Notarization / Analysis

Run the following command in Terminal

xcrun notarytool submit --apple-id "<your_AppleID>" --password "<yourAppSpecificPassword>" --team-id <yourTeamID> --wait "<path_to_zip>"

 <your_AppleID> = Your AppleID  you´ve used for registering your Apple deverloper account. Put the AppleID in quotes

 <yourAppSpecificPassword> = The password you´ve created at https://appleid.apple.com   For details see  chapter 1.3.  Put the password in quotes.

<yourTeamID> = You'll find your Team ID in your Apple Developer Account under Membership details
https://developer.apple.com/account

 <path_to_zip> = the path to the  zip. Put the path in quotes. This will avoid problems when the path contains spaces or any of the following characters \`!$

Or just drag and drop the zip file on terminal window. This will take care of spaces etc. as well

 The parameter --wait tells notarytool to wait until the submission was processed by Apple's Notarization services.

Example

xcrun notarytool submit --apple-id "[email protected]" --password "tic-tac-toe" --team-id "829898982GEUL" --wait "/users/matthias/name.zip" 

After uploading Notarytool is waiting until the submission was processed by Apple's Notarization services. According to Apple the process takes less than an hour.

You should then see something like this

Conducting pre-submission checks for name.zip and initiating connection to the Apple notary service...
Submission ID received
  id: df02b221-e999-4222-9c7e-8436c4a3e93a0
Successfully uploaded file(12,0 MB of 12,0 MB)
  id: df02b221-e999-4222-9c7e-846c4a3e93a0
  path: /Users/matthias/lc/name.zip
Waiting for processing to complete.
Current status: Accepted........
Processing completd
  id: df02b221-e999-4222-9c7e-846c4a3e93a0
  status: Accepted

 When you do not use the --wait option then Notarytool just returns the result of the upload process.

Conducting pre-submission checks for name.zip and initiating connection to the Apple notary service...
Submission ID received
  id: df02b221-e999-4222-9c7e-8436c4a3e93a0
Successfully uploaded file(12,0 MB of 12,0 MB)
  id: df02b221-e999-4222-9c7e-846c4a3e93a0
  path: /Users/matthias/lc/name.zip

  In this case you have to manually check the status manually. See Chapter 7.3 for this.

7.1.3. Delete the zip file again

As the zip file was only needed to  upload the app for notarization we can now delete the zip file again. We do not need it anymore.

 

7.2. Notarizing app (DMG/PKG method)

To get our DMG and  the containing pkg or app  notarized by Apple we need to upload it to Apple.

7.2.1. Uploading the PKG or DMG to Apple for Notarization / Analysis

 

Run the following command in Terminal

xcrun notarytool submit --wait --appleid "<your_AppleID>" --password "<yourAppSpecificPassword>" --team-id "<yourTeamID> "<path_to_dmg_or_pkg>"

<your_AppleID> = Your AppleID  you´ve used for registering your Apple deverloper account. Put the AppleID in quotes

 <yourAppSpecificPassword> = The password you´ve created at https://appleid.apple.com   For details see  chapter 1.3.  Put the password in quotes.

<yourTeamID> = You'll find your Team ID in your Apple Developer Account under Membership details
https://developer.apple.com/account

<path_to_dmg_or_pkg> = the path to the  DMG or PKG.

Put the path in quotes. This will avoid problems when the path contains spaces or any of the following characters \`!$

Or just drag and drop the DMG/PKG on terminal window. This will take care of spaces etc. as well

 The parameter --wait tells notarytool to wait until the submission was processed by Apple's Notarization services.

 

Note: See chapter 8  on how to reference to a password stored in Keychain Access instead of using your app specific password directly.

 

Example - uploading a dmg

xcrun notarytool submit --wait --apple-id "[email protected]" --password "tic-tac-toe" --team-id "829898982GEUL" "/users/matthias/name.dmg" 

 Example - uploading a pkg

xcrun notarytool submit --wait --apple-id "[email protected]" --password "tic-tac-toe" --team-id "829898982GEUL" "/users/matthias/name.pkg" 

After uploading Notarytool is waiting until the submission was processed by Apple's Notarization services. According to Apple the process takes less than an hour.

You should then see something like this

Conducting pre-submission checks for name.zip and initiating connection to the Apple notary service...
Submission ID received
  id: df02b221-e999-4222-9c7e-8436c4a3e93a0
Successfully uploaded file(12,0 MB of 12,0 MB)
  id: df02b221-e999-4222-9c7e-846c4a3e93a0
  path: /Users/matthias/lc/name.zip
Waiting for processing to complete.
Current status: Accepted........
Processing completd
  id: df02b221-e999-4222-9c7e-846c4a3e93a0
  status: Accepted

 

When you do not use the --wait option then Notarytool just returns the result of the upload process.

Conducting pre-submission checks for name.zip and initiating connection to the Apple notary service...
Submission ID received
  id: df02b221-e999-4222-9c7e-8436c4a3e93a0
Successfully uploaded file(12,0 MB of 12,0 MB)
  id: df02b221-e999-4222-9c7e-846c4a3e93a0
  path: /Users/matthias/lc/name.zip

  In this case you have to manually check the status manually. See Chapter 7.3 for this.

7.3. Check the status of Notarization process when not used the --wait option

Run the following command in Terminal

xcrun notarytool info <requestUUID> --apple-id "<your_AppleID>" --password "<yourAppSpecificPassword>" --team-id  "<YourTeamID>" 

<requestUUID> = the ID which was returned after successful upload (see 7.2.1)

<your_AppleID> = Your AppleID  you´ve used to join Apple´s deverloper program. Put your AppleID in quotes.

<yourAppSpecificPassword> = The password you´ve created at https://appleid.apple.com.  Put the password in quotes.

<yourTeamID> = You'll find your Team ID in your Apple Developer Account under Membership details
https://developer.apple.com/account

 

Example

xcrun notarytool info "df02b221-e999-4222-9c7e-8436c4a3e93a0" --apple-id "[email protected]" --password "tic-tac-toe" --team-id "829898982GEUL"

 

7.3.1. Check the status of analysis - ...in progress

If the Notarization process is not completed, you'll see something like this

 matthias@Mac ~ % xcrun notarytool info "df02b221-e999-4222-9c7e-8436c4a3e93a0" --apple-id "[email protected]" --password "tic-tac-toe" --team-id  "829898982GEUL"
Developer ID Application: Matthias Rebbe (829898982GEUL)
Successfully received submission info
  createdDate: 2023-02-22T23:30:30.108Z
  id: df02b221-e999-4222-9c7e-8436c4a3e93a0
  name: name.zip
  status: In Progress
matthias@Mac ~ % 

7.3.2. Check the status of analysis - ...Success

If the Notarization process was successful you should see something like this

with Status: Accepted

matthias@Mac ~ % xcrun notarytool info "df02b221-e999-4222-9c7e-8436c4a3e93a0" --keychain-profile "Notarytool"
Successfully received submission info
  createdDate: 2023-02-14T21:42:53.737Z
  id: df02b221-e999-4222-9c7e-8436c4a3e93a0
  name: name.dmg
  status: Accepted
matthias@Mac ~ % 

 

Stapling means the notarization ticket is added to the app/DMG.

This step is  not mandatory, but recommended.  It ensures that Gatekeekper can find the notarization ticket even when a network connection (internet connection) isn't available.

Without this step every time an app, dmg  or pkg is launched Gatekeeper has to check online if the PKG/DMG/App was notarized or not.

Stapling ensures that Gatekeeper can approve the notarization even when an internet connection isn't available.

To staple it run the following from Terminal

xcrun stapler staple -v "<path_to_app>"

Replace <path_to_app> with the path of the  standalone.

Put the path in quotes. This will avoid problems when the path contains spaces or any of the following characters \`!$

Or just drag and drop the app on terminal window. This will take care of spaces etc. as well

 

Examples  

xcrun stapler staple -v "/Users/matthias/Downloads/DropUpload/DropUpload.app"

If the staple was successfull then you should see The staple and validate action worked!

 

Instead of stapling the original standalone on the harddisk for distribution, you could just copy the app from the mounted DMG and use that for distribution as zip.

But at least i wanted to show that you also can staple the  app. ;)

 

 

 

To staple the DMG run the following from Terminal

xcrun stapler staple -v "<path_to_dmg_or_pkg>"

Replace <path_to_DMG> with the path of the  DMG or PKG.

Put the path in quotes. This will avoid problems when the path contains spaces or any of the following characters \`!$

Or just drag and drop the DMG/PKG on terminal window. This will take care of spaces etc. as well

 

Example stapling a dmg

xcrun stapler staple -v "/users/matthias/name.dmg"

 Example stapling a pkg

xcrun stapler staple -v "/users/matthias/name.pkg"

If you see The staple and validate action worked!, then your DMG/PKG was successfully stapled and is ready for distribution.

 

8. Addendum 1 - create a keychain-profile to use with notarytool

Instead of using your  password, Apple-ID and DeveloperTeam ID directly when running notarytool in Terminal, you can use a Keychain profile

To create such a profile enter the following command in Terminal

xcrun notarytool store-credentials "<profile-name>" --apple-id "<YourAppleID" --password "<AppSpecificPassword>" --team-id <YourTeamDeveloperID>

Replace <YourAppleID> with the your Apple ID you´ve used to join the Apple Developer Program. Wrap it in quotes.

Replace <AppSpecificPassword> with the the app-specific password you´ve created at https://appleid.apple.com. (See chapter 1.3). Wrap it in quotes.

Replace <profile-name> with the name under which you want to save the profile in your Keychain. Wrap it in quotes.
This will then be used with the --Keychain-Profile  parameter in Notarytool

Example

xcrun notarytool store-credentials "Notary" --apple-id "[email protected]" --password "tic-tac-toe"  --team-id = "829898982GEUL"

This command would create a keychain profile with the name Notary and would store the AppleID, password and Team ID to it.

8.1. How to reference to a Keychain profile?

 

The first paragraph of chapter 7 showed 2 ways how you let notarytool authenticate with the Apple Notarization services.

With a Keychain profile that holds all information about Apple ID, App Password and Developer TEAM ID we could  use the second example. So instead of using the parameter --apple-id, --password and --team-id, we just would use

--keychain-profile "<profile-name>"

xcrun notarytool submit --wait --keychain-profile "<NameOfTheProfileThatContainsTheNeededData>"  "<path_to_file>"

Example

xcrun notarytool submit --wait --keychain-profile "Notary" "/users/matthias/name.dmg"

 

Note: The value for Keychain profile is case sensitive. So in case the name of the profile has lowercase and uppercase characters in it, then use the exact same writing of the name when running notarytool.

 

 

9. Addendum 2 - Livecode stack

Using the attached Livecode stack to automate the above steps .

 

9.1. The Livecode Stack

There´s  a Livecode stack available which does all the steps required for Notarization and Stapling.

For creating DMGs the stack uses hdiutil or DropDMG's command line tool.

DropDMG is more powerful and allows to add layouts, licenses and much more to the DMG.

9.2. Quick Overview

This chapter is just a quick overview. More detailed information about settings can be found in chapters 9.3 to 9.6

If you want, you can test right away following steps

1 - go to stack preferences

2 - reset/empty all fields

3 - drag your app bundle you want to code sign & notarize to this field

Note: If your standalone is currently stored in a  folder which is synchronized with Dropbox, iCloud Drive or any other Cloud Drive, then please move the standalone to a folder that is not synchronized. There was feedback from users who encountered problems when trying to notarize a standalone which was stored on a  folder which was synchronised.

4 - Select the desired action

5 - Press START

6 - Debug mode - This will create a list of all shell commands to the clipboard as far as this is possible

7 - this field will contain the returned request UUID from Apple's Notarization services

8 - The status field shows  information including encountered errors during the code signing and notarization process. If an error is detected then an answer dialog will popup and the process is aborted.

The image below shows a successful notarization.

9.3. More Detailed...

9.3.1. The Main Window

1 - empty all fields

2 - go to stack references

 

9.3.2. The Settings

9.3.2.1. General Settings

1 - Close settings stack

2 - empty all fields

3 - enter your sudo password. This is needed for some tasks. See  https://support.apple.com/en-us/HT202035 for additional information about the sudo password.

4. enter a URL to which the Apple Notarization services should post the result of the submission.

5 - Keychain profile. Please see chapter Addendum 1

6 - Your Apple Developer ID Application.  This contains your name and a number. e.g Developer ID Application: Matthias Rebbe (123456GEUL)

7 - Your Apple Developer ID Installer.  This contains your name and a number. e.g Developer ID Installer: Matthias Rebbe (123456GEUL)

8 - Select if you want to overwrite existing Package Installers (.pgk)

9 - select if you have installed DropDMG and want use that tool for creating DMG

10 - click to open settings for  DropDMG

11 - select if you want to overwrite existing DMG (this setting will be ignored if DropDMG is used)

12 - select if you want to include an entitlements file for code signing an app

13 - click to open entitlements settings

14 - save settings

9.3.2.1.1. DropDMG settings

1 - Close settings

2 - empty all fields

3 - save settings

4 - default path to DropDMG´s command line tool

5 - press to select an other path

6 - Configuration to be used for DMG creation.

7 - press to select DropDMG configurations.

8 - Layout to be used for DMG creation

9 - press to select a DropDMG Layout

10 - License to be add to the DMG

11 - press to select a DropDMG License

12 - check to overwrite existing DMG. Otherwise DropDMG adds a counter to the name e.g. MyDMG-1.dmg
this is automatically handled by DropDMG´s command line tool

13 - go back to general settings

9.3.2.1.2. Entitlements settings

1 - Close settings

2 - empty all fields

3 - save settings

4  - the available entitlements - press the ones you want to be included in the entitlements plist file

5 - press to select all entitlements

6 - press to unselect all entitlements

7 - go back to general settings

This dialog contains all the entitlements that Livecode uses. To allow some features of LiveCode to work correctly in signed and notarized apps you need to include the relevant entitlements in an entitlements file. The permissions are then incorporated into the code signature when you build the app.

Or according to lesson Entitlements for signed and notarized apps  an option is to sign your app using all the entitlements that LiveCode uses. This will ensure that no features will break because the proper entitlement was not used.

9.3.3.

9.3.3.1. Show all recent successful submission

1 - close stack

2- Refresh the list

3 - empty the table

4 - Retrieves  information for the selected request from Apple´s Notarization service.

Note: Fetching the list of all recent notarization requests from Apple´s servers may take some time, so please be patient.

9.3.3.2. Show detailed information for selected request

1 - close field

2 - information for a request looks like this

3 - The status of the submission

 

10. Troubleshooting

It can happen that your app will not be  approved and the notarization fails. This can have several reasons. But how do you get to know what the reason was?

You can either use the stack mentioned in chapter 9 to find out or you use Terminal.app and run several commands to find out.

 

 This chapter explains how to find out using shell commands.

10.1. How to get detailed information about a notarization request

10.1.1. Get a list of all recent submissions

To list all recent notarization request run the following command in Terminal

xcrun notarytool history --apple-id "<YourAppleID>" --password "<AppSpecificPassword>" --team-id  "<DeveloperTeamID>"

<YourAppleID> = Your Apple ID  you´ve used for registering your Apple deverloper account. Wrap the Apple ID with quotes.

 <AppSpecificPassword> = The password you´ve created at https://appleid.apple.com   For details see  chapter 1.3.  Wrap  the password with quotes.

<DeveloperTeamID> = You'll find your Team ID in your Apple Developer Account under Membership details
https://developer.apple.com/account

Note:
Instead of --apple-id, --team-id and --password you can just use the parameter --keychain-profile "<profile-name">
Replace <profile-name> with the Keychain profile name under which your credentials were saved to the Keychain.

Chapter 8 Addendum 1  shows how to create such a keychain profile. 

 

After running the command you should see a list of all recent successful submissions.

Successfully received submission history.
  history
    --------------------------------------------------
    createdDate: 2023-02-22T10:47:22.901Z
    id: df2ab221-e961-4233-9c7e-936c4a3e93a0
    name: name.zip
    status: Accepted
    --------------------------------------------------
    createdDate: 2023-02-21T17:06:45.458Z
    id: 38d6f508-a140-49d8-b4f4-13e0767c47b0
    name: name.dmg
    status: Accepted
    --------------------------------------------------
    createdDate: 2023-02-21T17:04:14.568Z
    id: 018fa415-8ea8-5dae-bd48-05e18316a48f
    name: name.dmg
    status: Accepted

 

 

10.1.2. Get detailed information for a single completed submission

In the previous step we´ve copied the requestUUID of the failed notarization to the clipboard.

Now run the following shell command in Terminal:

xcrun notarytool log "<requestUUID>" --apple-id "YourAppleID" --password "<AppSpecificPassword>"

<requestUUID> = the requestUUID for which we want more information. In our case this is the id we´ve copied to the clipboard

<your_AppleID> = Your AppleID  you´ve used for registering your Apple deverloper account. Put the AppleID in quotes

 <yourAppSpecificPassword> = The password you´ve created at https://appleid.apple.com   For details see  chapter 1.3.  Put the password in quotes.

<yourTeamID> = You'll find your Team ID in your Apple Developer Account under Membership details
https://developer.apple.com/account

 

Note:

Instead of --apple-id, --team-id and --password you can just use the parameter --keychain-profile "<profile-name">

Replace <profile-name> with the Keychain profile name under which your credentials were saved to the Keychain.

Chapter 8 Addendum 1  shows how to create such a keychain profile. 

 

Running the command something similar to the following should be returned

{
 "logFormatVersion": 1,
  "jobId": "df02b221-e871-4333-9c7e-936c4a3e93a0",
  "status": "Accepted",
  "statusSummary": "Ready for distribution",
  "statusCode": 0,
  "archiveFilename": "name.dmg",
  "uploadDate": "2023-02-22T10:47:26.357Z",
  "sha256": "54f3f204cb556591fd814c2070428501b3a484d5eac61fc67dc80169565892b1",
  "ticketContents": [
    {
      "path": "name.dmg",
      "digestAlgorithm": "SHA-256",
      "cdhash": "7b4976ecdd3f9f87391258b70ee3e950f61a7bba"
    },
    {
      "path": "name.dmg/name.app",
      "digestAlgorithm": "SHA-256",
      "cdhash": "49f93d3c0ac0dd8eafd4c93e589d1af9c388f552",
      "arch": "x86_64"
    },
    {
      "path": "name.dmg/name.app/Contents/MacOS/revsecurity.dylib",
      "digestAlgorithm": "SHA-256",
      "cdhash": "59c60dff190d7faabc78de649b31143c438e5e19",
      "arch": "x86_64"
    },
    {
      "path": "name.dmg/name.app/Contents/MacOS/Externals/tsNet.bundle",
      "digestAlgorithm": "SHA-256",
      "cdhash": "63b5d72c7ec1e0d64cd57aa53c124fa0f270041f",
      "arch": "x86_64"
    },
    {
      "path": "name.dmg/name.app/Contents/MacOS/revsecurity.dylib",
      "digestAlgorithm": "SHA-256",
      "cdhash": "59c60dff190d7faabc78de649b31143c438e5e19",
      "arch": "x86_64"
    },
    {
      "path": "name.dmg/name.app/Contents/MacOS/BRx_Konverter_V2",
      "digestAlgorithm": "SHA-256",
      "cdhash": "49f93d3c0ac0dd8eafd4c93e589d1af9c388f552",
      "arch": "x86_64"
    },
    {
      "path": "name.dmg/name.app/Contents/MacOS/Externals/tsNet.bundle",
      "digestAlgorithm": "SHA-256",
      "cdhash": "63b5d72c7ec1e0d64cd57aa53c124fa0f270041f",
      "arch": "x86_64"
    },
    {
      "path": "name.dmg/name.app/Contents/MacOS/Externals/tsNet.bundle/Contents/MacOS/tsNet",
      "digestAlgorithm": "SHA-256",
      "cdhash": "63b5d72c7ec1e0d64cd57aa53c124fa0f270041f",
      "arch": "x86_64"
    }
  ],
  "issues": null
 }

 

 

 

 

 

12 Comments

Alice

I have followed these instructions and have successfully signed my app. Unfortunately have been unsuccessful with getting it notarized.

After several attempts using the Terminal and mrSignNotarizeHelperV4.livcode (Which is brillant!) I submitted the last UUID to the Apple log for answers and received this ...

"Must provide all app-specific password authentication arguments (--apple-id, --password, --team-id). You may leave '--password' unspecified on initial invocation to receive a secure prompt."

Any help would be truly appreciated.

Matthias Rebbe

It seems there is a problem with the parameters for Apple-ID, Password and TeamID

Did you create an App Specific Password in your Apple Account (https://appleid.apple.com/)

(see also chapter 1.3 in the lesson)

The correct syntax for submitting the bundle using Notarytool is

xcrun notarytool submit --apple-id ##apple-id## --password ##password## --team-id ##team-id## ##file-path##

Parameters:
--apple-id ##apple-id## Developer Apple ID.
--password ##password## App-specific password for your Apple ID. You will be
given a secure prompt on the command line if Apple ID
and Team ID are provided and '--password' option is
not specified.
--team-id ##team-id## Developer Team ID

##file-path## The complete filepath of the file that shall be submitted

Replace the ##...## placeholders with the appropriate values. You should wrap values with quotes.

The shorter command is

xcrun notarytool submit --keychain-profile "##keychain-profile##" "##uploadfile##"

The parameter --keychain-profile replaces the parameters --apple-id, --password --team-id

But this requires that you add this information to your Key Chain. See
https://lessons.livecode.com/m/4071/l/1653720-code-signing-and-notarizing-your-lc-standalone-for-distribution-outside-the-mac-appstore-with-xcode-13-and-up#addendum-1-reference-to-a-keycain-stored-password

The stack make use of the shorter command.

If notarizing still fails, then please post your xcrun submit command here, but please replace any sensitive data like the password, team-id and apple-id with "xxxxxx"

Regards,
Matthias

Panos

@Matthias

In section 7.3 the first terminal command is missing the "info" command after the "notarytool" command.

Also, in the example below, I think the "status" command should be "info" instead.

Thank you!
Panos

Matthias Rebbe

Thanks Panos for pointing this out. It is now fixed.
Regards,
Matthias

Jeff Jansen

Thank You! I was able to easy follow these directions and use the included stack to sign my app and PKG file so that they would run correctly when downloaded. It's very kind of you to write an application to automate all these steps. Thank you for all the work you put into this. It has helped me tremendously.

jeff k

Hi Matthias --
Just noticed that here the terminal command in section 3.1.1 includes the "timestamp" command, whereas this is missing in the PDF version of the lesson.
I know that creating a PDF version is lots of work, but I've found it helpful because my browser is so frequently busy searching for reasons why the signing procedure fails for one reason or another.
Thanks.
jeff k

Matthias Rebbe

Hi Jeff,
thanks for pointing this out. I've updated the PDF file.
Regards
Matthias

jeff k

Matthias --
Just want you to know that once I resolved complicated Keychain-related issues, your updated stack worked *flawlessly* in signing & notarizing & stapling my standalone for distribution.
In my case, this did require switching to a newer Mac onto which I could install Xcode 13, importing from the older Mac my identity as a .p12 file, and updating the intermediate signing certificate in Keychain. All of which was not obvious without spending days on the internet searching for clues.
One might think that Apple would make this easier for us, but your help was invaluable.
Best,
jeff k

Matthias Rebbe

Jeff, thanks your your kind words.
Regards,
Matthias

Georges Malamoud

Your app worked very well with no error messages.
But on Sonoma, because of gatekeeper, I had to apply also this command at the end, in order to open the app for the first time :

xattr -d com.apple.quarantine path_to_app

Matthias Rebbe

@Georges

Did you try to open it by right clicking and selecting open before you ran the xattr.... command?

Regards,
Matthias

Georges

No. Just double clicks - sorry for the amateurism. It was a version transmitted to one of my clients (different Mac then). But the problem is solved now.

Add your comment

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.