With the Shakespearian tragedy that is The Death of Imaging finally coming to an end with across-the-board T2 chips, there is a growing need for alternate workflows for bootstrapping machines. Apple’s answer for this problem is DEP and MDM. While this workflow isn’t ideal for every situation, it is possible for administrators to leverage these tools to provide a smooth and effective enrollment experience, whether using Internet Recovery or deploying brand new Macs.
Apple provides MDMs with the ability to install signed, custom pkg files on macOS with the InstallApplication tool (since replaced by the more secure InstallEnterpriseApplication in 10.13.6). While not a particularly robust deployment tool in and of itself, it is a useful way to bootstrap a custom agent such as Munki, Puppet, or Chef onto Macs for more sophisticated management.
However, this process can be brittle, even when bug-free, and control is limited. For administrators looking to provide smooth deployment or out-of-box experience for new or re-deployed machines, a greater degree of control is necessary. Perhaps the best solution for this is the open-source tool InstallApplications.
InstallApplications – What, Who, & Why
InstallApplications (note the ‘s’) is a tool for providing a custom MDM enrollment and bootstrapping experience for Macs, particularly for those enrolled in DEP. IAs is written by Erik Gomez, a Mac and Windows Client Platform Engineer at Pinterest and author and contributor for a number of open-source MacAdmin tools. You can read more about IAs, the reasoning behind it, and how it came about, as well as Mac Administration in general, at his blog, One More Admin.
The other “who” of IAs is any Mac administrator who uses DEP and an MDM that supports custom InstallApplication/InstallEnterpriseApplication usage. As of this writing that includes:
(Some other popular MDMs such as Jamf Pro use InstallApplication to deliver their own agent, and don’t really offer the ability to provide custom DEP enrollment processes.)
InstallApplications is built to overcome a number of the limitations inherent in Apple’s MDM toolchain. Erik lays out several of these on his blog, but some of the highlights include:
- While it appears to have been fixed, a long-standing bug in InstallApplication caused it to fail to install more than one package, even if multiple install commands were sent by the MDM.
- InstallApplication requires packages be signed, distribution pkg files. So if you are combining multiple sub-packages, you must rebuild and redeploy the entire package though your MDM each time a component is updated.
- Sub-packages that make up the monolithic distribution pkg must themselves not be distribution pkgs. This means that most tools will require re-packaging before they can be deployed.
- All component packages are installed at the same time. This means that all pre-install scripts from all packages run first, then all files are deployed from all packages, followed finally by all post-install scripts from all packages. This can lead to race conditions or other unintended consequences.
- The ability to control and customize user experience on the machine is severely limited.
How It All Works
InstallApplications was designed as a sort of “Munki-lite” tool and works in a similar, albeit much simplified, manner: the client machine reaches out to a URL, reads a manifest telling it what to do, and then pulls down the appropriate pkgs and scripts from a web server. After the IAs pkg is installed by the MDM, the main script downloads a JSON file with the details and location of additional scripts and packages to download and run/install. This process minimizes the changes required to update the various components to be downloaded and run. As long as the URL of the
bootstrap.json file is consistent, an administrator need only to update that file and the files it references, and not the IAs pkg itself. This means that iterations and changes can be made quickly and easily on a web server without the need to repackage, resign, and reupload anything to the MDM.
The InstallApplications Package
IAs consists primarily of three basic components that are packaged together into a signed distribution pkg and pushed out by an MDM via InstallApplication:
- A Python script (
installapplications.py) that accepts a number of arguments from the LaunchDaemon, reads the
bootstrap.jsonfile from the server, downloads pkgs and scripts, and runs them in the specified order.
- A LaunchDaemon for running
installapplications.pyand installing downloaded packages and rootscripts. This will require some customization before the pkg is built—at minimum, you are required to include the URL of a
- A LaunchAgent that can run scripts as a logged-in user rather than root.
Once the pkg is built and signed with an Apple Developer account certificate, it can be uploaded to an MDM and then pushed out to client Macs.
The other component of an InstallApplications setup is a simple web server. This can be anything you’re comfortable using, as long as it is freely accessible by clients at a consistent URL and uses HTTPS.
The most important item on the server is the
bootstrap.json file. Much like a munki manifest, this file contains information about the packages and scripts to be downloaded and installed/run, including their URLs and SHA-256 hashes. Changing what IAs will install/run and in what order is done by adding or updating the items hosted on the server and updating the bootstrap file. The IAs repo includes a script, generatejson.py, to help automate that last step. No repackaging or signing of any of the sub-packages is necessary.
InstallApplications runs in three stages, offering a greater degree of flexibility and control in over the enrollment process than the default Apple tool. During DEP, IAs is installed by the MDM during SetupAssistant, before a user has logged in. However, certain actions—such as running user-level scripts or tools that notify users of the setup process such as Yo or DEPNotify—can be postponed until a user logs in. Designating which component is included in what stage is done in the boostrap file.
This stage is designed to run only a single script as root. This script should check if certain conditions are met, such as if your management tools (Munki, Chef, Puppet, etc.) are installed. This is useful in that it allows pushing InstallApplications to previously-deployed machines without interruption if they are already managed.
If the preflight script exits 0, InstallApplications will cleanup and remove itself, bypassing the setupassistant and userland stages. If the preflight script exits 1 or higher, InstallApplications will continue with the bootstrap process.
The setupassistant stage is meant for packages and root scripts that should be prioritized for download/installation and can be installed during SetupAssistant, where no user session is present. This can pre-load applications or processes that will be used to inform users about the enrollment process.
The userland stage is for packages and scripts run either as root or a logged-in user that should be installed/run in the user’s context. This could be a tool such as DEPNotify that informs the user that a DEP workflow is being used. This stage will wait for a user session before installing.
InstallApplications is a useful tool for overcoming the limitations of Apple’s MDM tools and providing a custom DEP enrollment experience. While not itself an especially complex tool, it can take a bit of time to grasp all the moving parts. Once this is done, IAs offers a great deal of flexibility and control for administrators, whether re-deploying machines with Internet Recovery or giving users an smooth, out-of-box experience when setting up a new Mac. Moreover, updates to the process can be made without re-packaging/re-signing components or re-uploading pkg files to an MDM, and can even be managed with a CI/CD pipeline. In the words of it’s author, IAs “is the orchestrator for your DEP enrollment. It’s designed to install all of the basic building blocks needed for enrollment and solves every common issue related to DEP.”
This post explained the what, who, and why InstallApplications was written and how its various components work together. In Part 2, I will go how to set up and use IAs with SimpleMDM to provide a custom DEP enrollment process.