How to pass Gatekeeper checking when bundling an installer package inside the Mac application?

Hi everyone,

Since macOS 12.3+ removed built-in Python, I try to bundle the official Python installer package (.pkg) in our Mac Application (.app). Therefore the user can install Python directly in the application to make one of our app functions correctly.

However, this application cannot be opened because macOS cannot verify that this app is free from malware. This issue happened on macOS 12.4, but it can be opened without any error messages on macOS 10.14.6.

When bundling the package, I did re-sign it using our developer ID certificate, And the app also passes the notarization process. Then I checked the following utilities on macOS 12.4 and all of them are correct. Please help me to solve this issue. Thank you very much.

Checking the Gatekeeper:

spctl -a -t exec -vvv --ignore-cache Spark.app

Spark.app: accepted
source=Notarized Developer ID
origin=Developer ID Application: *** Inc (SKLFZ4533Y)

Checking the signature of application:

codesign -vvv --check-notarization --deep Spark.app

--prepared:/Users/oz-chc/Downloads/Spark.app/Contents/Helpers/python.pkg
--validated:/Users/oz-chc/Downloads/Spark.app/Contents/Helpers/python.pkg
Spark.app: valid on disk
Spark.app: satisfies its Designated Requirement

Checking the signature of Python package after re-sign and bundle it. (I marked the fingerprint)

pkgutil --check-signature Spark.app/Contents/Helpers/python.pkg

Package "python.pkg":
   Status: signed by a developer certificate issued by Apple for distribution
   Notarization: trusted by the Apple notary service
   Signed with a trusted timestamp on: 2022-08-25 03:07:00 +0000
   Certificate Chain:
    1. Developer ID Installer: *** Inc (SKLFZ4533Y)
       Expires: 2024-10-25 04:12:29 +0000
       SHA256 Fingerprint:
           ******
       ------------------------------------------------------------------------
    2. Developer ID Certification Authority
       Expires: 2027-02-01 22:12:15 +0000
       SHA256 Fingerprint:
           ******
       ------------------------------------------------------------------------
    3. Apple Root CA
       Expires: 2035-02-09 21:40:36 +0000
       SHA256 Fingerprint:
           ******

Are you sure that this is directly related to the Python installer package? If you temporarily remove that package, then run through the signing and notarisation process, does your app pass Gatekeeper?

I realise that your app may not function correctly in that case, but the only goal of this test is to see whether it passes Gatekeeper.

FYI, I generally try to avoid using commands like spctl and codesign to check for Gatekeeper compliance. Rather, I use the process described in Testing a Notarised Product.

Share and Enjoy

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

Hi Eskimo,

Thanks for your quick reply.

I had built the app which just removing the Python installer package. The app can be opened directly (only asking for permission that download from the Internet) and be able to show the GUI well. So I think the installer package results in this issue.

About the testing, it might take me a while to set up a VM, but I'll try. At least I did try to download the app again from Safari, then turn off Wi-Fi. The app shows the same alert message complaining that Apple cannot verify that this app is free from malware. I also open the system log (console -> Mac Analytics Data) when double-clicking the app, the log show a new one which says "assessment granted for .app by Notarized Developer ID". This is weird that real situation does not match with the log...

Are there any things I can do to gather more information about why macOS cannot let me open the app directly? Thanks for your help.

Are there any things I can do to gather more information about why macOS cannot let me open the app directly?

Debugging Gatekeeper problem can be quite challenging. I have a whole bunch of info about this in posts hung off Resolving Trusted Execution Problems.

In your first post you wrote:

I try to bundle the official Python installer package

I’d like to see how that package is signed. Can you post its URL?

If DevForums gets snarky about the URL, see tip #14 in Quinn’s Top Ten DevForums Tips.

Share and Enjoy

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

Thank you. I will study the post about Resolving Trusted Execution Problems and try to get more information.

About the Python 2.7.18 installer package, I downloaded the macOS 64-bit installer from the Python website.

https://www.python.org/downloads/release/python-2718/

Then I re-sign it using the following command using our certificate same as the app (except for the Developer ID Installer rather than the Developer ID Application)

productsign --sign "Developer ID Installer: XXX (SKLFZ4533Y)" "unsigned-python-2.7.18.pkg" "python-2.7.18.pkg"

The signature checking result can be seen in my original post.

Well, that’s interesting. The python-2.7.18-macosx10.9.pkg installer package isn’t signed at all, so you’ll definitely have to sign it. The code inside the package is Developer ID signed [1]. That in itself isn’t a problem. The notary service and Gatekeeper require that stuff be Developer ID signed, but they’ll accept any valid Developer ID, even a mix of them.

At this point I’m not sure why Gatekeeper is rejecting your app and I don’t have time here on DevForums to explore this further. If the suggestions from Resolving Trusted Execution Problems don’t turn up anything, I recommend that you open a DTS tech support incident, which will allow me to allocate the time to dig into this properly.

Share and Enjoy

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

[1] By Developer ID Application: Ned Deily (DJ3H93M7VJ)! I was surprised to see that there’s no official Python organisation signing identity involved here.

I removed the com.apple.quarantine attribute by calling xattr -c Spark.app. Then the app can be opened without any alert messages. I think this means that the Gatekeeper did block my app for some reasons.

I built, sign, and notarize the app on an old macOS 10.15.6. I don't know if this will be a problem.

Anyway, I've requested the code-level technical support and provided the application for further investigation. Thank you.

Then the app can be opened without any alert messages. I think this means that the Gatekeeper did block my app for some reasons.

Yes. On currently shipping systems Gatekeeper only checks things that are quarantined [1].

I built, sign, and notarize the app on an old macOS 10.15.6.

Probably not. You can get into trouble if you sign code with very old systems but AFAIK there have been no inflexion points since macOS 10.15 [2].

I've requested the code-level technical support

Cool. I’ll see you on the flipside.

Share and Enjoy

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

[1] This has changed in macOS 13 beta though. If you’re curious, see the WWDC video I linked to in Trusted Execution Resources.

[2] This is not true for iOS btw. See Using the Latest Code Signature Format.

Accepted Answer

Thanks for Eskimo's professional help via the support ticket, this problem got fixed. 😃 Here are the root cause and solution. Hope this information can help people who are bothered by similar issue.

The real problem is that I placed the Python installer package (.pkg) file in Contents/Helpers of the app bundle, which is a location reserved for code rather than data. So code signing tool has signed it in a wrong way, which causing Gatekeeper think the app's signing is wrong and refused the app to be opened.

The fix is simple. I just relocate the inappropriate items in Contents/Helpers, specifically place the installer package along with other data files in Contents/Resources. Rebuild the app. Done! The new app is now able to pass Gatekeeper checking on macOS 12.3, 12.4, and even 12.5.

Reference documents in detail:

Inside Code Signing: Hashes

Placing Content in a Bundle

If you put content in the wrong location, you may encounter hard-to-debug code signing and distribution problems.

How to pass Gatekeeper checking when bundling an installer package inside the Mac application?
 
 
Q