Notarized, Developer ID-signed App for Direct Distribution Won't Run (Wants App Store Sign-In, Then Says Damaged)

Hi all,

I'm attempting to distribute a notarized expiring demo variant of my Mac App Store app (TypeMetal) directly to potential customers as a download on our website, using the procedure documented here:

https://developer.apple.com/documentation/security/notarizing_macos_software_before_distribution

I successfully complete the 9 steps listed in "Notarize Your App Automatically as Part of the Distribution Process", including choosing "Developer ID (Distribute directly to customers)" and "Upload (Send to Apple notary service)", and successfully download the resultant .app bundle, but I'm unable to run the app. It looks to me as if the system is attempting to obtain an App Store receipt for the app, when what I want is for this variant of the app to be treated as distinct from the purchased Mac App Store version, and be runnable without purchase.

I have tried changing the app's bundle identifier and removing the LSApplicationCategoryType (in the Xcode target's settings, before building), but neither seems to affect these results. I'm left wondering how the system is determining that this is an .app that requires App Store sign-in/receipt-checking.

When I copy the downloaded, notarized .app to a different macOS user account, log in as that user, and attempt to launch it there, the system presents a panel, prompting for the user to sign in with their Apple ID:

When I attempt to launch the app in my own user account (the one I build and develop in), the system presents the same prompt in a slightly different form:

Whether or not I provide a valid Apple ID sign-in in either case, the launched app then terminates with a fatal alert. (Same result in a separate user account as in my own development account.)

I would like for the distributed app to be runnable by customers without requiring an App Store receipt. I have verified that my own App Store receipt-checking code is being omitted, as I intend, from the build I that submit for notarization. Is there something I need to do differently to make this work?

The notarized app has passed the checks described here:

Resolving Common Notarization Issues https://developer.apple.com/documentation/security/notarizing_macos_software_before_distribution/resolving_common_notarization_issues#3087721

I can provide the outputs of the codesign and spctl checks recommended on that page, if that would be helpful. The .app contains one embedded framework (OpenSSL.framework) and one command-line executable (tidy), but I believe they are correctly code-signed. I'm testing this on a 2020 M1 MacBook Air running macOS 12.3.1 (21E258), using Xcode 13.3.1 (13E500a) to do the build, upload for notarization, and export of the notarized result.

Thanks very much in advance for any insight you can offer.

Troy Stephens
Coherence Labs, LLC

I am going to address the Gatekeeper failure that you are receiving here. Based on the System Alert that you are receiving, possibly your app is not Notarized at all or the Notary ticket has become damaged or corrupted. A few things to check here:

  1. Do you have an internet connection to fetch the Notary ticket? If not, do you have one stapled to your app?
# Staple Notary ticket to your app.
$ xcrun stapler validate yourApp.app
  1. Is your Mac allowed to run apps that are not downloaded from the Mac App Store? See here for more information.

  2. If 1 or 2 do not provide you any information, you may want to check the Console.app when your app is opened for the first time on a Mac. This should either provide syspolicyd information or GateKeeper information:

$ log stream --level debug --predicate 'process == "syspolicyd"'
  1. If there is a signature or obvious Notary failure, please post the output for:
# General Signature
$ codesign -dvvvvv yourApp.app

# Tests the Notarized requirement in the signature
$ codesign --test-requirement="=notarized" --verify --verbose yourApp.app

# Check and verify the contents of your app.
$ codesign --verify --deep --strict --verbose=2 yourApp.app
Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com

Thank you for the detailed suggestions, Matt!

My Mac is indeed configured to "Allow apps downloaded from: App Store and identified developers", and my exported, notarized .app build appears to pass all of the suggested checks (output below). I'm uploading the app build to Apple's notarization service, letting subsequent export of the notarized app build archive from Xcode do the stapling for me as described in "Notarize Your App Automatically as Part of the Distribution Process" here: https://developer.apple.com/documentation/security/notarizing_macos_software_before_distribution

The syspolicyd log output from launch of the exported, notarized .app is lengthy. The only clearly suspicious things I see in it are errors like this one. I don't know whether they're alarming or normal:

syspolicyd: (Security) [com.apple.securityd:cfloadfile] failed to fetch /Users/troy/Desktop/TypeMetal.app/Contents/_CodeSignature/CodeRequirements-2 error=-10

I see these mentions of "MASReceipt" and wonder if they indicate anything about the intent to receipt-check the app as a condition for being able to run it:

syspolicyd: (Security) [com.apple.securityd:csresource] 0x161147db0 rule ^_MASReceipt$ added (weight 0, flags 0x10)
...
syspolicyd: (Security) [com.apple.securityd:rscan] try ^_MASReceipt$

