Running a Command as another User

This post is an update to an older post on the same topic. macOS has changed and I had a few things to add. Rather than keep modifying the older post, I decided to make this new one.

As MacAdmins, most of the scripts we write will use tools that require administrator or super user/root privileges. The good news here that many of the management tools we can use to run scripts on clients already run with root privileges. The pre– and postinstall scripts in installation packages (pkgs), the agent for your management system, and scripts executed as LaunchDaemons all run with root privileges.

However, some commands need to be run not as root, but as the user.

For example, the defaults command can be used to read or set a specific setting for a user. When your script, executed by your management system, is running as root and contains this command:

defaults write com.apple.dock orientation left

Then it will write this preference into root’s home directory in /var/root/Library/Preferences/com.apple.dock.plist. This is probably not what you intended to do.

Get the Current User

To get the correct behavior, you need to run the command as a user. Then the problem is as which user you want to run as. In many cases the answer is the user that is currently logged in.

I have written a few posts about how to determine the currently logged in user from shell scripts and will use the solution from those:

currentUser=$( echo "show State:/Users/ConsoleUser" | scutil | awk '/Name :/ { print $3 }' )

This will return the currently logged in user or loginwindow when there is none. This is the Posix sh compatible syntax, which will also run with bash or zsh.

Running as User

There are two ways to run a command as the current user. The first is with sudo:

sudo -u "$currentUser" defaults write com.apple.dock orientation left

The second is with launchctl asuser.

uid=$(id -u "$currentUser")
launchctl asuser $uid launchctl load com.example.agent

The launchctl command uses the numerical user ID instead of the user’s shortname so we need generate that first.

It used to be that the sudo solution would not work in all contexts, but the launchctl asuser solution would. This changed at some point during the Mojave release time.

Now, the lauchctl asuser works and is required when you want to load and unload LaunchAgents (which run as the user), but it does not seem to work in other contexts any more.

So, for most use cases, you want to use the sudo solution but in some you need the launchctl form. The good news here is, that you can play it safe and use both at the same time:

launchctl asuser "$uid" sudo -u "$currentUser" command arguments

This works for all commands in all contexts. This is, however, a lot to type and memorize. I built a small shell function that I use in many of my scripts. Paste this at the beginning of your scripts:

# convenience function to run a command as the current user
# usage:
#   runAsUser command arguments...
runAsUser() {  
  if [ "$currentUser" != "loginwindow" ]; then
    launchctl asuser "$uid" sudo -u "$currentUser" "$@"
  else
    echo "no user logged in"
    # uncomment the exit command
    # to make the function exit with an error when no user is logged in
    # exit 1
  fi
}

and then you can use the function like this:

runAsUser defaults write com.apple.dock orientation left

runAsUser launchctl load com.example.agent

Note: the function, as written above, will simply do nothing when the Mac is sitting at the login window with no user logged in. You can uncomment the exit 1 line to make the script exit with an error in that case. In your script, you should generally check whether a user is logged in and handle that situation before you use the runAsUser function. For example you could use:

if [ -z "$currentUser" -o "$currentUser" = "loginwindow" ]; then
  echo "no user logged in, cannot proceed"
  exit 1
fi

Insert this at the beginning of your code (but after the declaration of the currentUser variable) and you can assume that a user is logged in and safely use the $currentUser variable and the runAsUser function afterwards. The exact detail on when and how you should check for a logged in user depends on the workflow of your script. In general, earlier is better.

When to Run as User

Generally, you should run as the user when the command interacts with the user interface, user processes and applications, or user data. As MacAdmins these are common commands you should run as the user;

  • defaults, when reading or changing a user’s preferences
  • osascript
  • open
  • launchctl load|unload for Launch Agents (not Launch Daemons)

This is not a complete list. Third party configuration scripts may need to be run as root or user. You will need to refer to documentation or, in many cases, just determine the correct action by trial and error.

Sample Script

I have put together a script that combines the above code into a working example.

macOS 11

Last week at WWDC, Apple had two big announcements for the Mac platform.

The first one was a new user interface design, much closer to iPadOS and iOS. Apple considers this the “biggest design upgrade since the introduction of Mac OS X.” Because of this, Apple also gives this version of macOS the long-withheld ‘11’ as the major version number.

You can take a look at the new UI on Apple’s Big Sur preview page or you can download the beta from your AppleSeed for IT or Developer account. It shares many elements, styles and icons with iOS or iPadOS.

The other major announcement is that the Mac platform will have a transition from Intel CPUs to ‘Apple Silicon’ chips built by Apple themselves, just like the iPhone and the iPad. The Developer Kit for testing purposes is powered by the A12z chip that powers the iPad Pro, but Apple was insistent that future, production Macs would have chips designed specifically for Macs and not be using iPad or iPhone chips.

These are big announcements, for sure. But what do they mean for the macOS platform? And for MacAdmins in particular?

Apple’s commitment to Mac

There was a time not so long ago, where you got the impression that the Mac platform was merely an afterthought for Apple. I think it started after the release of the ‘trashcan’ Mac Pro. During those years, I think there was legit concern that Apple would lock down macOS as tightly as they did iOS, breaking what makes the Mac special.

Some of the recent additions to macOS, such as the increased privacy controls with their incessant prompts for approval, deprecation of built-in scripting run-times like Python and Ruby and even the deprecation of bash in favor of zsh, have made some ‘Pro’ users nervous and afraid that Apple wants to turn macOS in to iOS.

Now the unification of the user interface can add to those concerns: will macOS turn into iOS and iPadOS in more than just look and feel?

On the other hand, Apple has been more vocal and open about their plans for the Mac. This started when Apple announced they were working on a new Mac Pro in April 2017.

In Mojave (2018), and then Catalina (2019), Apple introduced several technologies unique to macOS:

  • System and Network Extensions
  • File Providers
  • DriverKit
  • Notarization
  • zsh as new default shell, dash

These technologies exist because Apple wants (or needs) to increase the security of macOS. Kernel extensions, which provide unfettered access to all parts of the system are replaced with System and Network extensions and DriverKit. Notarization allows Apple to check and certify software delivered and installed outside of the Mac App Store. zsh allows Apple and their users to move forward from a 13-year old bash version.

But, if Apple wanted to lock down macOS as completely as iOS and iPadOS, they wouldn’t have to introduce these new technologies to macOS. Instead, they are introducing new technologies to allow certain characteristics of macOS to continue, even with increased security. This is a lot of effort from Apple, which convinces me that Apple sees a purpose for macOS for years to come.

What are these characteristics that Apple thinks are special for the macOS? Apple told us in the Platforms State of the Union session this year. Starting at 15:10 Andreas Wendker says:

“Macs will stay Macs the way you know and love them. They will run the same powerful Pro apps. They will offer the same developer APIs Macs have today. They will let users create multiple volumes on disks with different operating system versions and they will let users boot from external drives. They will support drivers for peripherals and they will be amazing UNIX machines for developers and the scientific community that can run any software they like.”

This short section makes a lot of promises:

  • Pro Apps: including third party pro apps, like Affinity Photo, Cinema 4D, Photoshop, shown previously, and Microsoft Office, and Maya which were shown in the Keynote
  • Developer APIs: no reduced feature set
  • Disk and OS management: multiple volumes, external storage and boot, multiple versions of macOS on one device
  • Peripheral ports with custom drivers
  • UNIX machines for developer and science tools (this includes Terminal, Craig Federighi confirmed this in John Gruber’s interview)
  • ‘any software you like’
  • ‘flexibility and configurability’ (earlier in the presentation)

Apple wants to assure us that they understand what the macOS platform is used for. Remember that Apple uses macOS themselves for many of these tasks and it is unlikely they would want to switch to Windows or Linux based PCs for their work.

With all these assurances you can consider the UI changes to go merely ‘skin deep.’ Whether you like the new UI or not, the wonderfully complex innards of macOS should still be there for you to explore and (ab)use.

Mac Transition

When Apple announced the transition to Apple Silicon in the keynote, it felt like a repeat of the 2006 Keynote where Steve Jobs announced the Intel transition. Apple is even re-using the names for the technologies ‘Universal’ and ‘Rosetta,’ albeit with version ‘2’ attached. This is of course entirely intentional. Apple wants to assure that they have done this before and it worked out well.

