OSX code signing

Trying to find some advice on how to deal with OSX.

Currently we are distributing our game outside of App store and without doing any code signing… and gatekeeper is the bane of my life. It randomly removes the execution flag when we do patches, it quarantines the .zip file when users download our game. I’ve had enough of it and want to circumvent it.

From what I have read we can code sign to bypass gatekeper or we can distribute via the app store (which also involves code signing).

I am struggling to find good information on code signing a Unity application and staying outside of Apple store - is this a good idea, will it be problem free? Is there even any good information on this as I’m yet to find anything I can understand - I’m not an OSX user, so the apple ecosystem is fairly new to me.

Is there a guide somewhere on how to code sign a Unity application for OSX, are there any reliable automated tools to make it easy? I even struggled working out how to get a code signing ID as Apple’s webpages on the subject are circular in nature so you follow the hypertext links and end up back where you started and no wiser - so frustrating.

Would appreciate a bit of guidance from someone who has suffered this pain already.

Yes, we code-sign High Frontier and distribute it through our own store. And in fact, since it’s a cross-platform app, we also code-sign the Windows binary on our Mac build machine, as described here.

We do it all through the Unix command line. Here’s the shell script that does all the heavy lifting for the Mac version (only slightly sanitized, and reduced to deal with just one app — our real script does both the demo and full versions of the game):

#!/bin/bash

cd /Users/blah/blah/Build/Mac

echo 'Clearing "Untouched" versions...'
rm -rf *Untouched*

echo 'Code-signing Mac full build...'
codesign --deep -f -v -s "Developer ID Application: Strout and Sons, LLC" HighFrontier.app
codesign --deep --verify --verbose HighFrontier.app

echo 'Zipping Mac full build...'
rm HighFrontier-Mac.zip
zip -r HighFrontier-Mac HighFrontier.app

So, basically, the codesign (that’s code-sign, not co-design!) command is what you’re looking for. It digs up your private key from the keychain, where it’ll be installed if you’ve managed to follow Apple’s (confusing) guidelines, and uses it to sign the app package. Then we just zip it up for distribution. Some people prefer to deliver on a disk image, but as a user, I’d just as soon have a zip file rather than a disk image I have to mount, drag stuff out of, unmount, and then throw away.

7 Likes

Very helpful thanks, so we just have to go jump through the Apple hoops to get our code signing id and then the above can be applied?

Yes, that’s right.

But it’s easier than in the Windows world… you wouldn’t believe the rigamarole I had to go through to get my CODOMO certificate!

got the apple cert through today and appear to have code signed without issue. One thing we aren’t sure about is if you zip a code signed app does that stop the archive from picking up the quarantine flag if you then host that zip on goolge drive or a web host for download?

No, it’s fine. Once the zip file is unzipped, Finder will see that the app is signed and not bug the user about it.

Interesting time we have had with code signing. Because we don’t distribute through the Apple Store any zip file we provide gets quarantined (even if we have signed it all). However, we have discovered that if we package using a signed .dmg file then although it downloads as quarantined on first open it verifies and removes the quarantine. At this point we can run fine with full disk access which we can’t do using zip distribution as we get moved to a safe read only area due to the quarantine flag.

Interesting! That’s not something I’ve ever noticed with our game (but then, it’s not trying to get full disk access — it uses only a folder in Application Support). But perhaps it explains why so many apps are distributed as .dmg files!

I’m not sure what the subtle difference is between .dmg and .zip for one to follow a different security policy to the other, logically either one could run malicious code (which I’m told is the point of the quarantine). I’m just grateful one way works as we were looking like ending up in the Apple Store (hell no!).

1 Like

Hey JoeStrout:

Thanks for the script! I’m trying to do the exact same thing as well. I keep getting “no identity found” with respect to my cert, which I assume means I’m not naming it correctly or it’s not in the right place. Do you have any tips on installing and naming the cert so codesign command can find it?

I’m afraid not — except I guess to go back through Apple’s guidelines on where/how to install developer certificates.

