Unsandboxed app can't access files: System Policy deny(1) file-read-data

I am working on a macOS app which is distributed outside of the App Store and isn't sandboxed or signed. My understanding is that non-sandboxed apps should have access to everything that the user can access. Yet I'm getting a console error Sandbox: my-app(1868) System Policy: deny(1) file-read-data that is causing some problems:

The app uses several filepath inputs that the user types into a form. We do some validation of the filepaths, and the user can't submit the form until validation passes. Validation involves (1) checking that the path exists, (2) checking for rwx permissions, and (3) trying to open the file.
When the form autofills with inputs from the previous run, all filepath inputs fail validation on step (3). Clearing one input and re-entering it, which triggers validation to run again, causes all inputs to pass as expected. Looking at the console logs, there is an error Sandbox: my-app(1868) System Policy: deny(1) file-read-data <filepath> for each filepath input.

Each time the app is run, it writes to a workspace directory (by default ~/Documents/model_workspace/. It creates this directory if it doesn't exist and overwrites it if it already exists. If the workspace directory exists and was created by a previous run of the app, it works as expected. But if it exists and was created by mkdir or by the CLI version of the app, it doesn't work. A similar error Sandbox: my-app(1868) System Policy: deny(1) file-read-data ~/Documents/model_workspace shows up in the console logs.

Things I have tried:

  • Changed the file permissions to drwxrwxrwx (no effect)

  • Gave the app Full Disk Access in System preferences>Privacy (no effect)

  • Looked further into the logs. The error correlates with an error from tccd: FAIL: PID[2624]: SecTaskCopySigningIdentifier(): [22: Invalid argument]

I had thought that TCC would prompt the user for permission if the app tries to access ~/Documents. Maybe something is going wrong with that step? I tried to find more TCC logging with log show --info --debug --signpost --predicate 'eventMessage contains[c] "tcc"'. I have attached an excerpt from around the time of the form autofilling and validation failing. I notice several lines containing Composed entitlement check for ({ID: <ID of InvalidCode>. Is the invalid code a problem?

We are very stuck on this issue and any help would be appreciated!



Answered by DTS Engineer in 640805022

My understanding is that non-sandboxed apps should have access to
everything that the user can access.

That is not correct. 10.15 and later introduce additional access control for the desktop and the Documents directory. See WWDC 2019 Session 701 Advances in macOS Security. 10.14 introduces the concept of Full Disk Access. See WWDC 2018 Session 702 Your Apps and the Future of macOS Security. And data vaults, something we’ve never formally documented, were introduced in later 10.13 releases.

I had thought that TCC would prompt the user for permission if the app
tries to access ~/Documents.

That is the expected behaviour. I suspect your app has a code signing problem that’s confusing TCC.

I am working on a macOS app which is distributed outside of the App
Store and isn't … signed.

Yeah, that’s not good. TCC needs a stable signature for it to be able to record which app was granted permission by the user. You need to sign your code. For development, I encourage you to use an Apple Developer signing identity. For distribution, you’ll need Developer ID.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@apple.com"

I am working on a macOS app which is distributed outside of the App Store and isn't sandboxed or signed.

Then you are dead in the water. Apple has said that all apps will have to be signed. From what I understand, this means just to run them. If you are distributing apps, they will have to be signed and properly notarized by Apple.

My understanding is that non-sandboxed apps should have access to everything that the user can access.

This is not true. As of macOS 10.15 Catalina, the end user has more privileges than any running software, even when running under the root user.

The app uses several filepath inputs that the user types into a form. 

Don't use file paths. Use standard file open panels.

According to your logs, the app is running translocated. This is like a quasi-sandbox. I don't know if the app will be able to access the documents folder when launched translocated. And I see you are using Qt. And you are directly referencing bash. And Python!

I think you should seriously review the architecture for this app. Suppose you set out to build a SwiftUI app using the iOS SDK and tried to deploy it on Windows. That is essentially what you are attempting here. You are going to have no end of problems with this.
Accepted Answer

My understanding is that non-sandboxed apps should have access to
everything that the user can access.

That is not correct. 10.15 and later introduce additional access control for the desktop and the Documents directory. See WWDC 2019 Session 701 Advances in macOS Security. 10.14 introduces the concept of Full Disk Access. See WWDC 2018 Session 702 Your Apps and the Future of macOS Security. And data vaults, something we’ve never formally documented, were introduced in later 10.13 releases.

I had thought that TCC would prompt the user for permission if the app
tries to access ~/Documents.

That is the expected behaviour. I suspect your app has a code signing problem that’s confusing TCC.

I am working on a macOS app which is distributed outside of the App
Store and isn't … signed.

Yeah, that’s not good. TCC needs a stable signature for it to be able to record which app was granted permission by the user. You need to sign your code. For development, I encourage you to use an Apple Developer signing identity. For distribution, you’ll need Developer ID.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@apple.com"

I suspect your app has a code signing problem that’s confusing TCC.... TCC needs a stable signature for it to be able to record which app was granted permission by the user.

This sounds like the issue. I wasn't aware that signatures matter for anything after the app is opened. Thanks for clarifying!

You need to sign your code. For development, I encourage you to use an Apple Developer signing identity. For distribution, you’ll need Developer ID.

We are in the process of getting a developer ID authorized by our organization and hope to release a signed version soon. However we've been distributing the unsigned software for several years without issues. This is a scientific application so distributing through the App Store has not been a priority.

According to your logs, the app is running translocated. This is like a quasi-sandbox.

Thanks, this is helpful to know.

And I see you are using Qt. And you are directly referencing bash. And Python! I think you should seriously review the architecture for this app. Suppose you set out to build a SwiftUI app using the iOS SDK and tried to deploy it on Windows. That is essentially what you are attempting here. You are going to have no end of problems with this.

We are replacing the Qt UI with an Electron app soon. Could you please explain more about what is problematic with the architecture? As far as I know, we aren't using anything that's platform specific.

We are in the process of getting a developer ID authorized by our
organization and hope to release a signed version soon.

Cool. Pending that you should use an Apple Development signing identity for your day-to-day development. This will give you a stable signature, which should be sufficient to get TCC to behave.

Two things:
  • It may not actually be sufficient to get TCC to behave (-: There’s a world of potential issues here, especially when working with third-party libraries and language runtimes.

  • Your Developer ID and Apple Development signing identities looks different to TCC. If you do your day-to-day debugging with Apple Development, you’ll likely see some TCC oddities when you test your Developer ID app on the same Mac. This is one of the reasons for the testing procedure I outlined in this post.

This is a scientific application so distributing through the App Store
has not been a priority.

Folks often conflate code signing with the App Store. Code signing existed before the App Store, and before iOS even, and the App Store is just one application of the overall code signing technology. Probably the first application of code signing was the macOS keychain, where it lets us properly solve the “Is version N+1 of your app logically the same as version N?” problem. TCC needs it for similar reasons.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@apple.com"

We are in the process of getting a developer ID authorized by our organization and hope to release a signed version soon. However we've been distributing the unsigned software for several years without issues. This is a scientific application so distributing through the App Store has not been a priority. 

A developer ID is not for App Store distribution. The App Store is a totally different thing. But if you want to distribute, or perhaps even run in the future, you're going to need a signature. Ideally, the app should be notarized.

We are replacing the Qt UI with an Electron app soon. Could you please explain more about what is problematic with the architecture? As far as I know, we aren't using anything that's platform specific.

Hold up there! You are going in the wrong direction!

First of all, if your UI interface is not that complicated and you are considering switching from Qt to Electron, then you really have no excuse not to just do it in SwiftUI. It sounds like your UI and back-end code are well-separated. Otherwise such a switch wouldn't be possible. OK. Keep the separation. Just do the UI in SwiftUI. Do the back-end with a dylib or helper tool. It doesn't matter much. Once the app is hosted in Xcode, then these problems that you have now, and the massive problems you have coming up that you don't know about yet, simply go away.

Secondly, things like Electron, Qt, bash, and Python (and Xcode and SwiftUI) are most definitely platform specific. There is nothing wrong with that. The trick is, you have to use them on the appropriate platform. You are using, and switching to, tools that are not appropriate for the Mac platform. Can you get them to work? Maybe, but you are setting yourself up for so much pain - so much pain.

You said you have a scientific tool. Does that come in a command-line flavour? If so, you're essentially done. Use that. Wrap it in SwiftUI. Have Xcode build it all. Archive > Export > Upload > wait 2 minutes > Notarized!

(I realize I'm glossing over the bash and Python bits. If your command-line tool is Python, then that's still going to be a challenge to integrate into a Mac App. )
Unsandboxed app can't access files: System Policy deny(1) file-read-data
 
 
Q