How to List Apps Across All Macs
Using Kolide, you can easily view and query Mac Apps across your fleet.
Introduction
The primary means of software installation on macOS are bundles called Apps. These .app bundles may include software installed by the operating system, by the end-user via download, or by the end-user via the App Store. This inventory catalogs all apps found on a device regardless of installation path, so long as they are registered with the macOS LaunchServices API and then enumerates various metadata about the application such as version, the executable binary run by the app, and whether the software is signed.
To see a similar list on your device, you can follow the steps below:
- Click on the Apple menu at the top left of your screen,
- Click the item labeled "About this Mac" in the drop-down
- On the Overview tab of the About this Mac screen, click the button labeled "System Report..."
- In the sidebar on the left, scroll down to the section labeled "Software", and then click on the subitem labeled "Applications"
Kolide additionally enriches the data returned by osquery, by also retrieving the icon data for all installed apps.
What Mac App Data Can Kolide Collect?
Kolide's endpoint agent bundles in osquery to efficiently collect Mac Apps from Macs in your fleet. Once collected, Kolide will parse, clean up, and centrally store this data in Inventory for your team to view, query, or export via API.
Kolide meticulously documents every piece of data returned so you can understand the results.
Mac Apps Schema
Column | Type | Description | |
---|---|---|---|
id | Primary Key |
Unique identifier for the object |
|
device_id | Foreign Key |
Device associated with the entry |
|
device_name | Text |
Display name of the device associated with the entry |
|
applescript_enabled | Text |
Info properties NSAppleScriptEnabled label |
|
arch | Text |
If applicable, the arch of the signed code |
|
bundle_identifier | Text |
Info properties CFBundleIdentifier label |
|
bundle_name | Text |
Info properties CFBundleName label |
|
bundle_package_type | Text |
Info properties CFBundlePackageType label |
|
category | Text |
The UTI that categorizes the app for the App Store |
|
compiler | Text |
Info properties DTCompiler label |
|
copyright | Text |
Info properties NSHumanReadableCopyright label |
|
development_region | Text |
Info properties CFBundleDevelopmentRegion label |
|
display_name | Text |
Info properties CFBundleDisplayName label |
|
element | Text |
Does the app identify as a background agent |
|
environment | Text |
Application-set environment variables |
|
info_string | Text |
Info properties CFBundleGetInfoString label |
|
last_opened_at | Timestamp |
The last time the application was opened. Note on data collection: This value is updated automatically by LaunchServices on the device everytime an app is opened. The LaunchServices DB is occasionally cleared by major macOS updates, so a |
|
minimum_system_version | Text |
Minimum version of macOS required for the app to run |
|
name | Text |
Name of the |
|
path | Text |
Absolute and full Name.app path |
|
signature_authority | Text |
Certificate Common Name |
|
signature_cdhash | Text |
Hash of the application Code Directory |
|
signature_identifier | Text |
The signing identifier sealed into the signature |
|
signature_team_identifier | Text |
The team signing identifier sealed into the signature |
|
signed | Boolean |
|
|
bundle_short_version | Text |
The text representation of the version |
|
bundle_short_version_major | Bigint |
|
|
bundle_short_version_minor | Bigint |
|
|
bundle_short_version_patch | Bigint |
|
|
bundle_short_version_subpatch | Bigint |
|
|
bundle_short_version_pre | Text |
|
|
bundle_short_version_build | Text |
|
|
collected_at | Timestamp |
Time the row of data was first collected in the database |
|
updated_at | Timestamp |
Time the row of data was last changed in the database |
|
What Can You Do With This Information?
Kolide enables you to write your own queries against the data the agent collects. This allows you to build your own reports and API endpoints. For example, you can:
SELECT
name,
bundle_identifier,
device_name,
last_opened_at
FROM mac_apps
WHERE bundle_identifier ILIKE 'com.adobe%'
AND bundle_name IN(
'Photoshop',
'Photoshop CC'
'Illustrator',
'Illustrator CC',
'After Effects',
'Acrobat Pro',
'Acrobat Pro DC',
'InDesign',
'InDesign CC',
'Premiere Pro',
'Premiere Pro CC',
'Adobe Audition'
)
AND ( last_opened_at ISNULL
OR last_opened_at < (NOW() - interval '90 days'))
AND last_opened_at IS NOT NULL
LIMIT 5
name | device_name | last_opened_at | bundle_identifier |
---|---|---|---|
Adobe Illustrator.app | Ashleys-MacBook-Pro | 2018-02-16T20:52:52.000Z | com.adobe.illustrator |
Adobe InDesign CC 2018.app | daves-imac | 2018-02-14T21:56:28.000Z | com.adobe.InDesign |
Adobe After Effects CC 2017.app | jens-imac-pro | 2018-03-19T20:54:26.000Z | com.adobe.AfterEffects |
Adobe Audition 2020.app | Bills-MacBook-Air | 2020-05-03T21:16:33.000Z | com.adobe.Audition |
Adobe Acrobat.app | Steve-MacBook-Pro.local | 2018-02-15T18:00:48.000Z | com.adobe.Acrobat.Pro |
WITH
chrome_stable_split AS (
SELECT
version AS latest_stable,
version_major,
version_minor,
version_build,
version_patch
FROM google_chrome_latest_releases
WHERE channel = 'stable'
AND platform = 'mac'
)
SELECT
ma.device_name,
bundle_short_version AS installed_version,
latest_stable,
CASE WHEN (
bundle_short_version_major < version_major
OR bundle_short_version_major <= version_major AND bundle_short_version_minor < version_minor
OR bundle_short_version_major <= version_major AND bundle_short_version_minor <= version_minor AND bundle_short_version_patch < version_build
OR bundle_short_version_major <= version_major AND bundle_short_version_minor <= version_minor AND bundle_short_version_patch <= version_build AND bundle_short_version_subpatch < version_patch
) THEN 'true' ELSE 'false' END AS chrome_requires_update
FROM mac_apps ma, chrome_stable_split
WHERE bundle_identifier = 'com.google.Chrome' LIMIT 16
device_name | name | latest_stable | installed_version | chrome_requires_update |
---|---|---|---|---|
balthazar | Google Chrome.app | 102.0.5005.61 | 99.0.4844.51 | true |
daves-imac | Google Chrome.app | 102.0.5005.61 | 100.0.4896.127 | true |
Gens-MacBook-Pro-3 | Google Chrome.app | 102.0.5005.61 | 100.0.4896.127 | true |
Conference-Room-Zoom | Google Chrome.app | 102.0.5005.61 | 90.0.4430.85 | true |
Caitlins-MacBook-Pro-2 | Google Chrome.app | 102.0.5005.61 | 100.0.4896.75 | true |
Jimmys-MacBook-Air | Google Chrome.app | 102.0.5005.61 | 102.0.5005.61 | false |
Debras-MacBook-Pro | Google Chrome.app | 102.0.5005.61 | 102.0.5005.61 | false |
Why Should I Collect Mac Apps?
App installations are cataloged and tracked to facilitate a number of potential purposes, for example:
- Ensuring required software (VPN, Antivirus, Password Manager) is installed
- Discovering potential malicious software
- Tracking the install count of various licensed software (eg. Adobe Creative Suite, Microsoft Office)
- Finding unsigned software
End-User Privacy Consideration
Kolide practices Honest Security. We believe that data should be collected from end-user devices transparently and with privacy in mind.
An employer with access to your app installations can determine the following:
- What applications you have installed on your device (and the path of their installation)
- The most recent timestamp for when you last opened each application
When you use Kolide to list Mac App data from end-user devices, Kolide gives the people using those devices insight into exactly what data is collected, the privacy implications, and who on the IT team can see the data. This all happens in our end-user privacy center which can be accessed directly by employees.