Unable to Write Files Within App Bundle After Codesigning and Notarization

Codesigned and notarized app cannot directly write files inside the app bundle (neither in my.app/Contents/Resources/ nor my.app/Contents/MacOS/). Are there any restrictions regarding this? Is there a way to bypass these restrictions?

Here is the situation I encountered:

The main app contains several sub-apps and sub-executables. When the main app calls the sub-apps or sub-executables, it can write files within the app bundle, but when executed directly, it cannot write files. The app is usually opened using the GUI, and when using the command line, neither the main app nor the sub-apps/sub-executables can write files within the app bundle.

My codesigning environment is:

  • Sonoma 14.0 on mac mini M1.
  • I manually sign the app directly using the codesign command in CI instead of using Xcode. The process will traverse all of the files and sub-apps in the app folder and sign them from the deepest paths to the shallowest paths. I also tried applying this process to other applications, but all of them encountered the same issue of failing to write files.
  • The app should not be sandboxed (I did not add sandbox entitlements).

I have tried adding the entitlement com.apple.security.files.user-selected.read-write, but this has not resolved the issue.

Accepted Answer
Are there any restrictions regarding this?

Yes.

Is there a way to bypass these restrictions?

No.

App bundles are read-only by design. This isn’t a new requirement [1], but recent changes in macOS’s trusted execution system mean that it’s more important to follow the rules. To quote Embedding nonstandard code structures in a bundle:

A bundle is a read-only structure. All Apple platforms except the Mac enforce this requirement at runtime. On iOS, for example, any attempt to modify your app’s bundle at runtime will fail with an error. The Mac may or may not enforce this requirement at runtime, depending on the context, but modifying your app’s bundle isn’t supported because it breaks the seal on the app’s code signature.

So your current goal, having the app modify itself, is unsupported, likely to cause problems today, and even more likely to cause problems in the future.

If you can explain more about why you’re trying to modify your own app, I may be able to offer an alternative path forward.


I manually sign the app directly using the codesign command in CI instead of using Xcode.

Based on your description it sounds like you’re doing the right thing here, but I’d be remiss not to mention Creating distribution-signed code for macOS, which contains detailed instructions on how to sign Mac products.

Share and Enjoy

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

[1] Indeed, you can trace it all the way back to the mid 80s. See here.

Dear Engineer,

Thanks for your information.

Actually, We use Qt to develop an application on the macOS platform, and we are attempting to perform code signing and notarization to ensure our the application is trusted by Apple.

However, there are a few things that seem weird regarding your statement: "App bundles are read-only by design." Let me provide more details for your reference.


Currently, when our application starts, it needs to create folder (e.g. Temp) in the root directory of the executable

For example: Myapp.app/Contents/MacOS/Myapp ---> Myapp.app/Contents/MacOS/Temp

The folder is designed for storing runtime logs or config files for our application. In the past, users may also modify the settings inside target folder if needed.

However, the strange thing is that after the application is codesigned and notarized.

When we double-click the application Myapp (a.k.a Myapp.app) in Finder, it could successfully launch and create the Temp folder inside the Myapp.app/Contents/MacOS folder.

However, when we navigate and attempt to run the main application executable in command line mode (as our application supports this command line execution)

$ cd Myapp.app/Contents/MacOS
$ ./Myapp -h

As our application will check if the root folder has write permission before starting (i.e., check if Myapp.app/Contents/MacOS is writable because we require to create Temp folder in the following steps)

It pop up the error that folder does not have write permission.

The aforementioned scenarios seems to conflict with your statement: "App bundles are read-only by design" (because when the application is launched directly by clicking in Finder, the Temp folder can be created successfully, but via the console command line, it cannot).


I would like to confirm again if writing files in the notarized application MacOS directory is not allowed?

If not, do you have any recommended approaches? (e.g., changing the folder to another directory). What causes the different results in these running scenarios?

We are not concerned about breaking the signature after application launched, as it seems that macOS will add it to system trust list after first time successfully launch. (Download the app from internet --> System: it is an app downloaded from the internet. Are you sure want to open it...? OK --> Although our application creates the Temp folder after first launch, when we click the application second time, it could directly open the app)

Thanks

Dear @DTS Engineer , I still have questions I would like to ask you, please see the reply below, thank you.

Unable to Write Files Within App Bundle After Codesigning and Notarization
 
 
Q