bash,  Mac OS X,  Mac Security

Get Telemetry on App and System Extensions in macOS

Application extensions allow developers to import common SDKs into projects so they can build increasingly interesting apps without developing a lot of code for those things vendors expose. The Apple extensions typically allow a developer to bring in various Apple libraries and then call them in their code. For example, com.apple.quicklook.thumbnail is used to produce thumbnails in quicklook; therefore Apple apps like iBooks and Shortcuts and any 3rd party developer like MindNode that wants to use Quicklook can provide a known and so somewhat seamless user experience. Click on the Privacy & Security System Preferences and then Extensions and then Quick Look to see the non-Apple apps that use the Quick Look SDK.

These are loaded during plug-in discovery. When an app is opened, the plug-ins load and since they’re part of the /System/Library/ExtensionKit/Extensions or some other directory they can be dynamically loaded and exposed without consuming a ton of resources. There are tons of extensions. Some import graphical libraries and others allow developers to work with files more easily (e.g. com.apple.fileprovider-nonui in OneDrive), etc. In the Extensions screen of System Settings, click Finder extensions to see those that are loaded (including if it’s installed, OneDrive). Sharing sheets, Notifications, Photo Editing, and others can be seen in Extensions as well. Most (although not all) will require users to explicitly grant access to the necessary resources to load.

System Extensions are a replacement for kernel extensions and are typically used to change the way the system responds to various events. Some have higher barriers of entry, such as individual meetings to make sure the power they give the developer isn’t used for unintended purposes. Another barrier of entry is that users can disable them and/or have to have them enabled via an MDM as a part of a command or profile. To see a list of active System Extensions, use the systemextensionsctl command with a list verb to see the running extensions:

systemextensionsctl list

Some extensions also fall somewhere between what a System Extension might be used for and what app extensions are meant for. Some can be enabled programmatically, such as with:

pluginkit -e use -I io.MyAwesomeApp.AppExtension

Many cannot. One of these might be the Credential Provider extension. As these are managed by PluginKit, the pluginkit command can be used to see them loaded and provide metadata about them. For example, rather than use the Privacy & Security System Settings -> Extensions to see the Password AutoFill, we can check the status with pluginkit (which resembles Jorge but for extensions instead of hardware). The command to see this information would be pluginkit with some switches – for example, the following shows all extensions:

pluginkit -mAvvv

A quick find in Terminal shows the CredentialProvider along with where the .appex bundle is located:

  • io.myawesomeapp.myapp-macOS.CredentialProvider(0.1.0)
    Path = /Applications/myapp-macOS.app/Contents/PlugIns/CredentialProvider.appex
    UUID = 6688AAEE-0EC7-42B0-A55F-582AAF6F19AC
    Timestamp = 2022-11-10 14:36:00 +0000
    SDK = com.apple.authentication-services-credential-provider-ui
    Parent Bundle = /Applications/myapp-macOS.app
    Display Name = MyApp
    Short Name = MyApp
    Parent Name = MyApp-macOS
    Platform = macOS

The CredentialProvider is managed by the CredentialProviderExtensionHelper and the AppleCredentialManagerDaemon. The PluginKit binary is pkd (invoked by launchd and if all is well consuming less than maybe a dozen megs of memory).

Inside the CredentialProvider.appex bundle there is an info.plist with metadata about the credential provider and any app that loads an extension should have a corresponding /Applications/MyApp-macOS.app/Contents/_CodeSignature/CodeResources file that lists the extensions loaded:

cat /Applications/MyApp-macOS.app/Contents/_CodeSignature/CodeResources

Here, there are keys for resources and plugins loaded. That credential provider is then loaded in user space at ~/Library/Application Support/com.apple.AuthenticationServices/CredentialProviders (which SIP protects from reads). A network provider (e.g. what’s used by most ZTNA solutions) might show com.apple.networkextension.packet-tunnel and so looking for whether that’s loaded can net a way to programmatically derive the state of those by bundle ID. Unlike kernel extensions, these are imported and exposed as well-documented APIs for developers. To interrogate extensions (rather than walk through info plists and the like:

pluginkit -m -v -I io.MyAwesomeApp.AppExtension

Note: Most of this also applies to iOS simulators but you can’t really get to it on a running device.

Some of these require entitlements. To see a list of entitlements for many of these, see Jonathan Levin’s entitlement database at: http://newosxbook.com/ent.jl?osVer=MacOS15. It doesn’t include which third parties have access to entitlements but does lay out how Apple uses many internally.