How well this will really work will depend, not only on Apple alone, but on the third party developers. While Rosetta worked surprisingly well during the Intel transition, there was noticeable lag in some cases, and the soft couldn’t really unlock all of the hardware until there was a re-compiled version. I remember that every developer would proudly announce the availability of a universal binary.

Some solutions never made the jump. Some software solutions got lost when Apple finally turned off Rosetta in Mac OS X 10.7 Lion, the same way some solutions did not make the jump the to 64bit and are ‘lost’ unless you hold on to Mojave.

It is fair to blame the software developer for the lack of maintenance. Not all developers have the time to put in the effort to continually update a product, or they moved on to other companies or projects. Not all software products generate enough revenue to warrant any maintenance effort. From the user perspective, software that they paid for, has an arbitrary expiration date, the software vendor blames Apple, Apple blames the vendor. This is understandably frustrating.

Apple and macOS are certainly in a different place in the market than they were in 2007, but we will have to see how well the third-party developers and vendors take to the transition this time.

macOS 11 for MacAdmins

Enterprises, schools, universities, and organizations and their users are also in a different place these days. The addition of mobile devices (phones and tablets) as essential tools for the employees has forced many organizations to change their management and access strategies to be more flexible. The massive requirement to work remotely from the Coronavirus pandemic has accelerated this shift.

But once you have reworked your deployment and management strategies to work with one different platform, then adding a third or fourth platform to the mix will be less of a barrier. It will still be a significant effort, but it will not be as daunting and impossible as that first change. The changing infrastructure requirements have worked in favor of Apple platforms for the past years, lead by iOS, but pulling macOS behind them. But Apple has not yet had enough time to lock-in to these kind of deployments.

In education, ChromeBooks are gaining ground, mainly because of the price point, but also because of a powerful management framework. Dual booting your Mac to Windows with Bootcamp will not be possible on Apple Silicon. Additional problems stemming from the transition might just be enough to push users and organizations ‘over the edge’ to switch platforms.

Apple must have considered all this and believes the benefits from building their own chips for the Mac platform outweigh the downsides. Less heat and better battery life are obvious, quick wins. Apple’s A-series chips have a dedicated Neural engine for machine learning processes, which was already demonstrated.

Apple has brought some of the security benefits from iOS to the Mac platform with the T1 and T2 chips. These provide Touch ID and a secure enclave for certificates and encrypted internal storage. By removing the Intel chipset, Apple can tighten the security even more. The new Apple Silicon based system will have new startup options and more flexible secure boot settings. External boot will not only still be possible, but not be disabled by default which will simplify many workflows for techs and admins. When you have multiple macOS systems on a drive, you will be able to disable security feature per system, so you can have a ‘less secure system’ for experimentation or development, while keeping all security features enabled for the system with your personal data.

Device Management

There weren’t many news about MDM at WWDC itself. The changes that were shown are refinements to existing workflows rather than big changes. With all the other changes, stability in MDM and management will be helpful.

We have finally been promised a true zero-touch deployment for Macs with “Auto Advance for Mac,” but are still lacking details about the exact implementation.

But there are still some huge gaps in the MDM strategy. Application deployment (VPP) is still unreliable. There is no way for organizations to purchase and manage in-App purchases and subscriptions in quantity. Many essential settings and features of macOS still cannot be set or controlled with configuration profiles or MDM commands. MDM still has no solution for installing and managing software from outside the App Store. PPPC settings are still changing and complicated to manage for admins.

Apple considers the ability to run iOS and iPadOS on macOS a huge bonus. How useful this will be in reality, outside of games, remains to be seen. But it will certainly make managing apps from the Mac App Store more essential than it is now.

The acquisition of Fleetsmith, on the other hand, will have a big impact on the Apple MDM market and users. I have described how the changes to the service have affected the users and admins in my newsletter last week. While this has cast an unnecessary shadow on the acquisition, we still don’t know what Apple’s plans regarding Fleetsmith and MDM are going to be.

Strange New World

The changes MacAdmins got for device management are useful and necessary, but evolutionary in nature. (There is nothing wrong with that.) The Fleetsmith deal shows the possibility of more and larger changes to Apple’s device management strategy in the future. It might take years before we will see the implications of this.

Versioning is always influenced by marketing. The switch from version 10 to version 11 is more than just the end of an odd versioning convention. The time where Mac OS X stands apart from the other Apple platforms is over. Apple is promising a family of devices where the user interface, hardware, and software will be unified, while preserving the special characteristics of each platform.

Apple is has explained why and how they want to distinguish macOS from the other Apple platforms. They will have to live up to these promises over the next few years. There is a balance to be kept between implementing beneficial features from the other Apple platforms and maintaining the ‘flexibility and configurability’ of macOS. There is also the possibility that some of these Mac characteristics will make their way to other Apple platforms. (multi-boot, virtualization, or custom device drivers on iPadOS?)

Not everyone follows the WWDC announcements closely. As MacAdmins we will get many questions about the news from last week that does surface. We have to inform our organizations and our fellow employees what these changes means for them and their workflows and help them make an informed decision on which platform (Apple or other systems) matches their requirements.

There are bound to be issues with Apple’s plans. We will need to watch Apple’s strategy, give feedback on missteps and requirements. It is certainly a frustrating process, but Apple has changed features because of feedback from the MacAdmin community in the past.

If you haven’t enrolled in AppleSeed for IT yet, now is the time! Download the beta, start testing and providing feedback!s

Installomator updated: v0.2

It’s been nearly a month since I introduced Installomator.

Since then, it has gotten lots of feedback from others and many contributions. As the changes, fixes and additional apps have accumulated, I have created a 0.2 release to get a stable new version. If you like living on the edge you can also use the dev branch for the latest update.

Changes in this version:

  • many fixes for broken URLs and other bugs
  • pkgInDmg and pkgInZip now search for the first pkg file in the archive in case the file name varies with the version
  • notification on successful installation can be suppressed with the NOTIFY variable
  • Apple signed installers and apps that don’t have a Team ID are verified correctly now
    improved logging
  • several new applications: count increased from 62 in v0.1 to 87 in v0.2

Thanks to all who contributed!

Also, if you haven’t already, you want to read Mischa’s guest post on using Installomator with Jamf Pro.

Using Installomator with Jamf Pro

I introduced the Installomator script a while back. We have been using the script with our own Jamf Pro server and some of our customers.

Since I built the script, you’d think I’d have pretty good idea on how it should be deployed. But then Mischa van der Bent showed me a better way of using Installomater with Jamf Pro and I asked him to write it up for a blog post. Since he doesn’t have a blog of his own (yet), he has allowed me to post his instructions here.

Note: Installomator is designed so it can work with other management systems, too. If you have implemented Installomator with a different management system, let me know!

Everything that follows is from Mischa:

Preparation

After you have downloaded or cloned Installomator from Github, you can run Installomator.sh from the command line or from your management system:

> ./Installomator.sh googlechrome

The script requires a single argument: a label that chooses the application to download and install. (you can find a list of labels of applications in the Labels.txt file in the repository)

Adding the Installomator Script to Jamf Pro

The first thing we need to do is create a new Script in Jamf by going to Settings > Computer Management > Scripts.
In the General section you can give the Script a Display Name. I called mine Installomator. Assign a category and add the link to the GitHub repository to the notes as a reminder of the source of this script.

In the Script section, paste the entire code from the Installomator.sh file.

Important: Change the DEBUG variable from 1 to 0 for using Installomator in procduction, otherwise it will not actually install the new software.

The script requires a single argument and designed to use argument 4 from Jamf when present.

We can set the Parameter Label of parameter 4 to “Application name” in the Options section. This is going to be a reminder that we need to fill in the argument when we are creating a policy. You can leave the labels for the other parameters empty or fill in “DONT-USE” because the script does not use the other arguments.

We are done here and you can save the Script.

Scoping

To make sure that we are targeting to the right devices with an older release version we need to create a couple of things.

I’m going to use Jamf Patch Management to determine the latest release version of Google Chrome. Jamf will check the version before publishing this into the Patch Management. And if the software title is not in Jamf default Patch Management list you can create your own Patch Management source and add this on to Jamf Pro. You can also join the community patch server.

