Privacy preferences (PPPC) profile
macOS requires user consent before an app can access protected folders like Documents, Desktop, and Downloads. Without a PPPC profile, each user will see a macOS prompt the first time shft tries to read these folders:
"shft" would like to access files in your Documents folder.
In an enterprise migration, these prompts are confusing and disruptive. Deploy a PPPC configuration profile via MDM to pre-approve shft's access silently.
What shft needs access to
| Permission | Reason |
|---|---|
| Files and Folders — all user files | shft reads Documents, Desktop, Downloads, Pictures, Music, Movies, and any custom user folders to calculate sizes and transfer them |
| SystemPolicyAllFiles (Full Disk Access) | Required for reading ~/Library/Application Support, ~/Library/Preferences, browser data, and keychain export |
PPPC profile
Deploy this as a Privacy Preferences Policy Control payload via MDM. This cannot be installed manually — it must come from MDM.
<?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>PayloadType</key>
<string>com.apple.TCC.configuration-profile-policy</string>
<key>PayloadIdentifier</key>
<string>com.machinerysoftware.shft.pppc</string>
<key>PayloadUUID</key>
<string>B2C3D4E5-F6A7-8901-BCDE-F12345678901</string>
<key>PayloadVersion</key>
<integer>1</integer>
<key>Services</key>
<dict>
<!-- Full Disk Access — covers Library, Preferences, browser data, keychain -->
<key>SystemPolicyAllFiles</key>
<array>
<dict>
<key>Identifier</key>
<string>com.machinerysoftware.shft</string>
<key>IdentifierType</key>
<string>bundleID</string>
<key>CodeRequirement</key>
<string>identifier "com.machinerysoftware.shft" and anchor apple generic</string>
<key>Allowed</key>
<true/>
<key>Comment</key>
<string>shft needs full disk access to read user data for migration</string>
</dict>
</array>
</dict>
</dict>
</array>
<!-- Profile metadata -->
<key>PayloadDisplayName</key>
<string>shft Privacy Preferences</string>
<key>PayloadDescription</key>
<string>Grants shft access to user files and system data for Mac-to-Mac migration. Suppresses TCC consent prompts during migration.</string>
<key>PayloadIdentifier</key>
<string>com.machinerysoftware.shft.pppc.profile</string>
<key>PayloadType</key>
<string>Configuration</string>
<key>PayloadUUID</key>
<string>A1B2C3D4-E5F6-7890-ABCD-EF0987654321</string>
<key>PayloadVersion</key>
<integer>1</integer>
<key>PayloadScope</key>
<string>System</string>
</dict>
</plist>Deployment notes
This profile must be deployed via MDM
PPPC profiles cannot be installed manually — macOS ignores them if double-clicked or installed via profiles install. They must be pushed through an MDM server (Jamf, Kandji, Mosyle, Intune).
Deploy to both source and destination Macs
shft reads files on the source Mac (to calculate sizes and transfer) and writes files on the destination Mac. Deploy the PPPC profile to both.
Deploy before the user opens shft
If the user opens shft before the PPPC profile arrives, they'll see the TCC prompts. Once they dismiss them (allow or deny), the PPPC profile can't retroactively change their choice. Deploy the profile first.
Code requirement must match your signed app
The CodeRequirement field in the profile must match the actual code signature of your shft build. Once you have a Developer ID:
- Build and sign shft
- Run:
codesign -dr - /Applications/shft.appto get the designated requirement - Replace the
CodeRequirementstring in the profile with the output
If the requirement doesn't match, macOS silently ignores the PPPC grant.
Full Disk Access vs individual folder access
You might consider granting only specific folder access instead of Full Disk Access. However:
~/Library/Application Supportand~/Library/Preferencesrequire Full Disk Access- Keychain export via
SecItemCopyMatchingrequires Full Disk Access - Browser data in
~/Library/Safarirequires Full Disk Access - Granting individual folder access (Documents, Desktop, Downloads) doesn't cover Library
Full Disk Access is the only practical option for a migration tool.
Per-MDM instructions
Jamf Pro
- Go to Computers → Configuration Profiles
- Create a new profile
- Add the Privacy Preferences Policy Control payload
- Add an entry:
- Identifier:
com.machinerysoftware.shft - Identifier Type: Bundle ID
- Code Requirement:
identifier "com.machinerysoftware.shft" and anchor apple generic - SystemPolicyAllFiles: Allow
- Identifier:
- Scope to the same group as your shft deployment
Kandji
- Go to Library → Add New → Privacy
- Upload the
.mobileconfigabove, or configure manually:- App:
com.machinerysoftware.shft - Full Disk Access: Allow
- App:
- Assign to the appropriate blueprint
Mosyle
- Go to Management → Profiles → Privacy Preferences
- Add a new PPPC profile
- Add shft's bundle ID with Full Disk Access allowed
- Assign to target devices
Intune
- Go to Devices → Configuration profiles → Create profile
- Platform: macOS, Profile type: Templates → Custom
- Upload the
.mobileconfigfile - Deploy to target device groups
What happens without this profile
| Scenario | What the user sees |
|---|---|
| No PPPC profile, user clicks Allow | shft works normally, one prompt per folder category |
| No PPPC profile, user clicks Don't Allow | shft can't read that folder, shows 0 bytes, files won't transfer |
| PPPC profile deployed | No prompts. shft accesses everything silently. |
Privileged helper PPPC
The shft privileged helper (com.machinerysoftware.shft.helper) runs as root and doesn't need separate PPPC grants — root processes bypass TCC. Only the main app needs the PPPC profile.