Here are the outputs for the suggested diagnostics (hashes and team ID redacted in case I shouldn't post that stuff):

[21E258 ascent:~/Desktop] troy% xcrun stapler validate TypeMetal.app 
Processing: /Users/troy/Desktop/TypeMetal.app
The validate action worked!

[21E258 ascent:~/Desktop] troy% codesign -dvvvv TypeMetal.app 
Executable=/Users/troy/Desktop/TypeMetal.app/Contents/MacOS/TypeMetal
Identifier=com.CoherenceLabs.TypeMetalDemo
Format=app bundle with Mach-O universal (x86_64 arm64)
CodeDirectory v=20500 size=23915 flags=0x10000(runtime) hashes=736+7 location=embedded
VersionPlatform=1
VersionMin=720896
VersionSDK=787200
Hash type=sha256 size=32
CandidateCDHash sha1=(40 hex digits)
CandidateCDHashFull sha1=(same 40 hex digits)
CandidateCDHash sha256=(40 hex digits)
CandidateCDHashFull sha256=(64 hex digits)
Hash choices=sha1,sha256
CMSDigest=(64 hex digits)
CMSDigestType=2
Executable Segment base=0
Executable Segment limit=2310144
Executable Segment flags=0x1
Page size=4096
CDHash=(same 40 hex digits as "CandidateCDHash sha256")
Signature size=9069
Authority=Developer ID Application: Coherence Labs, LLC ([MYTEAMIDENTIFIER])
Authority=Developer ID Certification Authority
Authority=Apple Root CA
Timestamp=May 5, 2022 at 11:19:57 AM
Info.plist entries=30
TeamIdentifier=[MYTEAMIDENTIFIER]
Runtime Version=12.3.0
Sealed Resources version=2 rules=13 files=498
Internal requirements count=1 size=224

[21E258 ascent:~/Desktop] troy% codesign --test-requirement="=notarized" --verify --verbose TypeMetal.app 
TypeMetal.app: valid on disk
TypeMetal.app: satisfies its Designated Requirement
TypeMetal.app: explicit requirement satisfied

[21E258 ascent:~/Desktop] troy% codesign --verify --deep --strict --verbose=2 TypeMetal.app 
--prepared:/Users/troy/Desktop/TypeMetal.app/Contents/Frameworks/OpenSSL.framework/Versions/Current/.
--validated:/Users/troy/Desktop/TypeMetal.app/Contents/Frameworks/OpenSSL.framework/Versions/Current/.
TypeMetal.app: valid on disk
TypeMetal.app: satisfies its Designated Requirement

Is there something else I can try? Do you need more of the syspolicyd log output?

Thanks!
Troy

The only clearly suspicious things I see in it are errors like this one. I don't know whether they're alarming or normal:

Normal-ish.

Regarding:

I see these mentions of "MASReceipt" and wonder if they indicate anything about the intent to receipt-check the app as a condition for being able to run it: syspolicyd: (Security) [com.apple.securityd:csresource] 0x161147db0 rule ^_MASReceipt$ added (weight 0, flags 0x10) syspolicyd: (Security) [com.apple.securityd:rscan] try ^_MASReceipt$

This suggests that there is App Store Receipt validation code lying around still. I would test this on a clean machine, like a VM, and if you're still seeing this issue then it's likely that your app has forgotten to disable your receipt validation code.

Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com

In reviewing the second and third screenshot, the second alerts asking the user to sign in typically occurs when a macOS StoreKit app calls exit(173). This step normally occurs when the app checks for the presence of the appStoreReceiptURL and finds that it's nil. In the past, the recommendation has been for a macOS app to call exit (173). The third alert typically occurs after authenticating the user password request, then the StoreKit process is unable to find a matching record for the applications bundle identifier in the AppStoreConnect records. Normally if a matching app bundle identifier is found, the App Store Server generates an appStoreReceipt and installs it to the app. The app is relaunched, and this time the app detects the presence of the receipt. In case that there was no AppStoreConnect app match was found, the appStoreReceiptURL remains nil, the app again makes the exit (173) call. But this time the Finder detects the second attempt by the app and raises the alert.

You indicate that there is no need for an appStoreReceipt on startup - "I would like for the distributed app to be runnable by customers without requiring an App Store receipt." as such, if there is no appStoreReceipt, then don't make the exit (173) call.

If the app needs to validate the appStoreReceipt following a successful transaction, it can do so when the .purchased transactionState is returned to the updatedTransactions delegate. If the desire is to use receipt validation as a means to validate the app, the App Attest mechanism is the preferred means to do so.

rich kubota developer technical support CoreOS/Hardware/MFI

Thank you so much, Matt and Rich! Much to my surprise, it does appear that my own receipt-checking code is active and is causing the problem. I have a "Demo" build configuration in my Xcode project, that sits as a peer to the standard "Debug" and "Release" and defines the necessary preprocessor macro to omit the receipt-checking code, and that all works fine when I build and run my "TypeMetalDemo" build scheme that's set up to use that "Demo" configuration, but I gather the "Product" -> "Archive" command doesn't end up using that configuration (despite the "TypeMetalDemo" scheme being the selected scheme when I run the "Archive" command), and that appears to be where I went wrong. I need to figure out how to get the "Archive" command to build using my "Demo" configuration, if that is possible.

Notarized, Developer ID-signed App for Direct Distribution Won't Run (Wants App Store Sign-In, Then Says Damaged)
 
 
Q