Go to Patch Management under Computers > Content Management and create a New Software Title. We are going to use Jamf Repository. Scroll down the list and select Google Chrome.
The only thing we need to set here is the Software Title Settings and assign a Category. You can select the Jamf Pro Notification option to get emails when an update is posted..

Jamf Patch Management will query the inventory and list the clients where Google Chrome is installed and their versions. We now have the all the information we need!

Two Smart Computer Groups

Go to Smart Computer Groups and create a new one. I called this “Google Chrome not installed or out of date”

In the ‘Criteria’ section I add two criteria:

  • Patch Reporting Software Title: after choosing this select the right report; for our example select “Patch Reporting: Google Chrome”
  • change the ‘Operator’ to “Less than” with the ‘Value’ “Latest Version.”
  • add a second line and Changed the AND/OR to “or” and for the second criteria I used “Application Title”
  • change the ‘Operator’ to “does not have” with the ‘Value’ “Google Chrome.app”

This Smart Group will contain the clients where the application is not installed or is not up to date.

Unfortunately, we cannot use this smart group with a Policy. When you try you will get this error ‘Policy scope cannot be based on a smart computer group that uses the “latest version” criteria.’

But there is a work around:

  • create a second Smart Group, I called this one “Member of Google Chrome not installed or out of date”
  • in the ‘Criteria’ section add the criteria “Computer Group” changed the ‘Operator’ to “member of” with the ‘Value’ to “Google Chrome not installed or out of date”

The result is the same as the Smart Computer Group “Google Chrome not installed or out of date” but we can use this in a policy.

Policy

Let’s put all the bits and pieces together and create one policy that will install or update to the latest release version of Google Chrome. We also want to promote this in Self Service and we want to push this out as a mandatory update with a deferral duration of 7 days.

  • go to Policies and create a new one. I called this policy “Google Chrome”
  • use “Recurring Check-in as the trigger, and set the custom event value to ”googlechrome.” With the custom trigger name, we can use this policy in a script or can test with the terminal command sudo jamf policy -event googlechrome -verbose
  • set the ‘Execution Frequency’ to On-Going.
  • add the Installomator script to the payload
  • the Priority doesn’t matter, because there is no package, so leave it default ‘After’
  • in the Parameter values you see that the first one is ‘Application name’ (which we set earlier). Set “googlechrome” as value.

I removed the payload “Restart Options” because we don’t need to restart after we install Google Chrome , we can leave it there, but I like to keep my policies clean.

We need to report back to the Jamf Pro Server that we just installed the latest version so we are going to add the payload “Maintenance” and enable “Update Inventory” (this should be enabled by default).

We are done with the payload and need to set the Scope:

  • under target we add the Smart Computer Group: “Member of Google Chrome not installed or out of date”

Self Service

  • enable “Make the policy available in Self Service”
  • leave the Display Name the same as Policy.
  • Button Name Before Installation: use “Install”
  • Button Name After Installation: use “Update”
  • give a Description to display for the policy in Self Service like “Install or Update to the latest release of Google Chrome”
  • upload or select the Google Chrome icon for making the Self Service pretty (you can use the macOS Icon Generator app)
  • under User Interaction we change the Deferral Type to “Duration” and use 7 days.
  • we don’t need to set a Start or Complete Message (Installomator can notify on success)

Now, we can save and test the policy.

Testing

I tested this Policy with a couple of scenarios;

The first scenario is: no Google Chrome installed. Second: old version Google Chrome installed, notification for update, end user deferral, and later installation from the Self Service. Third: Google Chrome Beta is installed

The first scenario is easy, after running the policy latest version get installed.

In the second scenario I got prompted with the following message, and I submitted 1 hour.

I can’t install this update before the hour because I got this message in the jamf log “Policy ‘Google Chrome’ will not be executed because it was deferred by the user.”

The last scenario I installed the Google Chrome Beta version 84.0.4147.30, the latest version in Patch Management (for this moment) is 83.0.4103.61. This beta version registers as an “Unknown Version” and it will not fall into scope.

I can use this policy with the Installomator script to install the latest version on a clean machine, and I can push out an update (with a deferral time) to push a mandatory update in a polite way 😉

Because Installomator is checking the Developer Team ID of Google directly, I can be confident that it is the real installer from Google. So, we get security with less effort.

Introducing Installomator

As a System Engineer at an Enterprise Reseller, I have to manage and create many Jamf Pro instances.

Some of them are tightly managed and require version control on the OS and the apps. But, many of them are managed less stringently and often the requirement for applications is “install the latest version.”

This is not a statement which management strategy is ‘better.’ There are pros and cons for each. There are situations where either is really not appropriate. You will likely have to use a mixed approach for different pieces of software. When you are doing the first, more controlled deployment strategy, you really want to use AutoPkg and not this script. You can stop reading here.

Apple’s vision of deployment with ‘Automated App Installation’ through MDM (formerly known as VPP) is similar to the ‘less controlled’ strategy. When you install Mac App Store through MDM commands, then you will get the latest version available.

Not all applications are available on the Mac App Store. And even when they are available, installing applications with VPP is still unreliable and hard to debug, or retry when it fails.

If you are managing with the “just install the latest version” philosophy, then you probably have one or more scripts that will download and install the latest version of some software from the vendor’s website. This avoids the overhead work of having to download, repackage and manage every new update in the management system. (This can be automated with AutoPkg, but if you can avoid it entirely…)

When I started thinking about this, we had at least four different scripts. Most of them were internal, but William Smith’s installer script for Microsoft applications was a huge inspiration. it made me thing that you could generalize much of this.

Security Considerations

The main danger when downloading application archives and installers directly from the vendor is that a malicious actor might intercept the traffic or even hijack the servers and replace the download with a manipulated software that contains and or installs malware. Since management processes run with root privileges, we have to extra careful which files and processes are installed.

For user driven installation, Apple introduced GateKeeper, signed applications and Notarization as a way to verify downloaded software before execution. When you download software with a script, then you are bypassing GateKeeper. This is usually considered a benefit, because in a managed deployment we don’t want to scare and annoy a user with the warning dialogs.

But we can use the GateKeeper verification process in our script to verify that the archive, application, or installer is signed and notarized. With the spctl command, we can run the verification from the script without the user interaction.

We can even go one step further than GateKeeper. GateKeeper is happy when a software is signed and notarized with any Apple Developer ID. Since this script is working with a curated list of software, we can verify that the application is actually signed with the expected vendor’s Developer ID.

This will catch situations where someone creates or steals a Developer ID to sign and notarize a manipulated application. Apple can and will eventually block that Developer ID, but there will be a window where the manipulated application may be downloaded and installed. This is not theoretical, but has happened already. (more than once)

Installomator

With these ideas in mind, I started working on a script to unify all these installer scripts. (‘The one to rule them all.’) I may have gone a little overboard, but it turned into Installomator.

You can run Installomator from the command line or from your management system.

> ./Installomator.sh desktoppr

