Packages are structured files, denoted by a .pkg or .mpkg file extension, used to carry installable software. They can contain app and software components, scripts, receipts, and other metadata necessary to install, update, or remove an application. But there are several different types of packages that you might run across.
Varieties of PKGs
Packages can be flat or not. Flat PKGs are by far the most common type. They contain just a single, compressed file; its full contents are revealed when that single file is decompressed. They are compressed in the Xar format, which (among other things) means they can be signed to verify their provenance.
Typically, flat packages include:
- A payload, which is the main deliverable (more on that in a second),
- A PackageInfo file, which includes information about the package in XML format, and
- a BOM (bill of materials), which lists the files contained in the package.
They may also include special scripts designed to run before or after the payload is installed.
Non-flat packages—more commonly known as bundles—are largely a legacy technology now. They contain the full hierarchies of files, including executable code and its resources (instead of nesting those hierarchies in another PKG, as flat packages do). In older versions of macOS, you could right-click on a bundle package, select Show package contents, and see that entire hierarchy of files; you can’t do that with flat packages. (There are other ways to inspect those, which we’ll explain in a bit.)
You might also have seen files with the .mpkg extension. That’s also an older format, too, no longer very common but still worth knowing about. MPKGs are like packages of packages. An MPKG can contain several PKGs, as well as files and folders, in a single compressed archive.
Distribution PKGs are yet another variant. They include ancillary resources to enhance or customize the software installation process—such as multiple PKGs or graphics resources for customizing the install screen—making them well-suited for distributing software that the end-user will install themselves manually.
What Are PKGs Good For?
PKGs are most commonly used to deliver and install applications to Mac endpoints. When a user opens a PKG, it launches the installer app built into macOS, which then manages the process of decompressing the PKG and distributing its contents where they need to go.
Typically, PKGs being used for software installation themselves contain another PKG; those nested PKGs—the payloads mentioned above—are archives containing the entire hierarchy of files to be installed, including the application executable and its ancillary resources. Those resources can, in turn, include receipts, which macOS uses to keep track of the apps that have been installed.
But packages don’t have to include such payloads. They can, instead, just include scripts, which run when the package is opened (more on that in a moment). Because they don’t contain receipts, such packages can be reopened, and their content rerun, multiple times. As such, they were once considered a good way to deliver and run scripts that needed to run repeatedly. With the advent of MDM, that workflow is less necessary than it might have been a few years ago.
Software updates, patches, and plugins can also be distributed as packages; doing so can help ensure that only the necessary components are replaced or updated, preserving user data and configurations. You might also deliver configuration files in PKGs—but, again, there are numerous more modern alternatives (such as MDM) for that to handle most use cases.
Alternatives for Delivering Applications
There are plenty of alternatives to PKGs for delivering and installing applications, too.
Users don’t need to download PKGs for apps from the App Store, for example; those are delivered and installed directly. Automated app and patch management systems—such as Kandji’s Auto Apps—also make custom PKGs unnecessary; such systems handle the packaging, delivery, and installation for you.
But for apps that aren’t in the App Store and aren’t available through such software management tools, PKGs can be valuable delivery systems. They still aren’t the only such alternatives, however.
Applications can also be delivered in the form of DMGs or ZIP archives. We’re all familiar with opening a downloaded DMG to see a Finder window displaying an icon for the app and another for the Applications folder and encouraging us to drag the former onto the latter to install the app.
The only problem with those methods is that they’re not as good as PKGs for installing hierarchies of files. That means they’re fine for simpler apps, but not for apps with more complex installation procedures, which might need to put the main application executable in /Applications, say, but then other files in ~/Library and elsewhere. Apps with such installation requirements are the primary candidates for packaging.
(Note that there’s still yet another workaround for such complex installations: You could use a tool like Kandji’s Custom App Library Item to deliver a DMG or ZIP file containing all the files a given app requires, then use pre- and post-install scripts to move those files where they need to go.)
How to Build a PKG
Let’s assume you’ve determined that a PKG is the best way to deliver an app. How do you package that app and its resource files? There are numerous tools built to help you.
The most popular one is likely Packages. It presents the folder hierarchy of a target system. You then drag the resource files you wish to install into the folders where you wish them to reside; you can add new folders if you wish. When the resulting package is opened on the endpoint, the files are placed in those folders there. You can also set the appropriate permissions for each file, as well as add pre- or post-install scripts and other resource files (including licensing).
One issue to resolve before you start to build: Do you want to sign the packages you’re creating? Doing so will ensure that the PKG can be opened on the endpoint without Gatekeeper prompting the user; in some cases, it may also determine whether or not your MDM solution can deliver the package.
If you want to sign the packages you build in Packages, you can provide it with your developer ID certificate; the utility will then do the signing for you. Alternatively, you can also go into your own Keychain and create a self-signed cert there, then use that to sign PKGs. You will also need to distribute that certificate from your MDM solution, so it's trusted by the endpoints where said package is to be delivered.
If you prefer a command-line alternative to something like Packages, pkgbuild
and munki-pkg are popular choices. And if you want a tool for inspecting flat packages, Suspicious Package and Pacifist are the most common; while pkgutil
can expand PKGs via the command line. These tools can show you the contents of a package, where those items will be placed on the endpoint, the scripts that will run when the package is installed, whether the package is signed or not, and if that signature is trusted.
How to Distribute a PKG
When it comes to deploying PKGs to endpoints, different MDM solutions have different requirements. Some require that the package be signed. Some might do that signing for you. Some require a manifest file. Look up PKG in your MDM solution’s support documentation and find out what it needs and what is supported.
The alternative to deploying a PKG via MDM is to host it on a website, and have end users download and install it from there. Or, if your MDM solution installs a Self Service tool on endpoints (such as that provided by the Kandji Agent), you can have users download and install it from there.
The above is intended only as an overview of what packages are and what they can do. If you want to really dive more deeply into the topic, Armin Briegel—particularly his book, Packaging for Apple Administrators, as well as his website Scripting OS X—is an excellent resource. For fuller details on the flat packages, see the Flat Package Format - The missing documentation on the Suspicious Package website.
About Kandji
Kandji is the Apple device management and security platform that empowers secure and productive global work. With Kandji, Apple devices transform themselves into enterprise-ready endpoints, with all the right apps, settings, and security systems in place. Through advanced automation and thoughtful experiences, we’re bringing much-needed harmony to the way IT, InfoSec, and Apple device users work today and tomorrow.