Notarised and Stapled App is not running Embedded Python Interpreter

Hi Apple community,

many thanks in advance for your help.

My macOS app embeds a Python interpreter, compiled from source, including the Python executable and its associated libraries. We have tried compiling the project with Xcode 16.0 and 16.1 beta 2 over MacOS Sequoia 15.0 and 15.1

This is how the project looks like:

SampleApp.app
SampleApp.app/Contents
SampleApp.app/Contents/MacOS
SampleApp.app/Contents/MacOS/SampleApp
SampleApp.app/Contents/MacOS/bin
SampleApp.app/Contents/MacOS/bin/python3.11
SampleApp.app/Contents/Resources
SampleApp.app/Contents/Resources/lib
SampleApp.app/Contents/Resources/lib/python3.11
SampleApp.app/Contents/Resources/Info.plist

Since we want to 'initially' distribute the app directly, Python binary is signed as follows:

codesign --deep --force --options runtime --timestamp --sign "$DEVELOPER_ID_APPLICATION" "$BINARY_PATH"

App entitlements contain the next entries:

<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.files.downloads.read-write</key>
<true/>
<key>com.apple.security.files.user-selected.read-only</key>
<true/>
<key>com.apple.security.files.user-selected.read-write</key>
<true/>
<key>com.apple.security.network.client</key>
<true/>
<key>com.apple.security.network.server</key>
<true/>

The resulting app is signed with entitlements, notarised and stapled. Once the app is running, we can see the next error on Console:

Prompting policy for hardened runtime; service: kTCCServiceAppleEvents requires entitlement com.apple.security.automation.apple-events but it is missing for accessing={TCCDProcess: identifier=[IDENTIFIER]], pid=58826, auid=502, euid=502, binary_path=[PATH]}, requesting={TCCDProcess: identifier=com.apple.appleeventsd, pid=824, auid=55, euid=55, binary_path=/System/Library/CoreServices/appleeventsd},

Python process is not running, we can't see any AMFI message.

Next we added to Signing and Capabilities 'Apple Events' from Hardened Runtime section. The resulting app gets signed, notarised and stapled, but when running we get only the next errors:

error	09:42:32.787744+0200	SampleApp	Can't find or decode reasons
error	09:42:32.787832+0200	SampleApp	Failed to get or decode unavailable reasons

Just in case it is relevant, this is how the app interacts with Python:

process.executableURL = URL(fileURLWithPath: [PATH_TO_PYTHON_BIN])
process.environment = environment
process.arguments = arguments
process.standardOutput = pipe            
try process.run()
process.waitUntilExit()

We truly appreciate any guidance, help or advice. Thanks!!

Answered by DTS Engineer in 808502022

I’m glad to hear you’re making progress.

This is the new entitlements:

I recommend that you remove com.apple.security.app-sandbox.

In general, you shouldn’t add an entitlement with a value that’s the default. In this case, App Sandbox defaults to off, so you should only add the com.apple.security.app-sandbox entitlement if you want to turn it on. Adding an entitlement with the value of false is going to cause more problems than it solves.

It appears a pop up asking 'Allow [APP] to find devices on local networks?'.

That’s almost certainly because your Python code is doing a local network operation. The correct fix for that is to stop it doing that (or accept the alert if you actually meant to do something on the local network).

For more on this, see the Local Network Privacy FAQ (I’m actively working on a full update of that for macOS, but it’s not done yet).

It’s a bit of a mystery as to why it doesn’t show up when you put the tool in Contents/MacOS/bin. I think LNP interprets this nesting as a bundle and thus treats bin/python3.11 as an app. Now, that app isn’t really an app, and so LNP gets confused.

Regardless, this isn’t the correct fix because it’s possible that a future LNP could get past this problem and end up prompting anyway. The correct fix is to either:

  • Stop accessing the local network.

  • Or, if you actually meant to access the local network, accept that and plan accordingly.

