Config Profile and manage ALL the things…just about
You can manage so many more settings than Apple documents.
Apple’s list of supported management keys for configuration profiles is slowly growing, though some listed on their own support site no longer apply or work for current versions of macOS. If you want the official Apple documented supported settings for configuration profiles there’s two places, Apple’s developer documentation and an Apple support page
- https://developer.apple.com/documentation/devicemanagement/profile-specific_payload_keys
- https://support.apple.com/guide/mdm/complete-payload-list-mdm5370d089/1/web/1.0
The developer documentation is nice because it lets you know what keys have been updated and changed. The complete payload support page is nice because it gives a little more description about each setting.
But…But…But…there’s so much more, so many more settings you can manage with a configuration profile! So, what if you want to manage settings not listed in those documents…there’s a few ways to track down what is being set when a setting is changed.
1. The first way is to go to the User level Preferences folder or the global level Preferences folder and sort it by Date Modified. Now change the setting, sometimes it’s as simple as that, you can see the plist changed. Then, by viewing the plist file you may be able to determine what the key and value is. This way is easy, but can be confusing because a number of plist files may change at the same time, a plist file may contain dozens of keys and values, so determining which changed can be hard. And potentially the setting isn’t found in these folders, sometimes it’s in the subfolder ByHosts or in an app container.
2. Another way I hunt down what changes and what’s happening on the system is using an awesome open source GitHub project called Crescendo (https://github.com/SuprHackerSteve/Crescendo) that uses the Endpoint Security Framework. It’s a real time event viewer. Once you get Crescendo installed and running, I recommend quitting all other applications except the one you want to change and track. Even with every application closed, since this is a real time event viewer, there will be a lot happening. Even though there’s a lot happening, the process you’re looking for is cfprefsd which is the configuration preferences daemon. This will show you which file is changed but like just viewing the list in the Finder, you’ll have to figure out the key and value that’s changed within the plist. This will also show that certain processes may launch based off the setting.
3. Then the final way to track down a setting is using the Terminal command log stream --debug --predicate 'process == "cfprefsd" && eventMessage CONTAINS "wrote the key"'
.This shows events from the process cfprefsd and only if the event message contains the word “wrote the key”. This will show you the path to the plist and the key that’s being changed. But be warned, again this is SUPER BUSY, even more so than Crescendo.
One other way that rarely works but is worth mentioning, is running the strings
command against a binary and just taking an educated guess about what could be a configuration profile key in the text returned. If it’s an application bundle then in the Info.plist
you’ll have the CFBundleIdentifier
which would be the preference domain. This is the least likely method, but it has been used to find undocumentated configuration profile keys before.
Now that you know how to track down what’s changed, how do you make a configuration profile to deploy with your MDM to enforce the setting.
The most likely way that things will work is just making a configuration profile to control that preference domain directly.
Here’s an example of a Configuration Profile to enforce “Contacts Only” for AirDrop. Under the PayloadContent is the PayloadType which is com.apple.sharingd
. I got that value from the plist file name that changed, com.apple.sharingd.plist
. The key was called DiscoverableMode
and the two settings were Contacts Only
or Everyone
.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PayloadContent</key>
<array>
<dict>
<key>DiscoverableMode</key>
<string>Contacts Only</string>
<key>PayloadEnabled</key>
<true/>
<key>PayloadIdentifier</key>
<string>9a8471fe-dfde-42d8-aa8b-8758fb728154</string>
<key>PayloadType</key>
<string>com.apple.sharingd</string>
<key>PayloadUUID</key>
<string>9a8471fe-dfde-42d8-aa8b-8758fb728154</string>
<key>PayloadVersion</key>
<integer>1</integer>
</dict>
</array>
<key>PayloadDescription</key>
<string>Lock Airdrop to Contacts Only</string>
<key>PayloadDisplayName</key>
<string>Airdrop Settings</string>
<key>PayloadIdentifier</key>
<string>com.apple.sharingd</string>
<key>PayloadOrganization</key>
<string>TEST</string>
<key>PayloadRemovalDisallowed</key>
<true/>
<key>PayloadScope</key>
<string>System</string>
<key>PayloadType</key>
<string>Configuration</string>
<key>PayloadUUID</key>
<string>04c17696-b0c4-46e6-9261-ea9f5c4bd643</string>
<key>PayloadVersion</key>
<integer>1</integer>
</dict>
</plist>
So you’ll notice in the PayloadContent
section of the configuration profile we’re setting the PayloadType
to com.apple.sharingd
which was the same as the plist file name. Then in that same PayloadContent
section the key is set to DiscoverableMode
, which is the same key as found in the plist with the string value of Contacts Mode
.
Occasionally, this method of managing the domain directly will not do the trick and you must use ManagedClient preferences.
So your payload content section would look something like this…
<key>PayloadContent</key>
<array>
<dict>
<key>PayloadContent</key>
<dict>
<key>com.apple.sharingd</key>
<dict>
<key>Forced</key>
<array>
<dict>
<key>mcx_preference_settings</key>
<dict>
<key>DiscoverableMode</key>
<string>Contacts Only</string>
</dict>
</dict>
</array>
</dict>
</dict>
<key>PayloadEnabled</key>
<true/>
<key>PayloadIdentifier</key>
<string>95043937-af3e-42f3-b1b1-db331d097a5a</string>
<key>PayloadType</key>
<string>com.apple.ManagedClient.preferences</string>
<key>PayloadUUID</key>
<string>95043937-af3e-42f3-b1b1-db331d097a5a</string>
<key>PayloadVersion</key>
<integer>1</integer>
</dict>
You can manually install this configuration or sign it and push it out with the MDM of your choice.
Now that the profile is installed, how can you tell that it’s working…not every setting and application uses the preferences daemon.
- Try to change it in the interface. If you can switch the setting on and off in the UI it may not be respecting the configuration profile. HOWEVER, the interface doesn’t always represent the true setting value when set with a configuration profile. If you use our example of “Contacts Mode” vs “Everyone” for AirDrop, you can toggle between the 2 settings but nothing is actually being changed. Some settings will allow you to change them but when you quit and relaunch the application you’ll see that it’s set to the managed setting.
- If you watch the log stream while changing the setting you may not see anything change, which would mean the configuration profile is the authoritative setting. You can use the same command from before
log stream --debug --predicate 'process == "cfprefsd" && eventMessage CONTAINS "wrote the key"'
to watch preferences be set. - Or you can use a little application I wrote to read from cfprefsd called YAST (I’m open to suggestions for names). https://github.com/boberito/YAST
I used a lot of these tricks in hunting down preferences and settings for the macOS Security Compliance Project (https://github.com/usnistgov/macos_security). Even if you aren’t in a regulated industry, the project may be of interest to you for managing some undocumented settings.
These views are my own and not the views of my employer. If you have any questions or want more information on this, feel free to contact me on the MacAdmins Slack(boberito), Linkedin(linkedin.com/in/bob-gendler-8702014) or email(bobgendler@gmail.com).