Can't Run Embedded Pre-Compiled AOT Binary Code-signed with Hardened Runtime from App Bundle

I've got a macOS app (.app) bundle where I am trying to embed a pre-compiled ahead-of-time binary (cli application) into my app bundle but cannot get it to execute when hardened runtime is enabled.

I've got a run-script in Builds Phases in xcode (14.1) that looks like this

LOCATION="${BUILT_PRODUCTS_DIR}"/"MyApp.app/Contents/MacOS"
IDENTITY=${EXPANDED_CODE_SIGN_IDENTITY_NAME}

codesign --verbose --force -o runtime --sign "$IDENTITY" "$LOCATION/my_cli"

The binary is succesfully copied and placed as MyApp/Contents/MacOS/my_cli right along side the main executable binary for the app.

The main application is written in Dart with Flutter, while the binary (my_cli) is compiled through a combination of Rust and Dart to a single file executable.

I can successfully run my_cli when I omit the -o runtime from my main application using Dart:io Process.run (think of it as a means to execute a program, similar to Swift's Process.run), but this will fail Apple's Notary Service saying that my_cli needs to have been signed with hardened runtime.

I have tried putting the binary in multiple locations, including MyApp.App/Contents/Helpers and MyApp.App/Contents/Resources but still no luck.

The binary, my_cli, simply generates a .dylib within the Users/<user_name>/Library/Application Support/<bundle_id>/ for architecture specific optimizations, hence why it must be AOT.

The only hint I get comes from console.app which spits out something like this

Error reading receipt: Error Domain=NSCocoaErrorDomain Code=256 "The file “receipt” couldn’t be opened." UserInfo={NSFilePath=/Users/<user_name>/MyApp/build/macos/Build/Products/Debug/MyApp.app/Contents/MacOS/my_cli/Contents/_MASReceipt/receipt, NSUnderlyingError=0x7fc04960a7c0 {Error Domain=NSPOSIXErrorDomain Code=20 "Not a directory"}}

I find it strange that macOS thinks that my_cli is an app bundle or something. I still get this error even when I don't code-sign with the -o runtime flag so I am not necessarily sure it is relevant to the problem.

For some context, I have already created a cli application written in pure Dart and have embedded it within the app and code-signed with the -o runtime flag and it works great, but I have noticed that it only works successfully when I build it on my own machine rather when it gets built through a CI/CD service like Github actions. I will have to confirm this for my_cli but the source is currently broken and I am not involved in it. I will update this post if I get it to work when built on my machine. Regardless, I still want to know why it fails to execute when I pull it from our CI/CD runners.

I am aware of the quarantine flag that macOS will put on executables when downloaded from a browser, but I have already removed them and circumvented that problem by pulling through wget or curl (running xattr my_cli will come back with nothing listed).

MyApp is currently not sandboxed, but I have tried to add entitlements like

	<key>com.apple.security.cs.disable-executable-page-protection</key>
	<true/>
	<key>com.apple.security.cs.allow-jit</key>
	<true/>
	<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
	<true/>
	<key>com.apple.security.cs.disable-library-validation</key>
	<true/>

which I am pretty sure don't matter hence being un-sandboxed. The same boxes are checked in Xcode when you click on the "Signing and Capabilities` tab under the Hardened Runtime capability

I am running out of ideas here. If anyone has any information or a solution, it would be much appreciated.

Thanks in Advance!

You don’t need a custom code signing build phase to do this. Xcode can take care of this for you. For information on how to do that, see Embed an externally built tool in Embedding a command-line tool in a sandboxed app.

Note That article assumes that the container app is sandboxed, and yours isn’t, but the non-sandboxed case is significantly easier than the sandboxed case.

I have tried putting the binary in multiple locations

Placing Content in a Bundle has specific advice about that.

Share and Enjoy

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

Can't Run Embedded Pre-Compiled AOT Binary Code-signed with Hardened Runtime from App Bundle
 
 
Q