What is a package?
If you have been using a Mac, you will have encountered an installation package file or pkg.
Package files are used to install software and configuration files on your Mac.
Package files come in different flavors and formats, but they can be summarized to these relevant components:
- a payload
- installation scripts
A package file may have only a payload, only scripts, or both.
The payload is an archive of all the files that the package will install on the system. The package also contains a “bill of materials” (BOM) which lists where each file should be installed and what the file privileges or mode should be.
Installation scripts can be executed before and after the payload is installed.
Additionally, packages contain some metadata, which provides extra information about the package and its contents. They can also contain images and text files, such as license agreements that can customize the default Installer app interface.
Installer application
The most common way of installing a package file and start its installation process, is to open it with a double-click. This opens the default application for the pkg extension: Installer. The Installer app can be found in /System/Library/CoreServices/
. However, you rarely need to open it directly. It is usually started indirectly by opening a package file.
After launch, the Installer app presents different panels to the user. The exact order and content of the panels depends on what the developer of the package configured. At the very least, it will show:
- a short introduction
- prompt to authenticate for administrative privileges
- a progress bar of the installation
- whether the installation succeeded or failed
A package may also show:
- a custom background image
- a detailed introduction
- a license agreement that needs to be accepted
- alternative installation location
- options to select certain subsets of files and apps (components)
- more custom steps implemented by the developer
Installer app can also list the contents of a package file without installing it first. You can choose ‘Show Files…’ (⌘I) from the ‘File’ menu to get a list of files in the payload. This list can be very extensive and there is a search field to filter the list.
If you want to see more than just the progress bar during the installation, you can select “Installer Log” from the “Window” menu (⌘L) and then increase the output to “Show all Errors and Logs” (⌘3).
You can also review the installation log afterwards, by opening the Console application from Utilities and choosing “install.log” under “Log Reports.” You can also look at /var/log/install.log
directly.
This log is notoriously verbose. There will be many entries for each installation and some related system services like software update will log here, too.
Security
Packages can place files and executables in privileged locations in the file system. When you open a package file with the installer application, it will usually prompt for administrator privileges.
In the early days of Mac OS X, package installers had no limitations at all. However, these days, digital security and privacy are important features and criteria for platforms and Apple has implemented several features in macOS which set strong limits on what third-party package installers can do.
Most importantly, System Integrity Protection (SIP, introduced in OS X Yosemite 10.11) and the Signed System Volume (introduced in macOS Catalina 10.15) prevent third-party packages from affecting system files.
Even with these protections in place, packages still provide many options for abuse. Packages are very useful to install legitimate software but can also be used to install and persist malicious tools.
File Quarantine
File quarantine does not directly limit the abilities of package installers, but it is important to understand how it works together with other security features in macOS.
Quarantine flags were introduced in Mac OS X as early as version 10.4 (Tiger) but were not actually used for much until later in 10.5 (Leopard).
When a file arrives on your Mac from an external source, such as a download in a web browser, an email attachment, or an external drive, the process that downloads or copies generally adds a quarantine flag. The quarantine flag is added in an extended attribute to the file.
Note: the examples here reference desktoppr-0.5-218.pkg, the installer for a open source command line tool I wrote. You can download its installer pkg from the GitHub repository. The version and build number might be different.
After the download, you can see some of the metadata added to the download the Finder info window. Select the downloaded pkg file and choose ‘Get Info’ (⌘I) from the context or ‘File’ Menu. In the Info window that appears, you need to expand the ‘More Info’ section, where you will see the URL it was downloaded from. There might be more than one URL if the browser was redirected.
You can get more information in the command line using the xattr
command line tool: (xattr
stands for ‘extended attribute’, it is often pronounced like ‘shatter’)
> xattr desktoppr-0.5-218.pkg
com.apple.metadata:kMDItemDownloadedDate
com.apple.metadata:kMDItemWhereFroms
com.apple.quarantine
The quarantine flag has the attribute name com.apple.quarantine
. You can also use xattr
to show the contents of the extended attribute:
> xattr -p com.apple.quarantine desktoppr-0.5-218.pkg
0083;6842fcbe;Safari;A2964F09-ACDF-430F-8CFF-48BD75C464CD
The contents are (in order, separated by semi-colons):
- a hexadecimal flag number: always
0083
- a hexadecimal timestamp: e.g.
6842fcbe
- the process that created the file: e.g.
Safari
- a universal identifier (UUID)
You can convert the hexadecimal timestamp into a human readable time with
> date -jf %s $((16#6842fcbe))
Fri Jun 6 16:35:42 CEST 2025
There are two more extended attributes attached to the downloaded file that are interesting. The awkwardly named com.apple.metadata:kMDItemDownloadedDate
and com.apple.metadata:kMDItemWhereFroms
contain the download date and the web addresses the file was downloaded from respectively. When you look at them withxattr
, you see the data is stored in a binary property list format.
> xattr -p com.apple.metadata:kMDItemDownloadedDate desktoppr-0.5-218.pkg
bplist00?3A????r
To show this in a human readable format, you have to pipe the output through xxd
and plutil
:
> xattr -x -p com.apple.metadata:kMDItemDownloadedDate desktoppr-0.5-218.pkg | xxd -r -p | plutil -p -
[
0 => 2025-06-06 14:35:42 +0000
]
The name of the extended attribute gives us a hint that the information is also accessible through the file’s metadata, which is a bit easier:
> mdls -name kMDItemDownloadedDate desktoppr-0.5-218.pkg
kMDItemDownloadedDate = (
"2025-06-06 14:35:42 +0000"
)
The named kMDItemWhereFroms
attribute contains the URLs the file was downloaded from. It might be more than one URL because of redirections.
The URLs for GitHub downloads tend to be very long. After manually downloading Firefox, I see these URLs:
> mdls -name kMDItemWhereFroms Firefox\ 139.0.1.dmg
kMDItemWhereFroms = (
"https://download-installer.cdn.mozilla.net/pub/firefox/releases/139.0.1/mac/en-US/Firefox%20139.0.1.dmg",
"https://www.mozilla.org/"
)
It is important to remember that not all processes add quarantine flags to downloaded or copied files. As a general rule, applications with a user interface add quarantine files and command line tools and background processes do not. But there may be exceptions either way.
For example, when you download a file using the curl
command line tool, it will have no quarantine flag or other metadata extended attributes. This is might be exploited by malicious software.
The quarantine flag serves as a signal to the system that this file or archive needs to be checked before opening or running. The part of the system that performs this check is called Gatekeeper.
Gatekeeper
Gatekeeper was introduced to macOS in OS X Lion (10.7) in 2011. Gatekeeper will verify the integrity, signature and notarization status of an app or executable before opening it.
A package installer file can be:
- not signed at all
- signed, but not notarized
- signed and notarized
Gatekeeper works somewhat differently for installer packages compared to applications that you download in disk image (dmg) or other archive formats (e.g. zip). When you copy an application out of a disk image into the Applications folder or unarchive it from an archive, the system transfers the quarantine flag and metadata to the application bundle on the local disk. When you then open the app for the first time, the presence of the quarantine flag signals Gatekeeper to verify the integrity of the application using the signature and verify the notarization status. You can see the dialogs the system might present in this Apple support document.
The signature verifies the integrity and the source of an application or installer package. With an intact signature, you can be certain the package file has not been modified since it was signed. If the signature uses an Apple Developer ID, you can be fairly certain that the package was signed by that developer, or someone from that organization. There have been cases where Apple Developer ID certificates were stolen, but Apple will usually invalidate those fairly quickly.
Notarization is an extra step where the developer uploads the signed package file to Apple’s notarization servers. Apple then scans the package for certain security features and whether known malware signatures are present. Apple then adds the package file’s hash to their notarization database. The developer can also ‘staple a ticket’ to the package file, so that Gatekeeper doesn’t have to reach out to Apple’s servers on the check.
When the Gatekeeper verification of the signature and notarization status succeeds, the user gets a prompt to confirm that they want to launch the application they just downloaded.
When either verification fails, most commonly because the app is not notarized, the user gets a different, quite scary, prompt, stating that the system cannot verify the package is free of malware. You will get the same dialog when the package is not signed at all.
While generally, all software developers should sign and notarize their packages, this is not always the case. Open source projects, often have neither the financial nor logistical means to obtain an Apple Developer account, which provides the required Apple Developer ID certificates.
Bypassing Gatekeeper
Before you choose to install a package file which is not validly signed or notarized, you should first be certain the source is trustworthy. Then you should probably inspect the package using the tools in this post to verify that it only installs what it is supposed to, before actually installing it.
After attempting to open the pkg file with the Installer app by double-clicking and receiving the dialog that it could not be verified, click ‘Done.’ Then navigate to the ‘Privacy & Security’ pane in System Settings. Under the ‘Security’ section, you will see a message that the package ‘was blocked to protect your Mac’ with a button to ‘Open Anyway.’
This extra option will disappear after a few minutes.
You can also remove the quarantine flag using the command line.
> xattr -d com.apple.quarantine desktoppr-0.1.pkg
Without the quarantine flag, the Gatekeeper verification will not be triggered when the file is opened.
Packages installed by a device management service are not checked by Gatekeeper and do not need to be notarized. With some services, the packages may need to be signed, but not necessarily with an Apple Developer ID. Consult the documentation of your device management service for details.
Installer command line tool
You can also install package files from the command line using the installer
tool.
To install a package file on the current system volume, use the installer
command like this
> sudo installer -package desktoppr-0.5-218.pkg -target /
There are shorter flags for both these options:
> sudo installer -pkg desktoppr-0.5-218.pkg -tgt /
Installing a package with the installer
command will not enforce a restart or logout, whether the package requires one or not. You will have to perform or schedule the reboot manually.
Installing with installer
will also not trigger GateKeeper checks, whether the quarantine flag is set or not.
The -verbose
flag will increase the output of the installer tool which can help when you need to analyze problems. The installer process will also log to /var/log/install.log
so you can also monitor or review the installation log in the Console app.