Home > Mac administration, macOS, Management Profiles > Creating Privacy Preferences Policy Control profiles for macOS

Creating Privacy Preferences Policy Control profiles for macOS

As part of the pre-release announcements about macOS Mojave, Apple released the following KBase article:

Prepare your institution for iOS 12 or macOS Mojave:


Screen Shot 2018 08 31 at 2 38 58 PM

As part of the KBase article, Apple included a Changes introduced in macOS Mojave section which featured this note:

You can allow apps to access certain files used for system administration, and to allow access to application data. For example, if an app requests access to your Calendar data, you can allow or deny the request. MDM administrators can manage these requests using the Privacy Preferences Policy Control payload, as documented in the Configuration Profile Reference.

Screen Shot 2018 08 31 at 2 39 12 PM

What’s all this mean? For more details, see below the jump.

As part of macOS Mojave, Apple introduced new controls for accessing data in the individual user home folders. For more details about these changes, I recommend that you check out the following video and blog posts. Don’t worry about me, I’ll wait:

Back? OK, now that you’re familiar with what Apple was talking about with that section of the KBase, let’s discuss this section:

MDM administrators can manage these requests using the Privacy Preferences Policy Control payload, as documented in the Configuration Profile Reference.

What this means is that you may be able to whitelist your most common interactions and prevent them from displaying dialogs. Unfortunately, as of this date, Apple has provided only the following as documentation:

https://developer.apple.com/enterprise/documentation/Configuration-Profile-Reference.pdf (see the Privacy Preferences Policy Control Payload section.)

Apple refers to these as Privacy Preferences Policy Control Payload profiles, with a com.apple.TCC.configuration-profile-policy payload type. TCC stands for transparency consent and control and was discussed as part of the How iOS Security Really Works session at WWDC 2016:


These profiles can only be deployed to macOS Mojave and must be deployed by an user-approved MDM solution.

Screen Shot 2018 08 31 at 4 42 36 PM

While the current documentation doesn’t provide a lot of detail, based on my research, here is how the whitelist appears to work:

1. The item being whitelisted must be code-signed

As part of the profile, there is an entry for code signature so that the OS can verify that the whitelist entry matches up against the app requesting the action. How do you find out what the code signature of a particular app is? Run the following command against the application or other item that you want to whitelist:

codesign -dr - /path/to/Application.app

That said, there’s two ways that you can do this for third-party applications. As an example, if you’re using Jamf Pro 10.x to manage your Macs, the following application should be installed on your Mac:

/Library/Application Support/JAMF/Jamf.app

Screen Shot 2018 08 31 at 3 18 17 PM

If you run the following command, you should get the code signature for the app:

codesign -dr - "/Library/Application Support/JAMF/Jamf.app"

computername:~ username$ codesign -dr – "/Library/Application Support/JAMF/Jamf.app"
Executable=/Library/Application Support/JAMF/Jamf.app/Contents/MacOS/Jamf
designated => identifier "com.jamf.management.Jamf" and anchor apple generic and certificate 1[field.1.2.840.113635.] /* exists */ and certificate leaf[field.1.2.840.113635.] /* exists */ and certificate leaf[subject.OU] = "483DWKW443"
computername:~ username$

view raw


hosted with ❤ by GitHub

There’s two ways you can add this information to the profile:

Example A:

identifier "com.jamf.management.Jamf" and anchor apple generic

Example B:

identifier "com.jamf.management.Jamf" and anchor apple generic and certificate 1[field.1.2.840.113635.] /* exists */ and certificate leaf[field.1.2.840.113635.] /* exists */ and certificate leaf[subject.OU] = "483DWKW443"

Example A should be considered the least secure as it is very generic in how it reads the code signature, while Example B is the most secure because the full code signature is specified.

However, if Jamf ever needed to fundamentally change the code signature it was using for Jamf.app, Example A’s code signature would continue to match while Example B’s would not. Code signature fundamentals don’t change that often, but it is something to be aware of when creating the profiles.

One other thing to watch out for is multiple lines being returned by the code signature check, as I ran into this when checking an application produced by McAfee.

codesign -dr - "/Library/Application Support/McAfee/MSS/Applications/Menulet.app"

computername:~ username$ codesign -dr – "/Library/Application Support/McAfee/MSS/Applications/Menulet.app"
Executable=/Library/Application Support/McAfee/MSS/Applications/Menulet.app/Contents/MacOS/Menulet
designated => identifier "com.yourcompany.Menulet" and anchor apple generic and certificate 1[field.1.2.840.113635.] /* exists */ and certificate leaf[field.1.2.840.113635.] /* exists */ and certificate leaf[subject.OU] = GT8P3H7SPW
library => identifier libfmphelpers and anchor apple generic and certificate 1[field.1.2.840.113635.] /* exists */ and certificate leaf[field.1.2.840.113635.] /* exists */ and certificate leaf[subject.OU] = GT8P3H7SPW
computername:~ username$