I know I’m resurrecting an old thread but I’m attempting to do the exact same thing as what JoeStrout here does with his script and somehow any attempt I make to sign the .app manually from the command line is met with the following error message:

Test.app: code object is not signed at all
In subcomponent: /Users/XXX/Workspace/XXX/XXX/Build/OSX/XXX/Test.app/Contents/Frameworks/libssl.dylib

I haven’t been able to find much results when looking up that error message, anyone has experienced a similar issue.

1 Like

I haven’t met the error you are having, but sometimes the --deep command doesn’t sign everything and you have to sign everything manually. We’ve written an automated workflow / guide to prepare distribution for OSX (from start to finish) in and outside of the Appstore together with an extensive guide I would suggest reading it. The code to do it manually is also included and I would suggest you read up at signingpackage if you scroll up a bit it shows what other packages to sign. Good luck!

You can read the full text guide with DIY here and get the full here.

You can find the Unity forum thread here .

1 Like

@UNSH Thanks for the in depth guide. It looks great and all the steps seemed to work fine, but after installing the resulting Mac App Store package and running it, I get a crash with a “EXC_CRASH (Code Signature Invalid)” exception. I tried removing all the .dylibs/.bundles and signing/packaging the app with the following:

codesign -f --deep -s "3rd Party Mac Developer Application: COMPANY_NAME (ID)" --entitlements "my.entitlements" "My.app"
productbuild --component "My.app" /Applications --sign "3rd Party Mac Developer Installer: COMPANY_NAME (ID)" "My.pkg"

I made sure there were no other builds of the same app on my computer before installing. Is there any way to figure out which file is causing this? Any other suggestions that I could try to find the root cause?

I’m trying this on a build using Unity 2019.2.21

Not sure but the guide is behind again. You need a different certificate now the guide doesn’t describe that yet, but that’s a good start (link) because it will give code signing errors. We should update the guide but it’s a frustrating endeavour because things change all the time and we don’t build enough for macOS.

I know what you mean, it doesn’t seem like Mac App Store distributions are something people do too often with Unity builds. Otherwise maybe Unity would put some time into updating their docs as well (https://docs.unity3d.com/Manual/HOWTO-PortToAppleMacStore.html). Following those steps does not result in a valid build for me (even when removing all plugins/frameworks).

It looks like the issue in the link you mentioned is for Developer signed apps, so that doesn’t apply to me unfortunately (I’m signing with Distribution cert).

Sorry for the late reply. No I believe it does if you are using Catalina with Xcode 11.2 It’s a new cert also for Appstore distribution. If you look closely there’s “Mac App Distribution” (the old cert) and the Apple Distribution. In any case there’s so many variables that it’s difficult to say where you made a mistake but since you get a code signature invalid I would say it’s either the certs, and subsequently your profile, the signing identity or if you are using extra features like icloud or something that’s not set up correctly (resulting in an incorrect provisioning profile). It’s difficult to say as it’s even tough to remember all the steps, I would go over the guide and double check everything and keep trying. I know it’s like giving birth to a rock but there’s no other way since the error logs are pretty generic and there’s a ton of variables that can be set up wrong. There’s hopefully light at the end of tunnel with Unity’s Xcode builds.

5799265--612919--cert.jpg

What about just for distributing internally - do you use a development certificate? I give people a Mac build and (particularly if zipped) it fails to run on people’s Macs unless they hack settings in the terminal and/or allow it through privacy settings.
I just want it to be recognized as non-harmful, but do not need an app setup for it, as not going on any store
notorization via a terminal is like a foreign language to me coming from a windows background, very unfriendly!

They don’t have to allow it through privacy settings. All they have to do is, the first time, right-click the app icon and choose “Open” from the contextual menu, and then click the “Open” button in the warning dialog that appears. Once they’ve done that once, Finder will remember and they can just double-click it as usual after that.

Most Mac users are savvy to this, because unsigned apps are still fairly common.

I wish that were the case, but in Catalina there is no open button in warning dialog on right-click open and if sent by zip it just doesn’t open

There was a whole thread on this: https://discussions.unity.com/t/627211