Notarizing a DMG bundling a complete Perl environment

...and some more simple command line utilities. I've code signed all executables and binary libraries I could find. This has got rid of most errors already.

Now I'm struggling with the "hardened runtime" requirements. I understand I can somehow add entitlements - but have no clue how to do that, and what to add. Somewhere there was reference to PCRE - I don't think Perl uses that itself, but certainly does deal with regexes a lot. How would I add eg. the JIT entitlement (if that was required)? Most documents refer to .mobileprovision files or similar - but I'm dealing with a desktop application.

And as all of this is rather non-standard, we don't use Xcode at all. So I wouldn't even know how to use Xcode to create a profile for an an app which is managed completely "outside" of a normal macOS development environment.

Answered by mherger in 814057022

From https://developer.apple.com/documentation/xcode/embedding-nonstandard-code-structures-in-a-bundle:

In some cases you need to work with nonstandard code structures, that is, code whose structure doesn’t match the standard bundle structure for your platform. For example, you might be building a Mac app and want to embed an open source language runtime in it.

Yep, that's me 🙈.

Building a notarized Perl app on a Mac using the command line? You're kind of fighting the whole world at once there, eh? 😄

In addition to the hardened runtime, you'll need some entitlements to relax said hardened runtime. Put those in an XML file and use the "--entitlements" flag with "codesign".

Make sure to completely test your installation with all kinds of funky edge cases. In addition to all the up-front notarization checks, there are certain checks that happen only at runtime, or only at runtime when you try to trigger something like dynamic loading or JIT execution. That is the part that trips up most people in your situation who get that far.

I don't know which entitlements Perl will require - most likely all of them.

It’s better if you reply as a reply rather than in the comments; see Quinn’s Top Ten DevForums Tips for this and more.

Where would I find the documentation for that XML file?

The XML file is a property list. When working with a property list, use a tool rather than editing it by hand. Or, at a minimum, edit it by hand and then use plutil to convert it to the standard format.

I generally use plutil but, if you need more flexibility, check out PlistBuddy. Both are installed by default and have man pages.

The property list keys relevant to the hardened runtime are documented on the Hardened Runtime page.

The exact keys and values you need depend on what your code is doing. If your JIT code is up-to-date, you should be able to get away with just com.apple.security.cs.allow-jit. If not, fall back to com.apple.security.cs.allow-unsigned-executable-memory [1].

For general advice on signing and packaging Mac products, see:

I think you might be better off shipping an installer package rather than a disk image. That’ll let you install your tools at a fixed path, so something in /usr/local/nnn, where nnn is your company or product name. Unix-y tools tend to like fixed paths like this. If you let the user install your tools anywhere, you need to deal with executable-relative library references. I talk about this issue in more detail in Dynamic Library Identification.

Share and Enjoy

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

[1] You can fall back further to com.apple.security.cs.disable-executable-page-protection, but that’s unlikely to be helpful. On Apple silicon at least, it’s equivalent to com.apple.security.cs.allow-unsigned-executable-memory.

Thanks @DTS Engineer for your response and links. I used plutil to validate my entitlements file. And it said OK.

But as @Etresoft suggested I ended up adding more and more flags, until I had added about every flag I could find (eg. from https://developer.apple.com/documentation/security/hardened-runtime). Alas, it didn't help.

I think what I'm struggling with is https://developer.apple.com/documentation/xcode/embedding-nonstandard-code-structures-in-a-bundle. I'll have to give that a closer look. All my Perl modules and helper binaries certainly aren't in standard locations.

Accepted Answer

From https://developer.apple.com/documentation/xcode/embedding-nonstandard-code-structures-in-a-bundle:

In some cases you need to work with nonstandard code structures, that is, code whose structure doesn’t match the standard bundle structure for your platform. For example, you might be building a Mac app and want to embed an open source language runtime in it.

Yep, that's me 🙈.

YES!

Waiting for processing to complete.
Current status: Accepted.................
Processing complete
  id: 9999999-b078-4a91-8a55-9999999
  status: Accepted

The issue in my case were the binaries sprinkled across all of the package. After I moved everything to Contents/MacOS as outlined in the above link the notarization is now succeeding. Thanks for your pointers, @DTS Engineer!

Notarizing a DMG bundling a complete Perl environment
 
 
Q