C# .NET CLI Application: Is codesign enough or should I notarize too?

I do not own apple products at all, nor do I typically develop on Apple platforms. I have an open source CLI application that I distribute to Windows, Linux, and OSX. The distribution itself is just a single, self-contained executable.

I noticed that OSX users were getting "crashes" / untrusted modals when they try to run my application, which they download from a release page on Github. Looking into this, it seemed like running codesign is the answer. At first blush it looked like this required the $99 apple developer membership. I read that there are free ways to get developer ID certificates but I was not able to find any instruction on how to obtain those, and I did not see an option to create certificates at developer.apple.com until I paid for a membership.

In my Github Workflow which builds my application, I also run codesign using the cert I got from the apple developer cert page. I had a user with MacOS v12 run my program and it worked fine on the CLI without any further steps needed.

So here's my question: I read about this thing called the "gatekeeper" and that it requires notarization starting with macOS v10, but I did not notarize my dotnet application and it worked fine. I do not plan to distribute my program on Apple store or anything like that. I also am trying to avoid purchasing apple hardware just to distribute my app.

Is codesigning all I need? If so, why am I reading that notarization is required? Is a paid apple developer membership required for me just to codesign my open source application?

Code signing is needed to make the binary run if the binary is arm64. But you don't need a paid developer id certificate to code sign, you can generate your own certificate or use a default ad hoc one. However, to avoid the untrusted modals you need to code sign the binary with a developer id certificate (99$ a year) and to notarise it.

Gatekeeper (a name for a cluster of checks on the binaries) used to run only if there was a quarantine flag set, this flag is set by the application that downloaded the file from the internet so if it was used one application that did not set it, there would have been no check at all. This changed recently and even not quarantined binaries are checked sooner than later.

To ship a product that Mac users can run without jumping through hoops you must:

  1. Sign the code with a Developer ID signing identity.

  2. Place that code into its distribution packaging (for example, a zip archive).

  3. Notarise that.

If you don’t do this, the user will have to bypass Gatekeeper to run your program. For info on how they’d do that, see the Safely open apps on your Mac article from Apple Support.

You can find links to detailed info about the code signing and distribution process in various pinned posts here on DevForums:

Step 1 requires a paid development membership. If you don’t have such an membership, you can’t ship code that passes Gatekeeper. However, it still makes sense to sign your code because it gives the code a stable code signature [1]. Your best option is to use the free provisioning feature in Xcode (aka Personal Team) to generate an Apple Development signing identity. Once you do that, you can use that code signing digital identity to sign from the command line.

If you don’t want to do that then the next best option is to ad hoc sign your code (Sign to Run Locally in Xcode parlance). This is required for Apple silicon code and a good idea for Intel as well. To do this, pass - to the sign identity argument in codesign. See the codesign man page for details.

Share and Enjoy

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

[1] If you’re curious about the mechanics of this, see TN3127 Inside Code Signing: Requirements.

C# .NET CLI Application: Is codesign enough or should I notarize too?
 
 
Q