and all libraries (*.so, *.dylib and *.a) are signed as follows:

In most cases you don’t need to sign .a files. Indeed, in most cases you shouldn’t need to ship .a files. I talk about this in detail in this post, and doing so can cause problems. So, unless your third-party tooling requires these .a files to be present, I suggest you remove them.


I'm not sure if I can ask this in this thread, but I would love to distribute the app via the App Store. I already have a version available on TestFlight, but it's encountering errors when running python.

Right. Mac App Store apps must be sandboxed. Specifically:

  • Every executable in the app must be signed with the com.apple.security.app-sandbox entitlement.

  • Executables that you spawn — that is, run as a child process using posix_spawn or its equivalents — must also be signed with the com.apple.security.inherit entitlement.

I talk about this more in Embedding a command-line tool in a sandboxed app.

Share and Enjoy

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

There’s a lot to unpack here. Let’s start with the sandbox. Currently your entitlements enable the App Sandbox on your app. Why? You’re creating a Developer ID signed app, and thus distributing the app directly rather than in the Mac App Store. Developer ID apps don’t have to be sandboxed. So, are you enabling the sandbox because it’s the right thing to do? Or for some other reason?

Don’t get me wrong, enabling the sandbox is a good thing. However, it certainly does present extra complications.

Once I get an answer to this, I’ll have more to say about entitlements.


This is how the project looks like:

That’s going to cause problems. See Posting a Crash Report for advice on how to structure your bundle.


Python binary is signed as follows

Don’t use --deep. See Posting a Crash Report for an explanation as to why that’s problem. See Creating distribution-signed code for macOS for advice on how to sign code manually.


Finally, are you building the top-level app with Xcode? Or with other tools?

Share and Enjoy

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

Hello and thanks for your support,

Don’t get me wrong, enabling the sandbox is a good thing. However, it certainly does present extra complications

App Sandbox is not specially required by the app at this moment, if it makes things less complex it can be removed. It was there probably because I tried to distribute to AppStore at the same time.


That’s going to cause problems. See Posting a Crash Report for advice on how to structure your bundle.

I followed the link but can't find any information related to bundle structure. I followed this document Placing content in a bundle and because the interpreter is having an executable I placed it in MacOS folder.


Finally, are you building the top-level app with Xcode? Or with other tools?

Top level app is built with Xcode.

Thanks

App Sandbox is not specially required by the app at this moment

OK. Then I recommend that you disable it. You can always revisit that decision in the future.

Note that all the entitlements you listed in your original post are App Sandbox entitlements. However, if you distribute directly using Developer ID signing, you will need to enable the Hardened Runtime. It’s likely that your Python interpreter will need exception entitlements, so you can’t ignore entitlements entirely.

I followed the link but can't find any information related to bundle structure.

