Building a file utility/Full Disk Access/Sandboxing

My question: What is the best way to build a macOS app that requires 100% access to the entire file system of a user, in a way that complies with App Store policies? See details below:


I am new to macOS development and am still getting my head around Swift and Xcode, though I've been a professional developer for 15 years. I am building a macOS app in Xcode 11 and Swift 5.2, designed for systems 10.13 and later (though 10.14+ would be acceptable if the Full Disk Access factor makes 10.13 support impossible or not feasible).


The app is a file utility that lets users find certain files, filter them, and copy them to another location. Here is how the general UX goes:


- We start by showing the user a list of volumes, similar to the left pane of Finder. The user can select any volumes/root locations they want to search.

- We search those locations and store information about every file found in a db (SQLite at this point).

- The user can filter out what they don't want

- We can copy those to another location the user indicates.


I'm leaving this vague because the hope is that this will end up in the App Store. I am having trouble getting file access outside my package and would like to know what the experts would do here.


- I've created a Release build of my .app package, moved to /Applications, and manually enabled the Full Disk Access permission for that app. It seems my App Sandbox is still prioritized, I'm getting an access error when trying a fileManager.contentsOfDirectory.


- I've read in this forum that Security Bookmarks + FDA (Full Disk Access) are required, but that involves asking the user to pick the root "/" folder as a bookmark. This isn't in the spirit of what we want to build, our app is designed to find files that the user may have forgotten about, so we need to start by showing them the available Volumes so they have a complete idea of what's possible to search from. There is no option to choose sub-folders, it's a recursive search if they select Macintosh HD from the UI (not from an NSPanel or file picker).


What high-level steps should I be doing here to build an app where I can get the access I need, to every file on the user's system, forever, even if the user has to go through a painful set of steps to allow that permission? Full Disk Access alone doesn't seem to fix the problem, my Sandbox seems to be still standing in my way (unless there's a special way to approach this on the Swift side). I don't really have any meaningful code to post, it's a very basic test of trying to list files in a restricted location. Other apps are able to do this somehow and still comply with the App Store, so it's possible. How are they doing it?


Thanks.

Replies

What is the best way to build a macOS app that requires 100% access to the entire file system of a user, in a way that complies with App Store policies?

To be clear, that mission statement in unachievable in the general case. There’s at least two problems here:

  • The Mac App Store proscribes privilege escalation, and many files can only be accessed by privileged code (for example, files owned by other users on the system).

  • Beyond that, macOS supports something called data vaults that are inaccessible even to privileged processes (you need an Apple-only entitlement to access them).

It seems my App Sandbox is still prioritized

That’s correct. If you want to ship via the Mac App Store then you must work within the confines of the App Sandbox. That means that your first step must be getting the user to grant you access to the locations in the file system that you want to scan. They can do this in one of two ways:

  • The open panel

  • Drag’n’drop

Once they grant you access you can preserve that access via a security scoped bookmark.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

What is the best way to build a macOS app that requires 100% access to the entire file system of a user, in a way that complies with App Store policies?


This is impossible. Apple does "allow" Full Drive Access, but you have to be very careful about it. You cannot show it to the under unbidden. The user must navigate to some preferences dialog on their own and enable it. In your metadata, you cannot "require" Full Drive Access. In my experience, using the word "require" or even mentioning it at all, is an automatic rejection. If your app depends on this, it may be a non-starter.


And, even worse, people can be lulled into a mistaken hope based on variability between individual app reviewers. You may get version 1.0 into the store. Then you find a critical bug and need to issue an update. Reviewer #2 may reject your app and require a total redesign.


Some notes about eskimo's suggestions:

- Don't worry about data vaults. They are opaque and users can't access them anyway. Don't worry about that.

- Don't think you can just do privilege escalation outside of the Mac App Store. It won't work. I don't know if this is a bug or a feature, but I have found that helper tools, even when running as root, cannot get Full Disk Access. There is something about the launchd user/root divide and the new permissions system that breaks the connection. I even tried explicity giving the helper Full Disk Access. It didn't work. Maybe I was doing something wrong. I don't know.


Here is my advice:

- Write a different app. Do something that will work on iOS. Then you can port that relatively easily to macOS if you really want to. If you do macOS only, that's 90% of the market you are leaving on the table - and the best 90%.

- Stay in the Mac App Store. Don't listen to what developers on the internet tell you.

- Don't attempt any "system utilities" at all. Just come up with a novel idea that will work on any platform.