The script requires a single argument. The argument is a label that chooses which application to download and install. (As of now, Installomator can handle 56 applications, you can see a list of applications in the repository.

Please read the readme in the GitHub repository for more details.

Jamf or not

I have tried to keep Installomator generic enough that it can be used with platforms other than Jamf Pro.

However, we will use it with Jamf Pro, and thus I took the opportunity to add some workflows that Jamf is missing.

Drag’n Drop installations

“Drag this app to the Applications folder” is a common instruction found on downloaded dmg or zip archives for the Mac. The fact that Jamf Pro has always required repackaging and cannot directly handle application dmgs or zips is mystifying. Also, highly ironic, since Jamf delivers their own management applications in a disk image.

Nevertheless, Installomator can deal with apps that are downloaded in zip, tbz, and dmg archives.

Blocking Processes

Jamf will also happily attempt to install over a running application. So, Installomator will check for blocking processes and either stop the installation at that time or prompt the user and give them a chance to quit the application. (Yes, this is inspired by the behavior of Munki.)

Vendor update processes

Since Installomator will download and install the latest version of the application from the vendor website, it can be used for updates as well as first installations.

If an application has a built-in update process that can be triggered by the script, This can be used instead for updates. So, for Microsoft applications, when the script detects that the app is already installed, it will run msupdate instead of downloading a full installer. This way the update process will use Microsoft’s optimized thin updates. (Credit to Isaac Ordonez, Mann consulting for the idea and first implementation.)

So far, this is only implemented for Microsoft applications and Google Chrome. (and quite experimental)

Extensible

So far, the script can install 56 different applications or application suites. More application descriptions can be added fairly easily, by adding the proper variables. You can find more detailed explanations in the ReadMe, and of course, the existing applications serve as examples.

Not all applications are suitable to be installed with Installomator. To be able to install an application, the download URL must be accessible without requiring a login, and there must be some, fairly simple process to determine the URL for the latest version.

Installomator will only install the application itself, it will not configure any settings. You will have to use profiles, or additional scripts and installers for that.

When you add an application for your own workflow, please contribute as an issue or pull request! Thank you!

Installomator and AutoPkg

Obviously, much of Installomator’s workflow has been heavily inspired by AutoPkg. I have been using AutoPkg for a long time and provide a repository of recipes. And I plan to continue to use AutoPkg.

As mentioned before, Installomator is not suitable for every type of deployment. If you require control over the versions of the software deployed, then you need to download, re-package and manage the packages in your management system. This is obviously what AutoPkg was designed for.

Also, not every software can be installed with Installomator, mostly because the installer is not available as a direct download. In these cases, AutoPkg will be useful to automate the management and deployment, even when you management style is less controlling.

Going Forward

We have been using Installomator for the past few weeks in our own deployment and with one customer. We are now at a point, where we believe it is stable enough to share it and get feedback from other MacAdmins. (I have already shared it with a few, and many thanks to those that have given valuable feedback.)

We have been using this script with two smaller deployments and want to roll it out to more of our customers. But we probably haven’t hit all the weird edge cases yet. So, proceed with caution.

Consider this a beta release.

(Sidenote: I have tested the script with 10.14.6 and 10.15.x. Because it uses the notarization verification which is available in 10.14.4 and higher it will probably not run well on older macOS versions. Might be possible to adapt it though.)

If you are as excited about the script as we are, please start testing in your environment and provide feedback. But please, as with anything MacAdmin, don’t just go and push the script to hundreds or thousands of devices, but test, test, test first.

Then please provide any enhancements back on the GitHub repository. I have also created an #installomator channel on the MacAdmin Slack for discussion and questions.

Wrangling Pythons

As I noted in my last Weekly News Summary, several open source projects for MacAdmins have completed their transition to Python 3. AutoPkg, JSSImport and outset announced Python 3 compatible versions last week and Munki already had the first Python 3 version last December.

Why?

Apple has included a version of Python 2 with Mac OS X since 10.2 (Jaguar). Python 3.0 was released in 2008 and it was not fully backwards compatible with Python 2. For this reason, Python 2 was maintained and updated alongside Python 3 for a long time. Python 2 was finally sunset on January 1, 2020. Nevertheless, presumably because of the compatibility issues, Apple has always pre-installed Python 2 with macOS and still does so in macOS 10.15 Catalina. With the announcement of Catalina, Apple also announced that in a “future version of macOS” there will be no pre-installed Python of any version.

Scripting language runtimes such as Python, Ruby, and Perl are included in macOS for compatibility with legacy software. Future versions of macOS won’t include scripting language runtimes by default, and might require you to install additional packages. If your software depends on scripting languages, it’s recommended that you bundle the runtime within the app. (macOS 10.15 Catalina Release Notes)

This also applies to Perl and Ruby runtimes and other libraries. I will be focussing on Python because it is used more commonly for MacAdmin tools, but most of this post will apply equally to Perl and Ruby. Just mentally replace “Python” for your preferred language.

The final recommendation is what AutoPkg and Munki are following: they are bundling their own Python runtime.

How to get Python

There is a second bullet in the Catalina release notes, though:

Use of Python 2.7 isn’t recommended as this version is included in macOS for compatibility with legacy software. Future versions of macOS won’t include Python 2.7. Instead, it’s recommended that you run python3 from within Terminal. (51097165)

This is great, right? Apple says there is a built-in Python 3! And it’s pre-installed? Just move all your scripts to Python 3 and you’ll be fine!

Unfortunately, not quite. The python3 binary does exist on a ‘clean’ macOS, but it is only a stub tool, that will prompt a user to download and install the Command Line Developer Tools (aka “Developer Command Line Tools” or “Command Line Tools for Xcode”). This is common for many tools that Apple considers to be of little interest to ‘normal,’ non-developer users. Another common example is git.

Dialog prompting to install the Command Line Tools
Dialog prompting to install the Command Line Tools

When you install Xcode, you will also get all the Command Line Developer Tools, including python3 and git. This is useful for developers, who may want to use Python scripts for build operation, or for individuals who just want to ‘play around’ or experiment with Python locally. For MacAdmins, it adds the extra burden of installing and maintaining either the Command Line Developer Tools or the full Xcode install.

Python Versions, a multitude of Snakes

After installing Xcode or the Command Line Developer Tools, you can check the version of python installed: (versions on macOS 10.15.3 with Xcode 11.3.1)

> python --version    
Python 2.7.16
> python3 --version    
Python 3.7.3

When you go on the download page for Python.org, you will get Python 3.8.1 (as of this writing). But, on that download page, you will also find download links for “specific versions” which include (as of this writing) versions 3.8.1, 3.7.6, 3.6.10, 3.5.9, and the deprecated 2.7.17.

The thing is, that Python isn’t merely split into two major release versions, which aren’t fully compatible with each other, but there are several minor versions of Python 3, which aren’t fully compatible with each other, but are still being maintained in parallel.

Developers (individuals, teams, and organisations) that use Python will often hold on to a specific minor (and sometimes even patch) version for a project to avoid issues and bugs that might appear when changing the run-time.

When you install the latest version of Munki, it will install a copy of the Python framework in /usr/local/munki/ and create a symbolic link to that python binary at /usr/local/munki/python. You can check its version as well:

 % /usr/local/munki/python --version
Python 3.7.4

All the Python code files for Munki will have a shebang (the first line in the code file) of

#!/usr/local/munki/python

This ensures that Munki code files use this particular instance of Python and no other copy of Python that may have been installed on the system.

The latest version of AutoPkg has a similar approach:

> /usr/local/autopkg/python --version    
Python 3.7.5

In both cases the python binary is a symbolic link. This allows the developer to change the symbolic link to point to a different Python framework. The shebangs in the all the code files point to the symbolic link, which can be changed to point to a different Python framework.

This is useful for testing and debugging. Could MacAdmins use this to point both tools to the same Python framework? Should they?

The Bridge to macOS

On top of all these different versions of Python itself, many scripts, apps, and tools written in Python rely on ‘Python modules.’ These are libraries (or frameworks) of code for a certain task, that can be downloaded and included with a Python installation to extend the functionality of Python.

The most relevant of these modules for MacAdmins is the “Python Objective-C Bridge.” This module allows Python code to access and use the native macOS Cocoa and CoreFoundation Frameworks. This not only allows for macOS native GUI applications to be written in Python (e.g. AutoDMG and Munki’s Managed Software Center [update: MSC was re-written in Swift last year]), but also allows short scripts to access system functions. This is sometimes necessary to get a data that matches what macOS applications “see” rather than what the raw unix tools see.

For example, the defaults tool can be used to read the value of property lists on disk. But those might not necessarily reflect the actual preference value an application sees, because that value might be controlled by a different plist file or configuration profile.

(Shameless self-promotion) Learn more about Property lists, Preferences and Profiles

You could build a tool with Swift or Objective-C that uses the proper frameworks to get the “real” preference value. Or you can use Python with the Objective-C bridge:

#!/usr/bin/python
from Foundation import CFPreferencesCopyAppValue
print CFPreferencesCopyAppValue("idleTime", "com.apple.screensaver")

Three simple lines of Python code. This will work with the pre-installed Python 2.7, because Apple also pre-installs the Python Objective-C bridge with that. When you try this with the Developer Tools python3 you get an error:

ModuleNotFoundError: No module named 'Foundation'

This is because the Developer Tools do not include the Objective-C bridge in the installation. You could easily add it with:

> sudo python3 -m pip install pyobjc

But again, while this command is “easy” enough for a single user on a single Mac, it is just the beginning of a Minoan labyrinth of management troubles.

Developers and MacAdmins, have to care about the version of the Python they install, as well as the list of modules and their versions, for each Python version.

It is as if the Medusa head kept growing more smaller snakes for every snake you cut off.

(Ok, I will ease off with Greek mythology metaphors.)

You can get a list of modules included with the AutoPkg and the Munki project with:

> /usr/local/munki/python -m pip list
> /usr/local/autopkg/python -m pip list

You will see that not only do Munki and AutoPkg include different versions of Python, but also a different list of modules. While Munki and AutoPkg share many modules, their versions might still differ.

Snake Herding Solutions

Apple’s advice in the Catalina Release Notes is good advice:

It’s recommended that you bundle the runtime within the app.

Rather than the MacAdmin managing a single version of Python and all the modules for every possible solution, each tool or application should provide its own copy of Python and its required modules.

If you want to build your own Python bundle installer, you can use this script from Greg Neagle.

This might seem wasteful. A full Python 3 Framework uses about 80MB of disk space, plus some extra for the modules. But it is the safest way to ensure that the tool or application gets the correct version of Python and all the modules. Anything else will quickly turn into a management nightmare.

This is the approach that Munki and AutoPkg have chosen. But what about smaller, single script solutions? For example simple Python scripts like quickpkg or prefs-tool?

Should I bundle my own Python framework with quickpkg or prefs-tool? I think that would be overkill and I am not planning to do that. I think the solution that Joseph Chilcote chose for the outset tool is a better approach for less complex Python scripts.

In this case, the project is written to run with Python 3 and generic enough to not require a specific version or extra modules. An admin who wants to use this script or tool, can change the shebang (the first line in the script) to point to either the Developer Tool python3, the python3 from the standard Python 3 installer or a custom Python version, such as the Munki python. A MacAdmin would have to ensure that the python binary in the shebang is present on the Mac when the tool runs.

You can also choose to provide your organization’s own copy Python with your chosen set of modules for all your management Python scripts and automations. You could build this with the relocatable Python tool and place it in a well-known location the clients. When updates for the Python run-time or modules are required, you can build and push them with your management system. (Thanks to Nathaniel Strauss for pointing out this needed clarifying.)

When you build such scripts and tools, it is important to document which Python versions (and module versions) you have tested the tool with.

(I still have to do that for my Python tools.)

What about /usr/bin/env python?

The env command will determine the path to the python binary in the current environment. (i.e. using the current PATH) This is useful when the script has to run in various environments where the location of the python binary is unknown.

This is useful when developers want to use the same script in different environments across different computers, user accounts, and platforms. However, this renders the actual version of python that will interpret the script completely unpredictable.

Not only is it impossible to predict which version of Python will interpret a script, but you cannot depend on any modules being installed (or their versions) either.

For MacAdmin management scripts and tools, a tighter control is necessary. You should use fixed, absolute paths in the shebang.

Conclusion

Managing Python runtimes might seem like a hopeless sisyphean task. I believe Apple made the right choice to not pre-install Python any more. Whatever version and pre-selection of module versions Apple would have chosen, it would only have been the correct combination for a few Python solutions and developers.

While it may seem wasteful to have a multitude of copies of the Python frameworks distributed through out the system, it is the easiest and most manageable solution to ensure that each tool or application works with the expected combination of run-time and modules.

Downgrading a Mac that shipped with Catalina to Mojave

Apple has started shipping Mac models that used to come with Mojave pre-installed with Catalina. If your organization has blockers for Catalina (incompatible software, etc.) you may want to install Mojave on these Macs. Unfortunately, this is not so easy.

Important Notice: these instructions will only work for Mac models that can boot to Mojave. Usually a Mac requires at least the version of macOS that the model shipped with when it was introduced. As of this writing, all new Macs require at least Mojave. The exceptions are the iMac Pro (High Sierra) and the MacBook Pro 16“ and the Mac Pro (2019) which both require Catalina. You cannot use these instructions to force a Mac Pro or MacBook Pro 16” to boot to Mojave. Any new Mac models that Apple introduces from now on, will also require Catalina and cannot be downgraded to Mojave.

(Not meant as a challenge. I am aware that someone might be able to hack together a Chimera Mojave with Catalina drivers. These ‘solutions’ are not supportable on scale.)

Directly downgrading from Catalina to Mojave with the startosinstall --eraseinstall command will fail. Attempts to run the Mojave installer from a Catalina Recovery (local or Internet) will also fail. The reason seems to be that the Mojave Installer application chokes on some aspect of Catalina APFS. Apple is likely not very motivated to fix this.

So far, the recommendation has been to boot to Internet Recovery with the shift-command-R key combination at boot. This used to boot to a Mojave (more specfically, the system the Mac shipped with) recovery system, and then you can wipe and re-install Mojave. However, if a Mac was shipped with Catalina pre-installed, it will boot to Catalina Internet Recovery, regardless of whether the Mac can boot to Mojave or not.

We have to get creative.

External USB Installer

The solution requires a Mojave Installer USB disk. First download the latest Mojave installer. You can do so from by following this App Store link. If you are running Catalina, you can also use the new option in softwareupdate:

> softwareupdate --fetch-full-installer --full-installer-version 10.14.6


Then you can use the createinstallmedia command in the Install macOS application to build an external Installer Drive on a USB drive. You probably want to add the --downloadassets option to add the current firmware to the USB drive as well.

> createinstallmedia --volume /Volumes/Untitled --downloadassets


This will delete the target volume data on the USB disk.

Enable External Boot

To boot a new Mac with a T2 chip off an external drive, you need to allow external boot from the Security Utility in the Recovery partition. This utility is protected and requires the password of a local administrator user to access. When you get a new Mac “out of the box,” you cannot directly boot to Recovery to change this.

Instead, you have to boot to the pre-installed Catalina, work your way through the Setup Assistant, and create a local administrator user before you can boot to Recovery to change this setting.

You also need to connect the Mac to a network with non-filtered/proxied access to Apple’s servers, either with Wifi or an ethernet adaptor. You can see which services and servers the network needs to be able to access in this kbase article. You will definitely need the servers listed under ‘Device Setup’ from that list and many of the others, depending on your deployment workflow.

This network connection is required to verify the integrity of the system on the USB Installer drive. You could also disable ‘Secure Boot’ entirely, but that is not recommended as it will, well, disable all system security verifications.

Now, reboot the Mac and hold the option key, from the list of devices to boot from, select the Mojave Installer drive. Once booted to the Mojave installation drive, start Disk Utility. In Disk Utility, erase the entire internal drive. You may have to choose ‘Show All Devices’ from the View menu to be able to select the internal drive with all sub volumes, not just the system or data volume.

Then you can quit Disk Utility and start the Mojave installation process.

After completing the installation, you want to remember to return to Recovery and re-disable external boot again. However, you need to create a new admin account on the disk before you can do that…

Avoiding the Downgrade

This is obviously tedious and really hard to automate. (I have been wondering if you could build a MDS workflow, but this one would require at least three reboots.)

The preferred solution is for IT departments and organizations to have the workflows and infrastructure in place to support and use “latest macOS” (Catalina). Apple is discouraging system downgrades or using anything but “latest macOS.” On newer hardware — like the MacBook Pro 16″, Mac Pro 2019, and every new Mac Apple will introduce from now on — downgrading to Mojave is not possible at all, so you have to support Catalina when you (or your users) get those Mac models.

As mentioned before, I do not believe there is much motivation at Apple to simplify this particular workflow. It serves Apple’s interest and vision to push the latest macOS over previous versions. From a user perspective it allows better integration with their iOS and other Apple devices. From a security standpoint it provides the latest security updates and patches. Apple provides security updates for the previous two macOS versions, but those notoriously do not fix all the vulnerability that the latest macOS gets.

However, in some cases you may have blocking applications that cannot run, or cannot be upgraded to run on Catalina. Then this workflow can be a ‘last ditch’ solution until you get those ‘blockers’ sorted out.

Maybe the best solution is to use this complex and work intensive downgrade workflow as leverage to push for “latest macOS” support in your organization.

Thanks to Robin Lauren and Mike Lynn for figuring this out on MacAdmins Slack and sharing their results.

Book update: macOS Installation v5

There is a new update to my book “macOS Installation!”

It contains lots of updates regarding Catalina, and the usual list of typos and other fixes.

As usual, the update is free when you already own the book.

If you have already purchased the book, you can go to Apple Books application on your Mac and choose ‘Check for available Downloads…’ from the ‘Store’ menu. I have seen the Mac Books app be really slow (or even completely blind) in picking up updates, you can accelerate the process by removing the local download and re-downloading the book. In iOS tap on your iCloud account icon next to ‘Reading Now’ and then choose ‘Updates.’

If you have not yet purchased the book, I have good news for you: I have lowered the price!

Why did I lower the price? Let me explain…

This is the fourth update for “macOS Installation.” It might be its last.

When I first published the book in June 2018, I promised updates until the Mojave release. There have now been two updates beyond that: one for the Mojave “Spring” update, and another one for Catalina.

The format of the book had the original intention to help MacAdmins learn about and deal with the strange, new post-imaging world that came with the High Sierra and T2 Security chip. I like to believe it did that quite well. But since then, the releases of Mojave and Catalina have added more layers of complexity and information on top of that.

The post-imaging world isn’t new anymore. It is still strange, complicated, and sometimes hard to navigate. However, I feel that the book’s format would have to change to keep being a useful guide. Obviously, such a re-structuring is a massive effort and would pretty much result in a new book. Maintaining and updating a book is a lot of effort, re-writing it even more so.

Thus the decision that this might be last update for “macOS Installation.” Depending on how disruptive the changes in the Catalina “spring” update will be, I might update for those, but I am not planning to update the book for 10.16 next year.

I might work on some new book on macOS deployment and management in the future. However, I have a few other topics I want to publish before I do that, so that might be a while.

Charles Edge’s and Rich Trouton’s new book should be a great successor to “macOS Installation”:

  • Rich Trouton’s and Charles Edge’s “Apple Device Management: A Unified Theory of Managing Macs, iPads, iPhones, and AppleTVs”: pre-order on Amazon US, UK, DE (Affiliate Links)

“macOS Installation” should remain useful for the life time of Catalina, which, depending on your deployment practices should be another one to four years, more if 10.16 and 10.17 do not drastically change everything again.

Readers who bought the book 16 months ago got several updates for free. I believe free updates are one of the great value propositions of self-published digital books. Most computer related information changes quickly these days and being able to update digital books is a great way to extend their lifetime, usefulness, and value.

My plan to not further update for “macOS Installation” thus lowers its value a bit, and to reflect that I am lowering its price in the store.

That said, I am convinced the book is still very helpful and full of useful information as it is, so if you have not bought the book yet, this is your chance!

Changes in this version (you can also find this in the book in the ‘Version History’ section):

  • added “Moving to zsh” to More Books and updated links to new Apple Books format
  • extended the explanation on FileVault and the Secure Token
  • added Catalina System Volume Layout description
  • added instructions to block the macOS Catalina download
  • added an explanation for the expiring installer certificates from October 2019
  • updated download links for Older macOS Versions
  • added notes to NetBoot-based Installation regarding its further demise and the removal of System Image Utility from Catalina
  • added information on new softwareupdate features in Catalina to macOS Installer Application
  • added a section on new Catalina features
  • added a description of new stub Installer application behavior with startosinstall
  • added link to new SecureToken documentation
  • updated text and tables to reflect the 2019 iMacs
  • clarified reboot behavior of Mojave and High Sierra with Custom Packages
  • added a list of MDM commands that require DEP
  • now using the term ‘conventional’ Macs to refer to non-Secure Boot or pre-T2 Macs
  • many typos, minor changes and clarifications

Notarization for MacAdmins

Apple introduced Notarization in macOS Mojave. Since its introduction Apple has kept increasing the use of notarization checks in macOS. For macOS Catalina, Apple has been very vocal saying that Notarization is a requirement for distribution of Applications outside of the Mac App Store.

This has left many MacAdmins confused and concerned. A large part of the work as a MacAdmin consists of (re-)packaging applications, configuration files and scripts so they can be distributed in an automated fashion through a management system, such as Jamf Pro, Munki, Fleetsmith, etc.

Do MacAdmins need to notarize all the package installers they create as well? Do MacAdmin need to obtain an Apple Developer ID? How should MacAdmins deal with notarized and non-notarized applications and installers from third parties?

This post is an attempt to clarify these topics. It’s complicated and long, bear with me…

Signed Applications

Apple’s operating systems use cryptographic signatures to verify the integrity and source of applications, plug-ins, extensions, and other binaries.

When an application, plug-in, extension, or other binary (from now on: “software”) is signed with a valid Apple Developer certificate, macOS (or iOS, tvOS, and watchOS) can verify that the software has not been changed or otherwise tampered with since it was signed. The signature can verify the source of the signature, i.e the individual Developer account or Developer team whose Developer identity was used to sign the software.

If the contents of the software were changed for some reason, the verification fails. The software can be change by accident or with malicious intent, for example to inject malicious code into an otherwise beneficial piece of software.

Since Apple issues the Developer IDs, they also have the option of revoking and blacklisting certificates. This usually happens when a Developer ID has been abused to distribute malware. The Malware Removal Tool or MRT is the part of the system that will identify and block or remove blacklisted software.

App Store Distribution

Applications distributed through Apple’s App Stores have to be signed with a valid Developer ID. A developer needs to have valid subscription ($99 per year for individuals and $299 for organizations) to obtain a certificate from Apple.

When a developer submits software to an App Store on any Apple system, the software will be reviewed by Apple to confirm whether it meets the various guidelines and rules. This includes a scan for malware.

App Store applications also have to be sandboxed, which means they can only access their own data (inside the “sandbox”) and not affect other applications, services, or files without certain “entitlements” and, in many cases, user approval.

App Store rules and regulations and sandbox limitations preclude many types of applications and utilities. On iOS, tvOS and watchOS, they are the only way for developers to distribute software to end users.

Apple provides a method for Enterprises and Organizations to distribute internal software directly without going through the App Store and App Store review. This should be limited to distribution to employees and members of the organization (such as students of a university or school). This method has infamously been abused by Facebook and other major companies which lead to Apple temporarily revoking their certificates. (We will not discuss Enterprise App Distribution in this post.)

There is also much criticism about how realistic Apple’s rules and guidelines are, how arbitrary the review process is, and whether the sandbox restrictions are useful or unnecessarily draconic. A lot of this criticism is valid, but I will ignore this topic in this post for the sake of simplicity and brevity.

Software downloaded from the App Store is automatically trusted by the system, since it underwent the review and its integrity and source can be verified using the signature. In the rare case that some malicious software was missed but the review process, Apple can revoke the Developer certificate or blacklist the software with the Malware Removal Tool.

Distribution outside of the Mac App Store: Gatekeeper and Quarantine

As mentioned before, iOS, tvOS, and watchOS applications have to distributed to end users through the App Store, be signed with a valid Developer ID and under go the review.

Because the Mac existed a long time before the Mac App Store, software vendors have many ways of distributing software. Originally software was sold and delivered on physical media (Floppy Disks, CDs, and DVDs), but we with the rise of the internet, users could simply download software from the developer’s or vendor’s website or other, sometimes dubious, sources.

Apple has (so far) accepted and acknowledged that these alternative means of software distribution and installation are necessary on macOS. To provide an additional layer of security for the end user in this use case, Apple introduced Gatekeeper in OS X 10.8 Mountain Lion.

When a user downloads a software installer or archive from the internet it is ‘quarantined.’ When the user attempts to install or launch the software for the first time, Gatekeeper will evaluate the software. There are many steps in this evaluation, and Howard Oakley explains the process in much detail in this post.

You can see the quarantine flag with the xattr command:

% xattr ~/Downloads/somefile.pkg
com.apple.macl
com.apple.metadata:kMDItemWhereFrom
com.apple.quarantine

You can delete the quarantine flag with xattr -d com.apple.quarantine path/to/file. Usually, there is no real need to.

The first step of the evaluation is verifying the software’s signature, Developer ID, integrity. When encountering an unsigned piece of software the user will be presented with a warning dialog.

Users with administrator privileges can bypass Gatekeeper by choosing “Open” from the context menu instead of double-clicking to open. Gatekeeper can be completely disabled with the spctl command, though this is not recommended.

The Developer signature provides a way to verify the source and integrity of a piece of software, but since the distribution happens outside of Apple’s control, a malicious developer could still put any form of malicious code in the signed software to keep Gatekeeper happy. As long as the malware avoids widespread detection it will look good to Gatekeeper and the end user. Even when the malware is detected by Apple and the Developer ID is revoked, it is not hard for a malicious developer to obtain or steal a new Developer ID and start over.

Enter Notarization

Apple needed another layer of security which could scan software for known malware and enforce a certain set of security rules on third party software, even when it is distributed outside of the Mac App Store.

Note: I find the effort Apple is putting in to Gatekeeper and Notarization quite encouraging. If Apple wanted to restrict macOS to “App Store only” distribution in the near future, this effort would not be necessary. This shows that Apple still acknowledges the important role that independent software distribution has for macOS.

To notarize software, a developer has to sign it with their Developer ID, and upload it to Apple using Xcode or the altool command. Then Apple notarization workflow will verify that the software fulfills certain code requirements and scans for certain malware. The exact details of what is considered malware are unknown. However, we do know that the process is fully automated and, unlike the App Store approval process, does not involve human reviewers.

If the software has passed the notarization process the result will be stored on Apple’s servers. When Gatekeeper on any Mac verifies the software it can confirm the notarization status from Apple’s servers. Alternatively, a developer can ‘staple’ a ‘ticket’ to the software, which allows Gatekeeper to confirm the notarization status without needing to connect to Apple.

When Gatekeeper encounters a quarantined software that is notarized, it will show the familiar Gatekeeper dialog with an additional note that:

“Apple checked [the software] for malicious software and none was detected.”

Since 10.14.5, When Gatekeeper encounters signed software that is not notarized it will show the standard dialog but with an additional yellow warning sign.

As with the previous Gatekeeper checks for a valid signature an administrator user can override the check by choosing ‘Open’ from the context menu instead of double-clicking to open.

In Mojave notarization was enforced in Gatekeeper checks for kernel extensions and in 10.14.5 for software with new Developer IDs, which where created after June 2019.

Starting with Catalina, all software needs to be notarized to pass Gatekeeper when the first launch or installation is initiated by a user.

However, the warning can still be overridden by an administrator user using the context menu.

What can be Notarized

As of now, the following pieces of software can be notarized:

  • Application bundles
  • Kernel Extensions
  • Installer Packages (pkg), Disk images (dmg) and zip archives

When you are building other types of software, such as command line tools, you can (and should) place them in one of the archive formats. The preferred choice for MacAdmins should be an installer package (pkg) since it will also place the binary in the correct location in the file system with the correct access privileges.

What cannot be Notarized

You should not notarize a binary or application that you did not sign! The Developer ID used to sign a binary (application or command line tool) should be the same as the Developer ID used to submit the software for notarization.

Apple has loosened the requirements for notarization until Jan 2020 to give developers some extra time to adapt. Once the requirements return to the full restrictions an attempt to notarize third party software with a different Developer ID will fail. (Existing notarizations will remain valid after that date.)

Installer command

When you install software using the installer command from the Terminal or a script, it will bypass quarantine and the Gatekeeper check.

This is also true when you install software using a management system such as Jamf Pro, Munki, Fleetsmith, etc.

Software you re-package as a MacAdmin for distribution through management systems does not need to be notarized.

Given this and the limitations on notarizing third party software above, you should very rarely need to notarize as a MacAdmin.

Example: Re-packaging third party software from dmg

A lot of applications for macOS are distributed as disk images. The normal end user workflow would be to mount the dmg after downloading, and then copying the application from the dmg to the /Applications folder.

There are two steps where Gatekeeper might trigger: when you mount the disk image and when you launch the application after copying for the first time. To pass both these checks, a developer should prudently notarize both the disk image and the application. Google Chrome for example does exactly that, avoiding the Gatekeeper warning.

We can verify this with the spctl command:

% spctl -a -vv -t install ~/Downloads/googlechrome.dmg
/Users/armin/Downloads/googlechrome.dmg: accepted
source=Notarized Developer ID
origin=Developer ID Application: Google, Inc. (EQHXZ8M8AV)

% spctl -a -vv -t execute "/Volumes/Google Chrome/Google Chrome.app"
/Volumes/Google Chrome/Google Chrome.app: accepted
source=Notarized Developer ID
origin=Developer ID Application: Google, Inc. (EQHXZ8M8AV)

Unfortunately, some management systems don’t understand “Apps in disk images” as a distribution method. For these systems MacAdmins need to re-package the application into a pkg. You can do that quickly with pkgbuild:

% pkgbuild --component /Volumes/Google\ Chrome/Google\ Chrome.app --install-location /Applications/ GoogleChrome.pkg
pkgbuild: Adding component at /Volumes/Google Chrome/Google Chrome.app
pkgbuild: Wrote package to GoogleChrome.pkg

or use quickpkg.

This new installer package will be neither signed nor notarized:

% spctl -a -vv -t install GoogleChrome.pkg                          
GoogleChrome.pkg: rejected
source=no usable signature

When you send this installer package to another Mac with AirDrop, the receiving system will attach the quarantine flag. And when you double click it, you will get the Gatekeeper warning. However, when you can still install it using the installer command in Terminal, which bypasses the Gatekeeper system, just as your management system will:

% installer -pkg ~/Downloads/GoogleChrome.pkg -tgt /

Alternatively, you can choose “Open” from the context menu in Finder to bypass Gatekeeper. However, this is not something you want to teach your end users to do regularly.

Firefox can be downloaded as a disk image as well as a installer package. While the application inside both is notarized, neither the disk image nor the installer package are. The disk image mounts with no issues, but when you try to open the installer pkg by double-clicking you will get the expected notarization warning. Nevertheless, the pkg will work fine after importing to your management system.

Edge cases

There are some cases where notarization would be useful for MacAdmins but might not even be possible. I met a MacAdmin working at a university at MacSysAdmin last week. They need to re-package a VPN client with customized configuration files to be installed on student-owned machines.

There is really no solution without the students running into the notarization warning. Teaching the users how to bypass Gatekeeper is not a good solution.

In these cases you have to work with the software vendor and Apple to find a workable solution.

Summary

Notarization is a new security layer introduced by Apple in Mojave. The restrictions imposed on non-notarized software increase in Catalina.

When an Application is installed or launched for the first time by the user (by double-clicking) Gatekeeper will verify the signature and notarization status and warn the user if any are missing.

Developers should sign and notarize their applications and tools.

Mac Administrators should not notarize applications and tools from third parties.

Applications and packages installed through management systems bypass Gatekeeper and do not need to be notarized.

Conclusion

Apple is loudly messaging that notarization is absolutely required for applications in Catalina. While this message makes sense for the developers building the software, it does not apply to administrator who re-package third party software for distribution through management systems.

MacAdmins should join Apple in demanding signed and notarized binaries and installer packages from developers.

However, MacAdmins can also continue their current workflows for re-packaging and distribution.

Links

Imaging is still Dead

At WWDC last week, there was a very interesting session on “Apple File Systems” (APFS). It covered the new split system layout in macOS Catalina with a read-only system volume, volume replication with APFS, and how external USB drives and SMB works on iPadOS.

The entire session is very interesting and well worth watching. Go ahead, I’ll wait…

Around the 13 minute mark, during the ‘Volume Replication’ segment, the engineer on stage talks about using asr (Apple Software Restore) tool to ‘replicate’ a system volume to several computers at once and gives the example of a computer lab. He then proceeds to explain the new options in asr regarding APFS volumes and snapshots.

Slide from WWDC 2019, Session 710

The new features are hugely interesting and I think they will be very useful for backup solutions. There will probably be some applications for MacAdmins, but I disagree with the engineer on stage and some MacAdmins on Twitter and Slack:

Catalina will not bring a revival of imaging.

Note: I wrote a book on this: “macOS Installation for Apple Administrators

What killed imaging?

Back in the Sierra days, there was this idea that the introduction of APFS would ‘kill’ imaging. The asr tool relied on many HFS+ behaviors and it was questionable that Apple could or would maintain that for APFS. But while there were some changes to asr in the High Sierra and Mojave upgrades, it still worked.

What killed imaging as a process for MacAdmins was the T2 system controller, first introduced with the iMac Pro. There are two main aspects:

  • NetBoot and external boot are defunct
  • Firmware needs to be updated with the system

Netboot and external boot are defunct

To re-image or re-install a system, you have to boot it off a different system volume (NetBoot, Recovery, external drive). Alternatively, you can put the system into target disk mode and image or install the system directly on the internal drive.

On Macs with the T2 system controller, NetBoot is explicitly defunct. External boot is disabled by default. It can be re-enabled, but the process is convuluted, requires at least one full setup process, and cannot be automated.

This leaves Recovery as the system to use to replace the system volume and, not surprisingly, there are a few tools that have focussed on using Recovery in the new T2 Mac world:

Firmware needs to be updated with the system

You could also put the target Mac in target disk mode and image its system. This will work, as long as the system on the image is the same version as the system that was installed before. We have been warned about this in the infamous HT208020 support article:

Apple doesn’t recommend or support monolithic system imaging as an installation method. The system image might not include model-specific information such as firmware updates.

Modern Macs don’t just require a few files on disk to make a bootable system. Inside your Mac are several subsystems that require their own systems (i.e. firmware) to run. Most prominent are the T1 or T2 system controllers which are actually independent custom ARM-based processers running a system called ‘iBridge’ which is an iOS derivate.

If you just exchange the ‘normal’ system files on the hard drive over TDM, without also updating the various firmwares in the system, you may get your Mac into state where it cannot boot.

This was most obvious with the macOS High Sierra upgrade. After re-imaging a 10.12 Sierra Mac to High Sierra running on APFS, would lead to a Mac that could not read the new system volume. The firmware update that came with High Sierra is needed, so the firmware can mount, read and start the APFS system volume.

How can I update or upgrade?

For security, only Apple’s ‘Install macOS’ application and the intermediate software and security update packages have the necessary entitlements to change the built-in firmware(s).

Firmware updates can be in system updates (minor version updates, i.e. 10.14.4 to 10.14.5), security updates, and major system upgrades (i.e. 10.13 to 10.15).

There are three options to apply a system update (e.g. from 10.14.4 to 10.14.5) or security update:

  • ‘Install macOS *’ application, either manually or with the startosinstall tool
  • Software Update, either manually or through the command line tool
  • system or security update pkg installer downloaded from support.apple.com

When you want to upgrade a Mac through a major version change (e.g. 10.13 to 10.14 or 10.15), there is only one option:

  • ‘Install macOS *’ application, either manually or with the startosinstall tool

The one remaining use case for imaging

Given the above limitations, there is one use case left for imaging. When you have full control over the macOS version installed on the Mac and its firmware and the image matches that version, then you can image.

However, since NetBoot and external boot are defunct, you will have to image either over target disk mode (fast, but only a few Macs at a time) or using the Recovery (hard to automate, comparatively slow).

The remaining strength of the imaging workflow is the raw speed. Some application suites measure several Gigabytes, if not tens of Gigabytes. With installation workflows, these have to be downloaded, decompressed (pkg installers are compressed archives) and copied to the system drive, a process that takes a lot of time. With imaging, these can be layed down with fast block copies.

For example, the re-installation of a MacBook Pro I tested recently took about 25 minutes. This time includes downloading the 6GB ‘Install macOS’ application and the entire re-installation process. (I could probably have sped this up with a caching server or by pre-installing the full ‘Install macOS’ applications.) If I could have used imaging this would take 2–3 minutes.

If you are in a situation where you have to restore Macs to a pre-defined state frequently and quickly, then imaging might still be a useful workflow. One use case may be MacBooks that get frequently handed out as loan units, where the users get administrative privileges, so they can install extra software and configure the loan units.

You will have to invest extra effort during updates or upgrades to apply them first on the devices, to ensure the firmware gets updated, and then to update the image, as well. In some use cases this extra effort can be worthwhile.

MDM (and DEP) is required

With modern macOS there are other considerations for deployment that make classic imaging workflows less practical. Before macOS 10.13 High Sierra, MacAdmins could manage their Mac fleet without an MDM server. In High Sierra 10.13.4 Apple added two things to the MDM protocol:

  • ‘user-approved’ MDM
  • Kernel extension white listing via configuration profile

The second feature (white listing Kernel extensions) requires the first (user-approved MDM). You cannot manage Kernel Extensions or Privacy Preferences Control settings in Mojave, with out a user-approved MDM. In mosts organizations, these are not limitations you can work around. An MDM is now a requirement to manage Macs in an organization.

From what we can glean from the WWDC sessions, the (UA)MDM controls will be increased even further with Catalina. It will be driven even further: DEP or ‘Automated Device Enrollment’ with Apple Business Manager or Apple School Manager will be required for some new management features, such as ‘bootstrap tokens’ for FileVault.

Each Mac client needs to be enrolled in the MDM individually. The MDM enrollment cannot be part of an image. The easiest way to get a Mac enrolled is with Automated Device Enrollment (formerly known as DEP), which happens at first boot after installation.

Third party software

It is not just the macOS system that needs to individually enroll with the MDM server. Many third party solutions now also require subscriptions or licenses to be activated on each device individually. All these additional configurations that need to happen after installation or imaging, decrease the usefulness of including all software and configuration in an image.

Patching and software updates

Most imaging deployments, used a workflow where the image was kept ‘static’ or ‘frozen’ for longer periods of time, usually six or twelve months. This will minimize the effort to update the image, system and software.

However, modern operating systems and third party software have update frequencies of 4–10 weeks. Modern security requirements will require these updates to be applied in a timely matter. Critical security problems can strike at any time, requiring fast updates from the vendors and the Mac Admins.

As with the MDM above, having a system in place that allows the MacAdmin to easily and quickly deploy and, when necessary, enforce an update or patch to the entire fleet of devices is an important requirement.

Software and patch management of non-App Store applications is not part of the MDM protocol. Nevertheless, many MDM solutions also include additional functionality for software management, with varying degree of usefulness.

Some MacAdmins prefer to combine their MDM solution with the open source solution Munki instead. Munki is considered to be the best software management solution for macOS, but does not include MDM functionality itself.

Whichever software management solution you use, once you have that in place, it will be easier to manage (i.e. install and enforce) software through the management system, than to keep an image up-to-date and re-applying it.

You will end up with a ‘thin’ base image and everything else deployed and managed by the management system. At that point you might as well switch to an installation based workflow.

But, the engineer on stage said…

Here are all the limitations on imaging, summarized:

  • NetBoot and external boot are defunct
  • system firmware needs to be updated with the system
  • MDM and DEP are required
  • frequent security updates and patches require continuous software management

None of these limitations are addressed by the changes to the asr tool in Catalina. Changes in other areas of the system in Catalina will actually re-inforce some of these limitations.

Imaging is still dead.

But why even have asr, then?

The asr tool exists because Apple needs a tool to image the operating system to new Macs in the factory. Obviously, Apple has absolute control over the versions of macOS and firmwares deployed to the systems, so they ensure they all match. Speed is a priority, so Apple needs and maintains asr.

Other uses of asr, including the use as an imaging tool for administrators have always been secondary.

As mentioned earlier, when your environment has similar requirements (fast re-deployment) and can provide tight control over the macOS and firmware versions, then imaging might still be a useful workflow for you.

You can already do this with High Sierra or Mojave. You do not have to wait for the new Catalina features for this.

In general, a simpler (albeit slower) installation-based workflow is less complex to deploy and maintain. (Imaging might seem less complex, because it is more familiar.)

So, the new features in the presentation are pointless?

The other use case for asr in the presentation, backups, are very exciting. They will allow the system to take a snapshot and then copy the data of the snapshot to a backup while the system keeps running and changing files. You may also be able to restore a system from a snapshot stored elsewhere.

The split of system volume and user data volume in Catalina is also very intriguing for Mac Admins. This may of course, break some third party software. (Start testing now.) But it may also open up new options for management. One of these (user enrollment) is introduced in the “Managing Apple Devices” WWDC video.

One possible workflow could be to snapshot and/or image the data volume and leave the system volume intact (you have to, it is read-only and SIP protected). It is still questionable how well this might work, since the firmlink connections between the system and the data volume might not survive the replacement of their targets. You can start testing this now, but keep in mind that the details of the new file system layout will still change during the beta phase.

Summary

  • The changes introduced to the file system in macOS Catalina at WWDC are major and will enable new workflows for MacAdmins.
  • Start testing Catalina now.
  • The limitations that ‘killed’ imaging, still apply or might be re-inforced. Imaging is still dead