D’oh! I have similar Keyboard Maestro macros for Posting a Crash Report and Placing Content in a Bundle, and I typed the wrong one. Sorry about that. And I’m glad you found the right doc (-:

Top level app is built with Xcode.

OK. That’s important because it limits your wiggle room. If you’re manually signing things then you can bend the rules about where to place content in your bundle. It’s not ideal, but it does work. OTOH, Xcode is less tolerant of such things.

Earlier you wrote:

SampleApp.app
SampleApp.app/Contents
SampleApp.app/Contents/MacOS
SampleApp.app/Contents/MacOS/SampleApp
SampleApp.app/Contents/MacOS/bin
SampleApp.app/Contents/MacOS/bin/python3.11
SampleApp.app/Contents/Resources
SampleApp.app/Contents/Resources/lib
SampleApp.app/Contents/Resources/lib/python3.11
SampleApp.app/Contents/Resources/Info.plist

I’m presuming that bin/python3.11 is an executable. If so, get rid of the bin and you’ll be fine on that front.

What about lib/python3.11. That’s not a single file, right? It’s a directory containing a hierarchy of Python goo, right?

Share and Enjoy

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

Hello, I've made a very good progress. following the changes you indicated the app works :)

There is only a little detail, if python executable is moved to:

SampleApp.app/Contents/MacOS/python3.11

It appears a pop up asking 'Allow [APP] to find devices on local networks?'.

I tested the app placing python here:

SampleApp.app/Contents/MacOS/bin/python3.11

and the app works the same but the pop up is not appearing. This is a capability is not requested in the app... I'm very curious to know why this happens.

Let me share the changes that were applied:

This is the new entitlements:

<key>com.apple.security.app-sandbox</key>
<false/>

I enabled Hardened Runtime in Build Settings - Signing section.

What about lib/python3.11. That’s not a single file, right? It’s a directory containing a hierarchy of Python goo, right?

Yes, it is a folder with all the libraries, etc. Is it ok when the folder stays in Resources?

Last change I made is to remove the --deep when signing python executable, now it looks like this:

codesign --force --options runtime --timestamp --sign "$DEVELOPER_ID_APPLICATION" "$BINARY_PATH"

and all libraries (*.so, *.dylib and *.a) are signed as follows:

codesign --force --preserve-metadata=identifier,entitlements,flags --timestamp=none --sign "$DEVELOPER_ID_APPLICATION" "$BINARY_PATH"

We tested the notarised dmg in different macs and works perfect, I'm so thankful :)

I'm not sure if I can ask this in this thread, but I would love to distribute the app via the App Store. I already have a version available on TestFlight, but it's encountering errors when running python. Before I open a new thread I would like to review the proper documentation. Could you recommend any link, advice, or tips? I already visited this post and the links are appearing on it: XPC Rendezvous, com.apple.security.inherit and LaunchAgent

Many thanks in advance!

Accepted Answer

I’m glad to hear you’re making progress.

This is the new entitlements:

I recommend that you remove com.apple.security.app-sandbox.

In general, you shouldn’t add an entitlement with a value that’s the default. In this case, App Sandbox defaults to off, so you should only add the com.apple.security.app-sandbox entitlement if you want to turn it on. Adding an entitlement with the value of false is going to cause more problems than it solves.

It appears a pop up asking 'Allow [APP] to find devices on local networks?'.

That’s almost certainly because your Python code is doing a local network operation. The correct fix for that is to stop it doing that (or accept the alert if you actually meant to do something on the local network).

For more on this, see the Local Network Privacy FAQ (I’m actively working on a full update of that for macOS, but it’s not done yet).

It’s a bit of a mystery as to why it doesn’t show up when you put the tool in Contents/MacOS/bin. I think LNP interprets this nesting as a bundle and thus treats bin/python3.11 as an app. Now, that app isn’t really an app, and so LNP gets confused.

Regardless, this isn’t the correct fix because it’s possible that a future LNP could get past this problem and end up prompting anyway. The correct fix is to either:

  • Stop accessing the local network.

  • Or, if you actually meant to access the local network, accept that and plan accordingly.

and all libraries (*.so, *.dylib and *.a) are signed as follows:

In most cases you don’t need to sign .a files. Indeed, in most cases you shouldn’t need to ship .a files. I talk about this in detail in this post, and doing so can cause problems. So, unless your third-party tooling requires these .a files to be present, I suggest you remove them.


I'm not sure if I can ask this in this thread, but I would love to distribute the app via the App Store. I already have a version available on TestFlight, but it's encountering errors when running python.

Right. Mac App Store apps must be sandboxed. Specifically:

  • Every executable in the app must be signed with the com.apple.security.app-sandbox entitlement.

  • Executables that you spawn — that is, run as a child process using posix_spawn or its equivalents — must also be signed with the com.apple.security.inherit entitlement.

I talk about this more in Embedding a command-line tool in a sandboxed app.

Share and Enjoy

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

Notarised and Stapled App is not running Embedded Python Interpreter
 
 
Q