I just read about the notarization functions in the next Mojave.
( https://www.macrumors.com/2019/04/08/mac-apps-notarization-macos-10-14-5/ ). I am already annoyed by having to code sign my AppleScript apps that automate things for my customers. If I find a error in my code, or just want to update it for some very good reason, it appears I have to bring it back to my computer to do the changes, then save it with signing, then send it back to the user’s computer, and so on.
Will I now have to send it to Apple as well?
Do you folks understand the ramifications of these changes?
TIA
Lenny
The announcement presumably means what it says: signed apps will have to be notiarized. Just how that will be handled for scripts is not yet entirely clear.
Well, it seems that I can’t notarize an applet. Apple’s service gives me this error message:
The executable does not have the hardened runtime enabled.
I suspect you can do but at this stage you will have to sign the applet manually. You will need to specify the runtime
option flag, as well as creating an entitlement property list file and passing its path to the --entitlement
option. I suspect the only entitlement you will need is com.apple.security.automation.apple-events
. And you will probably also need the --timestamp
option.
I’m guessing an entitlement file like this should be enough to give scripting plus loading external frameworks:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.automation.apple-events</key>
<true/>
<key>com.apple.security.cs.disable-library-validation</key>
<true/>
</dict>
</plist>
At least, that’s the theory. Post back and let us know how it goes.
Hi Shane,
thanks for your answer. After some trying it went well. Here is what I’ve done:
- I signed the applet:
xattr -rc APPLET.app
codesign -f --deep --options=runtime --timestamp --entitlements Entitlements.plist -s MACDEVID -v APPLET.app
- I created a signed disk image (with DMG Canvas) for the applet (maybe not necessary).
- Sent the disk image to Apple’s notarization service:
xcrun altool --notarize-app --primary-bundle-id "COM.NOTARIZATION.ID" --username "your@mail.tld" --password "@keychain:AC_PASSWORD" --file DISKIMAGE.dmg
- After successful notarization (checked with the Notarize app) I included the notarization ticket into my disk image:
xcrun stapler staple DISKIMAGE.dmg
Informations about notarization and how to fill the keychain can be found here: Customizing the Notarization Workflow | Apple Developer Documentation
Here’s an excellent step-through from someone initially facing the same thing with Automator-build apps.
I’m curious how it worked without an entitlements file, but it might be because by default actions inherit a com.apple
-based identifier.
I’m still getting to grips with this myself, but as I understand it, you can codesign with the hardened run time flag without adding any extra entitlements
codesign --verbose --force --deep -o runtime --sign "Developer ID Application:xyzzy" /path/to/app.app
Hardening is just a mach-o flag that gets written into the binary. If you want to pass entitlements (like being able to send apple events to other apps), you should be able to build an entitlement plist and feed that to codesign (caveat: theory, I ain’t tested it yet!).
Yes, I was assuming that would be the case with an Automator applet, but of course it doesn’t have to end Apple events.
See earlier in this thread for an example.
Yeah, sorry only saw afterwards that that had already been covered.
I’ve been playing with this a bit, and here’s some more info…
@Tekl : I suspect you have only stapled your disk image, not the app. You can check by running spctl
:
spctl --assess --type exec -vv /path/to/Applet.app
For a normal codesigned applet you will see:
source=Developer ID
For one that’s been stapled, you will see:
source=Notarized Developer ID
It turns out the issue with submitting zipped applets is that stapling only works with 64-bit-only binaries. This may well change at some point — it seems odd that the notarizing process has no such limitation, and only the stapling fails — but at this stage you need to use lipo
on the applet binary to strip 32-bit code before you sign.
Also, the --deep
argument is useless when signing with the required hardened runtime. If your applet includes any other binaries, you have to follow the same lipo/codesign
process with them first, working from the deepest level up.
The last point makes notarizing an Enhanced Applet (or any applet with embedded frameworks, apps or binaries) reasonably complex.
A utility to handle the process is under development, and it should end up relatively straight-forward. Exactly how it will be made available is still undecided. Watch this space.
Hi Shane,
thanks for looking deeper. Apple tells that notarizing a disk image will also notarize the content.
Alternatively, you can put apps, kernel extensions, and other software in a container, like a disk image, and notarize the container. The notary service accepts disk images (UDIF format), signed flat installer packages, and ZIP archives. It processes nested containers as well, like packages inside a disk image.
Yes, but I’m pretty sure it only staples the ticket to the disk image. That’s fine as long as you then distribute that unchanged disk image.
Apps can be notarized without being stapled, of course. It just means the original checking process Gatekeeper does involves talking to Apple’s servers rather than consulting a local ticket.
And indeed it has. Apple’s server now handles fat binaries (it provides tickets covering both binaries).
And see here:
Oh, thank you so much
This has all been very helpful. Thanks! However, I am wondering about distributing updates. What does notarization make “note” of? If I distribute a MyAmazingApp.app v1.0.0 properly code signed and notarized, how do I release v1.0.1 and yet still allow v1.0.0 to be distributed and run?
Versions shouldn’t cause any problems. When you staple your app, the ticket that’s stapled to it contains a hash of all its executables as calculated from the upload, and Gatekeeper will compare that with what it presumably calculates itself.
How and when any other checks are done is unknown at this stage, and will probably (a) change and (b) be purposely kept obscure.
Further to the question of versions, this is what of the Apple team wrote on their developer forums:
We encourage developers to upload all the macOS software they distribute, including versions previously released. This helps users of older versions of your software and helps us improve as well.
I have a problem that stops me from beginning with notarization. It is maybe a bit off topic for this thread – but a would appreciate any suggestions.
I have två apple-id:s: One is my private account, which all my devices including my workplace computer is logged into, and another that I use as developer ID in my work. That’s the way I want it to be. Since my workplace Mac is connected to my private account, my keychains, my files on iCloud Drive and so on are always in synch between work and home. I don’t want to merge the two accounts into one, and I think it would also be some technical obstacles in doing that.
Now notarization demands app specific passwords, which in turn demands the Apple ID uses two factor authentication. But – as I understand it – two factor authentication demands that at least one Apple device is connected to iCloud with that Apple ID. When I’m logged in at my Apple ID account page with my developer ID, the alternative to create two factor authentication is not present. Two step verification is the only available choice, and the reason seems to be that I have no device connected to iCloud with that account.
So my fear is that I can’t begin to notarize my apps unless I mix my private and professional world – ether use my developer ID for iCloud och vice versa – which Is really unwanted. Or did I misunderstand something? Is there a workaround?
(BTW, thanks for that tool, Shane.)