LiveCode LessonsLiveCode LessonsHow To - Step-By-Step Guides To Tasks In LiveCode Signing ApplicationsCodesigning and notarizing your LC standalone as DMG for distribution outside the Mac Appstore

Codesigning and notarizing your LC standalone as DMG for distribution outside the Mac Appstore

This tutorial describes the following tasks to get your app codesigned and notarized for distribution outside the Mac Appstore as DMG.

- Codesinging your app (including some necessary preparations)

- creating and codesigning the DMG using DropDMG or hdiutil

- Notarizing your app (including final stapling) using the shell or App Wrapper 3

 

There´s also a Livecode stack available which does steps 2 to 7 for you automatically. See addendum 2

 

 

1. Prerequisites

Please make sure that you fulfill 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 Deverloper  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 developer@mrd.de as Developer ID.

1.5. 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 the one you need for this tutorial

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

- Developer ID Installer

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.6. 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.7. Xcode 10.2

For this tutorial Xcode 10.2.1 command line tools were used for code signing, notarzing and stapling.  Xcode 11 should work as well.

1.8. 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.<MyCompany>.MyAppname

 

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

 

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

 

 

2.2. Renaming the localization folders

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

open the folder Contents/Resources

you'll see .lproj folders. The names of all .lproj folders have to be iso langage 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.

For more information see the Apple documentation and ISO language codes.

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 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

3.1. Codesigning standalone - now codesign

Run the following command in Terminal

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

Replace <your_developer_id> 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 --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

4. Verifiying 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 codesigned or not.

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

5. Creating DMG

Run the following command in Terminal to create the DMG

hdiutil create -volname "<Name_of_Volume>" -srcfolder "<path_to_your_app>" -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_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

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

 

Example

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

 

 

The above command would create a DMG  with the name DropUpload.dmg. When mounted the volume name would be DropUpload.

 

 

6. Codesigning the DMG

Run the following command in Terminal

codesign --deep --force --verify --verbose --sign "<your_developer_id>" --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 signing was successfull then you should see something like this

 

7. Verifying the codesigning (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 the 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"

 

 

8. Notarizing your DMG

If you own App Wrapper, you can do the final Notarizing with its new Notarizer Tool (see Addendum 3)

Or, we can do it with Terminal (see the following substeps.)

8.1. Upload the file to Apple for Notarization /Analysis

Run the following command in Terminal

xcrun altool -type osx --notarize-app --primary-bundle-id "<BundelIdentifier>" --username "<your_AppleID>" --password "<yourAppSpecificPassword>" --file "<path_to_dmg>"

<BundleIdentifier> = this is the identifier you´ve set in the standalone settings for your app. It is also shown in terminal after the code signing was successfull (see screenshot in step 3.1.)

Put it in quotes

 

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

Put it in quotes

 

<yourAppSpecificPassword> = The password you´ve created at https://appleid.apple.com   For details see  Prerequisites 1.3.

Put the password in quotes.

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

 

<path_to_DMG> = the path to the  DMG.

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 on terminal window. This will take care of spaces etc. as well

 

Example

xcrun altool -type osx --notarize-app --primary-bundle-id "tk.rebbe.dropuploadx>" --username "<developer@mrd.de>" --password "tic-tac-toe" --file "/users/matthias/name.dmg" 

 

If the upload was successful and the file was accepted for notariziation you should see something like the output in the screenshot below

*** Please make a record of the returned RequestUUID (either by copying it to the clipboard, making a screenshot or just by writing it down). You will need it later. ***

 

Apple is now analysing your uploaded file. If all is well, you´ll get an email from Apple confirming that your app is ready for distribution.

The analysis process could take a while. The fastest here was about 2 minutes, the longest so far 35 mintues.

If you don´t want to wait for the Apple confirmation e-mail  and want to check the notarization status see step 8.2.

 

 

8.2. Check the status of analysis

Run the following command in Terminal

xcrun altool --notarization-info <requestUUID> --username "<your_AppleID>" --password "<yourAppSpecificPassword>"

<requestUUID> = the returned ID from step 8

<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.

 

Example

xcrun altool --notarization-info 8a741234-12b4-1d34-12a4-74abcde2e93c --username "developer@mr-d.de" --password "tic-tac-toe"

If the anaylsis process is not finished then you see something like this

 

8.3. Check the status of analysis - invalid

There might be other messages like Status: invalid

This could come up, if you´ve forgot to do the preparations listed step 2

8.4. Check the status of analysis - Success

If the anaylsis process was successfull you should see something like this

with Status Message: Package Approved

8.5. confirmation e-mail from Apple

You will also receive an e-mail from Apple informing you about the result of the notarization/analysis.

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 ticket even when a network connection isn't available.

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

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

 

 

 

To staple the DMG run the following from Terminal

xcrun stapler staple -v "<path_to_dmg>"

Replace <path_to_DMG> with the path of the  DMG.

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 on terminal window. This will take care of spaces etc. as well

 

Examples

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

 

If you want to distribute the original standalone, which still is outside the DMG, (for example as a zip file), then you could staple that as well.

 

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. ;)

 

 

 

