No more sudo with softwareupdate or unattended updates on macOS running on Apple Silicon

Today, Apple announced new Macs running on Apple Silicon running on macOS Big Sur. Let’s talk about a change that should concern IT admins. On Apple Silicon Macs, you get the following message when you try to run:

sudo softwareupdate -i

Using softwareupdate to install updates on Apple Silicon should not be run with sudo

And immediately after, you get prompted to authenticate with a GUI prompt.

Two things to note here:

  1. Almost all software management tools for macOS are built to run as root and run as sudo.
  2. Never before has an update required a user to confirm an update by authenticating their credentials. This makes unattended updates impossible.

What are the methods to get users to update their operating system?

There are a few different methods that have been used by admins to get users to update their Macs.

  • Schedule an OS update using the MDM command. Apple approved.
    • This is unreliable. It does not work consistently on either iOS or tvOS, let alone with macOS. There is also not a very good user experience attached. If the command goes through successfully, the user simply sees their computer restart immediately.
  • Manage automatic update settings though a configuration profile. Apple approved.
    • This is not reliable either. There are specific requirements that need to be met in order for updates to automatically install that Apple has not documented. Running applications can also easily prevent an OS update from taking place. This also seems to take place in the middle of the night when laptops may not be powered on.
  • Force updates using the command line tool: softwareupdate.
    • Up until Macs with T2 chips were introduced, this was the most reliable method. With T2 Macs, this has been a less reliable particularly when bridgeOS updates are part of the equation.
  • Constantly notify the user that they need to update their OS using custom tooling.
    • Perhaps the most reliable method today since this is the method that Apple has designed their software update process around for consumers. This has the drawback of annoying your end users. This also partially relies on being able to read what updates may be available through softwareupdate.
  • Using Zero Trust security policies, block end users from accessing company resources until they’ve updated their OS.
    • This works great if your environment has been setup with all resources being gated behind networked resources and your company has been able to implement zero trust policies. However if there are resources that are not gated behind zero trust policy, you may end up with end users that never update.
  • Deploy the latest full OS installer every time a new update is released.
    • To be fair, I don’t know of anyone using this method. But it is an option nonetheless. Updates will likely take 30-35 minutes if you go this route. Big Sur is supposed to improve and speed up the update process. Deploying the full OS installer would likely undo any of these update improvements. This also would mean deploying ~12GB installers every time there is an update as opposed to the ~5GB downloads you’d be dealing with (combo updates have largely been hovering around this size). Another thing to consider is that it may be possible that a full installer is skipped on certain updates. And there are other side effects of performing a full install vs an update.

Each method has their pros and cons. They all work great in environments where a user is assigned to them. However, they don’t really address the methods in which 1) there is no human available to install an update or 2) where the end user simply is not complying with the notifications or requirements.

Apple has not provided better management options for macOS updates. In fact, with each major OS release they’ve gotten rid of the options that have been available to us. You can no longer run your own Apple Software Update Server. You can no longer ignore specific updates. The command line tool softwareupdate has become less reliable depending on the conditions in which you tried to run it on Macs with T2 chips. Now it seems

I (and I’m hoping other IT admins, too) have requested better options and improvements to the current management tooling, but Apple has yet to implement any of them. As of today, you have the two options listed above which involve sending MDM commands or a configuration profile. Additionally, you have the ability to delay updates up to 90 days where major and minor OS updates are treated the same. But that doesn’t achieve the purpose of getting devices on to the latest OS version.

In our environment, this would be quite disastrous as we have computers that are online, but unattended. There’s no reliable automated method to update Macs to a specific OS version with a good user experience.

The request to Apple: better update enforcement tooling

From an IT admin perspective, I do not believe what is being asked would conflict with Apple’s goal of having users running a secure operating system.

I am (and hopefully other admins are too) just asking for a method that allows us to force a device to be updated by a set date using a configuration profile. We cannot rely on MDM commands that simply may or may not reach a device. This workflow should also account for situations where a user may be turning on a computer for the first time after the deadline has passed, they should have X amount of reminders before the update is forced at this point.

The UX around this request should be handled by Apple (a company that prides itself on its UX) so that IT admins don’t have to deal with custom tooling. This would result in the user getting reminded regularly and then forced to upgrade if the deadline has passed. I believe the above request would work well for other Apple platforms like iOS and tvOS as well.

Final Thoughts

This is not the first time I’ve written about managing software updates on macOS. I cannot help but wonder how a company like Apple can promote and put so much focus on the security of their products and yet not make proper management tooling to keep those same products up-to-date when used in a business environment? Microsoft has figured out how to manage OS updates on Windows and Google has figured it out on ChromeOS so why can’t Apple do the same for its various platforms? Why does Apple make it more difficult for companies to keep devices they have purchased/owned up-to-date?

As of right now, I’m not entirely sure how we’ll be able to manage macOS updates going forward on these machines that are unattended. In the grand scheme of things, our organization is probably insignificant to Apple in terms of the amount of money we spend. I’m writing this in hopes that other admins provide feedback to Apple because this makes the macOS platform considerably harder to keep secure (on the latest version) in business environments. Jamf has a good article that discusses the various options for providing Apple with feedback. Please let your fellow admins know and start filing that feedback with Apple.