view raw


hosted with ❤ by GitHub

Screen Shot 2018 08 31 at 2 11 05 PM

The needed code signing is what’s listed on the designated => line of output:

identifier "com.yourcompany.Menulet" and anchor apple generic and certificate 1[field.1.2.840.113635.] /* exists */ and certificate leaf[field.1.2.840.113635.] /* exists */ and certificate leaf[subject.OU] = GT8P3H7SPW

Screen Shot 2018 08 31 at 2 11 06 PM

2. The whitelist covers the parent process which is performing the action

Note: Here we’re heading off into territory that I can’t get confirmation about yet from Apple’s documentation. My research has lead me to the belief that the information below is right, but I don’t know for sure. Deploy appropriate levels of skepticism.

When creating the whitelist, you’re likely going to need to do a lot of testing to figure out what is actually calling an action that needs to be permitted by the user via a dialog window which appears. In many cases, you’ll need to whitelist the parent process which is asking for X, which in turn is running Y, which is executing Z and Z is what is actually causing the dialog window to appear.

A good example is when using Jamf’s Self Service to install software. A Self Service policy might include the following:

  1. The policy which installs the software.
  2. A notification that tells you “Hey, the software’s installed”
  3. A script that pops up its own dialog window to say “Hey, we’ve installed this software but it’s unlicensed and we need you to now enter the license code you got from the help desk.”

Jamf has a couple of applications involved in this process to help it go smoothly:


The notification and dialog window may trigger a dialog window which asks you if you want to allow a particular thing to happen. Depending on which application triggered it, you may see a notification that jamf (or jamfAgent) is the one requesting it. However, it may seem senseless: that “Hey, the software’s installed” notification is clearly an AppleScript dialog; why isn’t AppleScript the one being referred to as the requester?

The reason is that whichever application was named was the process that started the chain of events going. If jamfAgent is the one referenced, that means that the jamfAgent process is the process that asked AppleScript “Hey, mind showing that to my friend sitting between the keyboard and chair? Thanks.” So in this situation, even though it’s ultimately an AppleScript dialog window that appears, you would need to whitelist /usr/local/jamf/bin/jamfAgent.

3. There are filesystem permissions and there are application permissions

There are a number of dictionary keys available to the whitelist profiles:

  • AddressBook
  • Calendar
  • Reminders
  • Photos
  • Camera
  • Microphone
  • Accessibility
  • PostEvent
  • SystemPolicyAllFiles
  • SystemPolicySysAdminFiles
  • AppleEvents

For whitelisting things like dialog messages and allowing access to data, there are two that seem to matter most:

  • SystemPolicyAllFiles
  • AppleEvents

SystemPolicyAllFiles allows the whitelisted application access to all protected files. As an example, your antivirus software may pop up dialog messages like crazy because it’s trying to scan areas of your home folder that Apple has now marked as protected. Once you identify the process which is actually running the scan and whitelist it using SystemPolicyAllFiles, the scans should now succeed without dialog messages because the scanning process has now been authorized by the whitelist to go into those areas.

AppleEvents allows the whitelisted application the ability to send an AppleEvent to an otherwise restricted application. For example, you may have a script which includes the following command:

osascript -e 'display dialog "Hey there!" with title "Hello"'

Screen Shot 2018 08 31 at 4 04 35 PM

You may get a dialog window requesting permission to let osascript control the Finder. If you add an entry to your whitelist for /usr/bin/osascript, to authorize it to be able to send AppleEvents to com.apple.Finder, now you won’t get the permission request because now osascript is authorized to send requests to the Finder.

Creating the profiles

When creating my own profiles, I found a great tool created by Carl Ashley:


This tool allowed me to plug in what I needed to whitelist and generated a profile for me. For example, I wanted to generate a profile for McAfee Endpoint Security with the following criteria:

Full Disk Access:

/Library/Application Support/McAfee/MSS/Applications/Menulet.app

Note: /usr/local/McAfee/fmp/bin/fmpd is the McAfee file scanner

Able to send restricted AppleEvents:

/Library/Application Support/McAfee/MSS/Applications/Menulet.app – Send AppleEvents to SystemEvents, SystemUIServer and Finder

I was able to use the following command with the tccprofile tool to generate the profile I needed:

/path/to/tccprofile.py –allfiles "/Library/Application Support/McAfee/MSS/Applications/Menulet.app" /usr/local/McAfee/fmp/bin/fmpd –appleevents "/Library/Application Support/McAfee/MSS/Applications/Menulet.app","/System/Library/CoreServices/System Events.app" "/Library/Application Support/McAfee/MSS/Applications/Menulet.app","/System/Library/CoreServices/SystemUIServer.app" "/Library/Application Support/McAfee/MSS/Applications/Menulet.app","/System/Library/CoreServices/Finder.app" –allow –payload-description="This profile allows specified applications to display information to the logged-in user." –payload-identifier="com.company.mcafee.tcc.privacy.whitelist" –payload-name="Privacy Settings Whitelist – McAfee" –payload-org="Company Name" –payload-version="1" -o McAfee_All_Files_and_Notifications_v1.mobileconfig

view raw


hosted with ❤ by GitHub

However, there was a problem with the profile because of McAfee’s extra code-signing line.

Screen Shot 2018 08 31 at 4 26 43 PM

Once the profile was edited to remove the extra code signature information, the profile was ready to go.

Screen Shot 2018 08 31 at 4 27 43 PM

Reference Examples

Since this is a new area for Mac admins, I’ve posted several profiles for reference at the following location:


All were generated by the tccprofile tool and I’ve included README files that describe the individual profiles and the commands used to create the profile in question.

  1. Wesley
    September 6, 2018 at 3:39 pm

    Very cool! It might seem like a pain now, but I’m excited to see how this affects Mojave.

  2. Tobias Hall
    October 2, 2018 at 3:14 pm

    Thanks for the info. Apologies but is there a way to identify what process is required by a specific application? I’m got as far as getting all the existing apps (sqlite3 /Library/Application\ Support/com.apple.TCC/TCC.db “SELECT * from access”) and then the current actions (/usr/bin/log stream –debug –predicate ‘subsystem == “com.apple.TCC” AND eventMessage BEGINSWITH “AttributionChain”‘) but can’t figure out what access the approved apps need specifically.

  3. Matt
    October 3, 2018 at 7:34 pm

    It appears I am unable to upload these profiles as the Jamf Server is not allowing me to. Is there something I need to do to bless them before uploading? I am on Jamf Pro v. 10.7.1

  4. Headbolt
    October 26, 2018 at 10:32 am

    I have a simple Login Script that fails on the Below Line, none of the Given Examples stop the error “36:268: execution error: Not authorised to send Apple events to System Events. (-1743)” even though it seems they should.

    Any Ideas ?

    userPass=”$(osascript -e ‘Tell application “System Events” to display dialog “Blah Blah Blah.\nPlease enter password.” default answer “” with title “Startup” with text buttons {“Ok”} default button 1 with hidden answer’ -e ‘text returned of result’)”

  5. Jason McDonald
    October 31, 2018 at 7:35 pm

    Has anyone found a way to whitelist apps that are NOT code signed?

    • October 31, 2018 at 7:35 pm

      No. Code signing is required.

  6. Grand-Mumbler
    December 4, 2018 at 5:17 am

    As always, thanks for helping this stuff make sense.

  7. Justin Taylor
    April 17, 2019 at 1:08 pm

    With the privacy payload, is it only good for that specific version of the application? Say for filmmaker 17.0.4, when we update to 17.0.5 do we need to create another payload?

  8. Headbolt
    August 28, 2019 at 5:40 pm

    There are new Sections in Catalina, any ideas how to write a profile that works for them, The one causing me Headaches is “Screen Recording” without it 3rd Party Dock’s and 3rd Party Remote control \ remote support dies as you can move the mouse and type, but not see the screen

  9. Bruno
    February 24, 2021 at 3:17 pm

    Any idea how to upload a profile for Privacy preferences control, without using a MDM? I mean, can I manually create and upload a profile that changes the Privacy Preferences? I tried to create it using apple configurator, but it seems to does not control the priivacy settings, anu clue? thanks

    • February 24, 2021 at 3:39 pm

      You don’t. Managing PPPC settings requires User-approved MDM, which in turn requires using MDM.

  10. GabeShack
    February 11, 2022 at 4:14 pm

    @rtrouton Im noticing something seemed to change with a security update in 11.4. I used to run an AppleScript that would enter the current users name into a browser field during the first login (to help with no touch deployment). I had a PPC config profile for jamf which includes all the various pieces of jamf and i have another for osascript. Both Allow access to Accessibility, but since 11.4, it seems the child process com.jamf.doesnt seem to allow for this from the parent process anymore. Not sure if you have any advise here, but I’ve been looking at this for weeks and cant seem to solve it.

    I’ve documented this at https://community.jamf.com/t5/jamf-pro/quot-jamf-quot-wants-access-to-control-quot-system-events-quot/m-p/140815#M129892

    Hoping to hear any thoughts you have. My eyes are numb from the amount of logs ive gone though at this point.

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: