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 ~ %
7.4. staple the app, DMG or PKG. Optional, but recommended.
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.
7.4.1. staple the app. Optional, but recommended.
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. ;)
7.4.2. staple the DMG/PKG. Optional, but recommended.
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
}
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.
Peter Bogdanoff
When using the MrSign V4 stack I get an error:
Conducting pre-submission checks for MITA.zip and initiating connection to the Apple notary service...
Error: HTTP status code: 401. Invalid credentials. Username or password is incorrect. Use the app-specific password generated at appleid.apple.com. Ensure that all authentication arguments are correct.
This worked before. I think the issue is that I changed my Apple ID password earlier which revoked all current app-specific passwords. So I went to my iCloud site and generated a new app-specific password. That is now in my keychain. But the mrSign stack doesn't seem aware of the new password item "MITA Build".
How do I get mrSign to read the keychain properly and finish the process?
Panos Merakos
@Peter
If you go to the Settings card, does the "Keychain-Profile" field reference the new password item "MITA Build"?
Panos