Waiting for the macOS Big Sur installer to launch

As part of Gatekeeper, macOS runs a code signature validation scan on all apps when they are run the first time. This results in some really large apps taking 2-3 minutes before they can run. Some apps include: Xcode, Matlab, Mathematica, etc.

The macOS installer app for Big Sur suffers from this too and as a result if you try to run “Install macOS Big Sur.app” it will take at least 2 minutes while macOS scans it. If you launch the app installer through the GUI, the app will simply bounce in the dock until the scan completes. If you run the app through the CLI using startosinstall, it will show no activity until the scan completes.

There’s no way to force macOS to scan a particular app for its code signature validation other than actually trying to run it. This would obviously lead to a bad user experience for the end user.

As a workaround, you can trigger the code signing validation by using startosinstall --usage. This will not actually run an OS upgrade and macOS will start to scan “Install macOS Big Sur.app” silently in the background.

I’ve written a simple script that is designed to run immediately after “Install macOS Big Sur.app” has been installed. I’ve designed it for use in Jamf Pro, but you could easily modify it for other uses if you wanted. The idea is to make the user experience better so that when the user launches an OS upgrade whether through a GUI install (as Apple intends) or a CLI install relying on “startosinstall” there’s no a 2-3 minute period of silence. You can run the script immediately after deploying the installer app to the computer.

File feedback with Apple so that they can improve this user experience and macOS installer apps can be scanned immediately after a download has taken place. This would also have benefits to other large apps as well. Jamf has a good article that discusses the various options for providing Apple with feedback.

Additional research

XProtectService and syspolicyd

If you try to see what’s going on in the when you launch the installer macOS app, you will see XProtectService mentioned in the Console logging when dealing with one of these apps and syspolicyd. Some research on syspolicyd that helped a bit in my testing and research: https://knight.sc/reverse%20engineering/2019/02/20/syspolicyd-internals.html

There is a Launch Daemon at /System/Library/LaunchDaemons/com.apple.security.syspolicy.plist which seems to have the frequency at which some syspolicyd actions might be taking place depending on the LaunchEvent. The com.apple.security.syspolicy.find.bundles key seems to be relevant based on the name. That runs weekly (604800 secs). There is a CLI to this: /usr/libexec/syspolicyd but it’s not very clear to me how to interface with this or whether I’m supposed to. I assume that spctl is the tool that’s supposed to interact with syspolicyd.

Investigating options to workaround code signing validation

For the curious, I did try a bunch of things to kick off the code signing validation before I tried to launch the app or to avoid code signing validation altogether.

The following does not work:

# Remove com.apple.quarantine recursively from app bundle
xattr -dr com.apple.quarantine "/Applications/Install macOS Big Sur Beta.app"

# Clear all extended attributes recursively from app bundle
xattr -cr "/Applications/Install macOS Big Sur Beta.app"

# Asses app
spctl -a "/Applications/Install macOS Big Sur Beta.app"

# Stop spotlight from trying to index app
mdutil -i off -a

# Register app with launch services
/Volumes/Macintosh\ HD/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister -R -f "/Applications/Install macOS Big Sur Beta.app"

# Add path to app to Gatekeeper
spctl --add "/Applications/Install macOS Big Sur Beta.app"

# Not sure if using the –path option makes a difference
spctl --add --path "/Applications/Install macOS Big Sur Beta.app"

# Put label on app bundle and then enable label so that Gatekeepr will bypass it
spctl --add --label "Approved" "/Applications/Install macOS Big Sur Beta.app"
spctl --enable --label "Approved"

# Disable Gatekeeper
spctl --master-disable

# Tried to modify the syspolicy database sqlite3 /var/db/SystemPolicyConfiguration/ExecPolicy using:

INSERT INTO policy_scan_cache (volume_uuid,object_id,fs_type_name,bundle_id,cdhash,team_identifier,signing_identifier,policy_match,malware_result,flags,mod_time,timestamp,revocation_check_time)
VALUES ('C202AB2C-4F93-44BE-9F4F-CB5DA760F07E','189698','apfs','com.apple.InstallAssistant.Seed.macOS1016Seed1','45bc1b465728e65fb091f81bcc0ea147370f455f','','com.apple.InstallAssistant.Seed.macOS1016Seed1',11,0,512,1604217029,1604217029,1604217029);Error: attempt to write a readonly database

This failed because its a read-only database naturally.

# Tried to change the date more than 7 days into the future hoping that might trigger the OS to do its scanning:
date -u 1111000020

The following did work:

I did find one way to avoid the code signing validation but it cannot be automated with either CLI tools or through MDM. Go to Sys Pref > Security & Privacy > Privacy tab > Developer Tools > Enable Terminal. Going forward, no security check takes place when I run (from Terminal) the exact binary that’s supposed to get loaded.

With Terminal not enabled in Developer Tools:
/Applications/Install macOS Big Sur Beta.app/Contents/Resources/startosinstall --usage would normally take 120 secs
But with Terminal enabled in Developer Tools, that runs immediately.