xcframework notarization

For testing I moved our "universal" (iOS, macOS, tvOS, watchOS) xcframework from one Mac to another for testing, and encountered this issue when testing the macOS slice:

not valid for use in process using Library Validation: library load disallowed by system policy

and

“X.framework” can’t be opened because Apple cannot check it for malicious software.

This software needs to be updated. Contact the developer for more information.

It appears that the xcframework needs to be notarized. However, the WWDC on notarization talks about enabling Hardened Runtime. Our xcframework projects don't seem to have Hardened Runtime as an option. Is it not needed?

And what roughly is the process of notarizing an xcframework? If I take all I've listened to about notarization from WWDC videos (keeping in mind the term xcframework I did not hear occur once) it sounds like I should be zip archiving the xcframework using ditto with some special parameters, sending it off to get notarized, and then stapling the result to the original xcframework. Is that essentially correct? Is there more documentation on notarization of xcframeworks somewhere?

Our xcframework projects don't seem to have Hardened Runtime as an option. Is it not needed?

The hardened runtime flag is only relevant for a main executable. Both the notary service and macOS ignore that flag on library code.

And what roughly is the process of notarizing an xcframework?

Put it in a container (a zip archive is fine but you can use any support container format) and submit that to the notary service. For general guidelines on this, see Signing a Mac Product For Distribution.

Having said that, I don’t think you need to notarise an XCFramework. Ultimately your framework is going to be incorporated into a final product and it’s this product that must be notarised.

encountered this issue when testing the macOS slice

Was that raised during the build? Or during the execution?

Share and Enjoy

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

So, what’s happening here is that AirDrop quarantines the framework which means that Gatekeeper examines in when the client process tries to load it. This normally isn’t an issue because a macOS app embeds a copy of the framework and that embedding process should both drop the quarantine and re-sign the code. At that point Gatekeeper will no longer examine the code until it’s quarantined again when the user downloads it, at which point the client app’s author is expected to have notarised the whole app, and the resulting ticket covers both the app and the framework.

How you proceed here depends on your goals:

  • If you’re only hitting this as part of your internal build and test process, the easiest option is to remove quarantine from framework after you transfer it.

  • If you ship the framework to a wide range of users, as part of an SDK perhaps, then you should notarise your SDK and the resulting ticket will include your framework.

Share and Enjoy

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

It sounds like you're saying that notarization is not needed in this case then. Is that correct?

In most cases [1] Gatekeeper only runs if the item is quarantined. If you’re transferring code that you trust via a channel that you trust, manually removing quarantine is fine.

It also sounds as though you're saying that AirDrop specifically created this issue.

AirDrop quarantines the files you receive, for fairly obvious security reasons.

Can this issue be bypassed today by transferring the xcframework by using a means other than AirDrop, such as using a thumb drive or copying over the network to a shared drive?

Yes. Or by removing the quarantine at the destination.

Most folks in your situation use scp for this sort of thing, and it does not set quarantine. That’s because scp is an expert-level tool while AirDrop is aimed at normal users. If you’re using scp, you’re expected to know enough not to transfer and then run untrusted code. If you’re using AirDrop, the system tries to keep you safe.

Share and Enjoy

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

[1] There are some high-security cases, like KEXTS, where Gatekeeper runs more frequently.

How can I staple a ticket to xcframework that I got notarized?

Our general advice is that you notarise and staple your outermost container. So, if your XCFramework is on a disk image, notarise and then staple that disk image.

The only edge case here is a zip archive, which you can notarise but can’t staple. If that bothers you, switch to a different container (disk image or installer package).

Not that in many cases stapling isn’t important. It’s relevant if the user downloads your product, then goes offline, then tries to use it for the first time while offline. If the user is online when they first use your product then the lack of a stapled ticket isn’t a problem because the system will fetch it from Apple directly.

ps You can find a lot of hints and tips about this stuff in my Signing a Mac Product For Distribution post.

Share and Enjoy

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

xcframework notarization
 
 
Q