9. Addendum 1 - reference to a keycain stored password

Instead of using your  password directly in the Terminal commands you can use a reference to the saved password in keychain. Therefore you have to store your password in Keychain Access.

9.1. Use terminal to store password in Keychain.

Enter the following command in Terminal

security add-generic-password -a "<apple_id>" -w "<app_specific_password>"  -s "<keychain_item_name>"

Replace <apple_id> with the your Apple ID you´ve use to join the Apple Developer Program. Put it in quotes

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

Replace <keychain_item_name> with the name you want the password be saved under in Keychain. This will be the Keychain Item Name.  Put it in quotes.

Example

security add-generic-password -a "developer@mrd.de" -w "tic-tac-toe"  -s "Notarizing"

The above example would add  the password tic-tac-toe for  account developer@mrd.de to Keychain and would name it Notarizing.

 

9.2. Use Keychain Access to store password in Keychain

 

- Select File->New Password Item (cmd+N)

- Enter the desired name example Notarizing in the field Keychain Item Name

- Enter your developer email example developer@mrd.de in the field Account Name

- Enter your app specific password example tiac-tac-toe in the field Password

 

 

The screenshot shows the German GUI of the Keychain Access.app. See red translations.

9.3. How to reference to a Keychain password?

 

In Step 8 the password parameter was

--password "<yourAppSpecificPassword>"

Example

--password "tic-tac-toe"

 

 

To reference to a password in keychain the parameter would be

--password "@keychain:<name_of_pw_in_keychain>"

Replace <name_of_pw_in_keychain> with the Keychain Item Name you´ve use when adding the password to the Keychain

Example

--password "@keychain:Notarizing"

 

Importan Note: The first time you run altool (step 8), you get a security confirmation dialog asking you whether to allow altool to read the password from the keychain. Enter your user password and click on Always allow.

 

10. Addendum 2 - Livecode stack

Using author´s Livecode stack to automate the above steps (currently for step 2 - 7)

 

There is also a screen recording available showing how to use the stack. The file size of the video exceeds the filesize limit on this system.

Therefore you have to go here to watch the video: https://livecode.dermattes.de/mrSign_Notarizer_lc_lesson.mp4

 

10.1. The Livecode Stack

For steps 2 to 7 there´s  a Livecode  stack available which does the required preparations, code signing and  DMG creating.

The stack also allows the use of DropDMG to create the DMG. So if you own DropDMG you can use its command line tool for DMG creation instead of hdiutil

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

Future versions of the stack will also do the notarization and stapling.

 

Feel free to change or extend the stack. but be warned, the code needs to be polished, as it was created  in a hurry for a project.

But it works. ;)

 

10.2. What is what

1 Pressing the Trash bin empties all fields

2 Click gear icon to show settings

3 Drag and drop your standalone bundle on field App bundle

4 After successful code signing  your app this field will show the BundleID which will be needed later in Step 8 (Notarizing your DMG)

5 Click double page icon to copy the BundleID to clipboard

6 Status field shows status information

7 enabling Debug mode option, does not run anything but creates the needed commands with placeholders (except renaming the localization folders from step 2)

8 Button to start the action

10.3. General settings

1 exit the settings

2 save the current settings

3 your sudo password (needed for some commands in step 2)

