A journey through Pandoras Box
In part 1 of this 2 part series, we first took a shallow look into macOS application deployment, I warned you of the horrors, grief and pain to come, and provided some instructions on how to prepare yourself for this task as well as how to check whether an application that you want to deploy is signed and notarized.
In Part 2, i will try to cover all aspects of the hell that is – packaging an unsigned and non-notarized application.
There are a few things you will want to do before starting to package and notarize applications. Completing these steps early in the process will help to ensure that you wont have issues further down the track.
- Update your macOS to the latest version
- Download xcode from the appstore – if you already have this installed, ensure its the latest version (check for updates)
- If you dont already have one – Create an Apple ID.
- Have a $100USD ready
Apple Developer Program
In order to be able to sign and notarize applications, you need a certificate to be able to sign the application with, and an account to be able to use for submitting notarization. For this, we will need to sign up to the Apple Developer Program.
This can be completed by following this link here – Before You Enroll – Apple Developer Program
The annoying thing here is that this is not an instant process and can take a few business days to complete. I did find i was able to get this completed much quicker by calling Apple Support – Worldwide Telephone Support – Apple Developer and telling them that i was waiting for my account to be activated, after which it was instantly activated.
1. Apple Developer Program – Generating a Developer ID Certificate
First things first, Once you have your Apple Developer ID membership activated, you will then have access to the Apple Developer Program and be able to generate a Developer ID Certificate
- Navigate to Certificates, Identifiers & Profiles – Apple Developer
- Click on the + icon next to Certificates
3. Select “Developer ID Installer” and then click on Continue
4. You will then be taken to a page where you are required to upload a certificate signing request(CSR). The instructions for this are fairly straight forward and can be found here. Once you have generated your CSR, you will need to upload it to the page, then click on continue.
5. Once completed successfully, you will be presented with a page that contains some information about your certificate aswell as an option to download it, click download and save the certificate.
6. Once you have downloaded the certificate, double click certificate and click on “Add” to add the certificate to your keychain. You can then verify that the certificate has been successfully imported by opening keychain and checking or by running a command.
To check for the certificate via command line, open terminal and run the below command.
security find-identity -v
2. Preparing the .pkg
Preparing applications that arent in .pkg format
Note: If your application is already available in .pkg format, you can skip this section
For the purpose of this walk-through, i have chosen to demonstrate this process using an opensource VPN application called Tunnelblick. I have chosen to complete this using Tunnelblick as it covers a couple scenarios that will sometimes be faced. The idea is that by adding these scenarios into this blog post, you wont also have to go around googling….
“How to convert application to .pkg”
“How to convert .dmg to pkg”
Tunnelblick is an opensource VPN application that comes wrapped in a DMG, is not signed, and therefore not notarized. As a result we have 2 things that we need to do here.
- Extract the application file from the .dmg
- Convert the application file into .pkg (Remember – intune only accepts .pkg format installers)
How to get the .pkg from a .dmg
Double clicking the .dmg installer will mount and launch the application for you, we only really want one thing here, which is to get the .dmg mounted so that we can extract the application file.
- Double click the downloaded .dmg
- Close the application installer window
- Through Finder, Navigate to the mounted .dmg file
- Copy the Tunnelblick application file to your desired location (In my case i just copied it to desktop)
How to convert .app to .pkg
- Run Terminal
- Enter the command below
sudo pkgbuild --install-location /Applications --component ./Desktop/Tunnelblick.app ./Desktop/Tunnelblick.pkg
- sudo – running commands as sudo helps rid us of permission errors.
- pkgbuild – the script that executes the “conversion”
- –install-location – this defines where the .pkg file will place the application in.
- –component – The source file and the destination file locations are defined here
The command should run and complete as below.
You can then run a quick installation test using the newly created .pkg file and verify that it installs correctly.
I suggest uninstalling the application after this test.
3. Signing the .pkg
Checking signed status
Now that we have our .pkg file ready, we can proceed with signing the .pkg file. First of all, lets check its signed status by running the following command
pkgutil --check-signature ./desktop/Tunnelblick.pkg
We can see that the package is not signed and returning a “Status: no signature”. We can proceed with signing the package.
To sign the package, we run the following command. If you are unsure of your Developer ID Installer, refer to this step above.
productsign --sign "Developer ID Installer: Firstname Lastname" ./Desktop/Tunnelblick.pkg ./Desktop/Tunnelblick_Signed.pkg
- productsign – The script in charge of perfoming the signing action
- –sign – The script argument that defines the Apple Developer ID Certificate to associate to the .pkg
- ./Desktop/Tunnelblick.pkg – The .pkg source file path and name
- ./Desktop/Tunnelblick_Signed.pkg – The target file path and name of the newly generated, signed .pkg file.
Now that we have run the command to sign the package. Lets run the command to check for a signature again and verify its status.
pkgutil --check-signature ./desktop/Tunnelblick_Signed.pkg
As can be seen above, the Tunnelblick_Signed.pkg has now been signed with the developer ID certificate. The package is now ready to be sent for notarization.
3. Notarizing the .pkg
The command that we will use to notarize the package will look something like this
xcrun altool --notarize-app --primary-bundle-id "com.ccextensions.ext3" --username "YourAppleID@mail.com" --password "abcd-efgh-ijkl-mnop" --file "/fullpath/tothe/Tunnelblick_signed.pkg"
There are several things that are required when it comes to notarizing a package. You will require a;
- Bundle ID
- Your AppleID email
- A apple app-specific password
So, now what are these and how do we get them? (we have a huge issue here if you still dont know your AppleID email and have made it this far….)
Retrieving the BundleID
I found the easiest and quickest way to retrieve the bundleid for an application is to simply, install the application on the Mac, then run the below command.
osascript -e 'id of app "Tunnelblick"'
We can see that in the case of tunnelblick, our bundle ID is “net.tunnelblick.tunnelblick”
Generating an App-Specific Password
As can be seen from the command that we will use to notarize the package, we also need an app-specific password.
- Sign in to your Apple ID Account page.
- Click on “Sign-in and Security”
- Click on “App-Specific Passwords”
- Click the + icon to the right of “Passwords”
- Enter a name for the password and click on Create
You will then be presented with an app-specific password. Note this down.
Now that we have our BundleID, Apple ID, app-specific password & our signed .pkg, we are ready to submit the app through to apples notarization servers.
Based off what we have determined, the command should look like the below.
xcrun altool --notarize-app --primary-bundle-id "net.tunnelblick.tunnelblick" --username "YourAppleID@mail.com" --password "uykc-eoou-osrc-asdf" --file "./Desktop/Tunnelblick_signed.pkg"
- xcrun – calls xcode so that we can run xcode executables
- altool – the xcode executable that performs notarization
- –notarize-app – the flag that tells altool to request notarization
- –primary-bundle-id – links to the installers bundle id
- –username – your apple username to verify the app-specific password against
- –password – your app-specific password
- –file – the file that you want to upload with notarization
Dependent on the size of the package that you are uploading, the time that the command takes to run varies. While it performs its upload you will simply be left with an open command in terminal, once it has uploaded, you should get something like the below back.
Notarization time also varies dependant on the size of the package as well as the load on Apple servers. Using the RequestUUID that has been provided from running the last command, we can check on its status using the below command.
xcrun altool --notarization-info d11a1221-d204-437b-abcd-a9d052372cdc --username "YourAppleID@mail.com" --password "uykc-eoou-osrc-asdf"
As can be seen on the image below, the package has been approved and the status of notarization is success.
You should also receive an email to your AppleID Email with notarization results.
Stapling the notarization ticket to the file
Performing the action of stapling the notarization success result to the file is a step that is done as best-practice, although not really required. All it is doing is essentially stapling the success result to the package, which means that gatekeeper does not need to contact any apple servers to verify the notarization status of a package.
The command to perform stapling is as below:
xcrun stapler staple "./Desktop/Tunnelblick_Signed.pkg"
Last but not least.
Lets confirm that our package is notarized.
spctl -a -vvv -t install ./Desktop/Tunnelblick_Signed.pkg
And so there you have it. Hopefully, this is a good enough guide to assist you in getting your applications signed and notarized and ready for intune deployment.
There is no doubt, that along the way you will run into issues at certain points. One thing that i have noticed is sometimes, a simple restart of the Mac will clear the issue. Other times, simply retrying the command with sudo also helps to alleviate the issue.
If you have any questions or issues, please reach out via comments and ill do my best to help when i can.
Thanks for reading 🙂