4 your AppleID

5 your DeveloperID Application

e.g. Developer ID Application: Matthias Rebbe (386687PEUL)

6 enable this option to use DropDMG (DropDMG and its commandline tool have to be installed), when enabled you´ll see a link to the DropDMG settings

7. overwrite existing DMGs when using hdiutil for DMG creation

   if not selected, then instead of overwriting the DMG, the seconds are added to the name of the DMg

   Example name_1562965014.dmg

8 click to go the the DropDMG settings (only visible when UseDropDMG is selected)

10.4. DropDMG settings

1 exit the settings

2 click icon to empty all fields except the path to the commandline tool of DropDMG

3 save current settings

4 path to the commandline tool of DropDMG (default is /usr/local/bin/dropdmg

5 click the button to list all available configruations in DropDMG

6 the button to list all available layouts in DropDMG. Note: If you´ve defined a Layout in your choosen configuration then there is no need to fill this field

7 click the button to list all available licenses in DropDMG. Note: If you´ve defined a License in your choosen configuration then there is no need to fill this field.

8 enable to overwrite existing DMG, otherwise a counter is added to the name of the newly created DMG. This is automatically handled by DropDMG´s command line tool

  Example  name-1.dmg

11. Addendum 3 - App Wrapper

Using App Wrapper to do the final Notarization and Stapling of the DMG.

Note: App Wrapper 3.9.1 or higher is needed.

As of the time of writing this tutorial App Wrapper 3.9.1 was still in beta.

11.1. Open Notarizer tool in App Wrapper

You´ll find it under Tools -> Notarizer

11.2. Adding an account

Before you can use App Wrapper´s Notarizer you´ll need to add an account.

11.3. Add Developer Account Info

This account info will be stored in Keychain.

1. enter an account name of your choice . This will be the name under which the password is stored in the Keychain.

2. enter your developer e-mail adress

3. enter the app specific password you´ve created at https://appleid.apple.com

4. press SAVE to store the data in the Keychain

11.4. Starting the Notarization process

Add your codesigned DMG into the window

11.5. Enter some required information

1. Enter here a product version. This is just for you as a reference.

2. Enter here the bundle identifier from step 4. (see screenshot in step 4)

3. This shows the Code signature which was used to sign the DMG.

Note: if the DMG was not already signed,  you´ll see a dropdown menu. see annotation 6

In this case select the correct Developer Certificate. As we want to distribute outside the Appstore, we select the certificate for web distribution.

Don´t be confused about the "Web: Matthias Rebbe". Web: indicates that this is the certificate for distribution outside of the App Store.

4. select an account you want to use. Remember this is the account we´ve added in step 3 of this addendum 3.

5. press the Add button to proceed

11.6. submit the DMG to Apple

1. Press the submit button to submit the DMG to Apple and start the Notarization process

11.7. File is now uploading

The first time you upload a file using a newly created account (from step 3) you´ll need to enter your user password to grant altool the access to Keychain to get the app specific password it needs to authenticate with Apple.

1. enter your computer password here

2. press  Always allow (recommended)  or Allow

If you press Allow, then you have to enter your password again the next time altool tries to access the Keychain

 

I am working with a German Mac OS, so the screenshot just shows the German text.

11.8. Status Window - Uploading

You should see now that the DMG is uploaded to Apple.

11.9. Status Window - Uploaded, waiting for first check

After the file is successfully uploaded Apple will analyse the DMG.

Appwrapper checks analysis status with increasing time intervals.

11.10. Status Window - still in progress

If the analysis is not finished yet you see Anaylsis still in progress

11.11. Status Window - waiting for next check

If the analysis status is still in progress then Appwrapper waits again some time before it checks the status again.

11.12. Status Window - Ready for deployment

When anaylsis and notarization is finished  you´ll see Ready for Deployment in the status window

The DMG is now notarized and already stapled.

The DMG is ready for distribution now.

11.13. confirmation e-mail from Apple

You should also receive an email from Apple notifying you that your software has been notarized.

11.14. staple also the original app outside the DMG

Please see step 8.6 for information how to staple an app.

 

0 Comments

Add your comment

E-Mail me when someone replies to this comment

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