Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create signed/notarized macOS binary (was: "Compiled asset at GH release loses execute permissions") #17

Open
w00lf opened this issue Nov 13, 2019 · 9 comments
Labels
help wanted Extra attention is needed

Comments

@w00lf
Copy link
Contributor

w00lf commented Nov 13, 2019

Currently, our github action build creates a new release with compiled binary asset attachment, however, such upload is lacking execute permissions so it need to be packed to execute container - dmg

@w00lf w00lf changed the title osx: Uploaded compiled asset to github release lose execute permissions osx: Uploaded compiled asset to github release loose execute permissions Nov 19, 2019
@ronaldtse
Copy link
Contributor

@w00lf apparently there is the way to do so: https://forums.developer.apple.com/thread/120989

But it's kind of complicated, and I wonder if it's easier to just distribute the packed-mn via Homebrew https://github.com/metanorma/homebrew-metanorma. (and we can make it an option to install the single binary vs the development chain).

Thoughts @opoudjis @CAMOBAP795 ?

@ronaldtse ronaldtse added the help wanted Extra attention is needed label Nov 28, 2019
@ronaldtse
Copy link
Contributor

We might be able to use https://www.electron.build to sign the executable within a DMG, done just like in:
https://github.com/ituob/itu-ob-editor/blob/master/.github/workflows/build-electron.yml

So it should be possible.

@ronaldtse
Copy link
Contributor

Seems like we need to first package the binary in a DMG or PKG format from the Apple Community post above.

Here's some command line guidance for creating a DMG file:
https://askubuntu.com/questions/1117461/how-do-i-create-a-dmg-file-on-linux-ubuntu-for-macos

And we can also use this to create a PKG installer:
https://medium.com/swlh/the-easiest-way-to-build-macos-installer-for-your-application-34a11dd08744

Then we can sign + notarize the DMG / PKG using the electron builder command electron-builder.

@ronaldtse
Copy link
Contributor

For the record, this is what we need to do on the "executable" itself:

From https://forums.developer.apple.com/thread/120989

  • Use the 10.9 or later SDK. Notarisation requires this because it confirms that your program is using modern code signing.
  • Make sure you specify a deployment target using -mmacosx-version-min. This causes clang to add the relevant Mach-O load command (LC_VERSION_MIN_MACOSX or LC_BUILD_VERSION, depending on how far back you support) that’s required by the notarisation system to confirm that you’re built with the 10.9 or later SDK.
  • Pass --timestamp to codesign to get a secure timestamp.
  • Pass -o runtime to codesign to enable the hardened runtime.
  • If you need to opt out of specific hardened runtime features, put the relevant entitlements in a .entitlements property list and pass that to codesign via the --entitlements option. See Hardened Runtime Entitlements for more on these entitlements.
  • Sign your tool with your Developer ID Application identity.
  • Notarise the outermost container (for example, if you have a tool in a .pkg on a .dmg, notarise the .dmg).

(The last step would be for Electron Builder)

@ronaldtse
Copy link
Contributor

But it's kind of complicated, and I wonder if it's easier to just distribute the packed-mn via Homebrew https://github.com/metanorma/homebrew-metanorma. (and we can make it an option to install the single binary vs the development chain).

This is done in metanorma/homebrew-metanorma#53.

The original issue on DMG building still applies.

@CAMOBAP
Copy link
Contributor

CAMOBAP commented Mar 25, 2021

@ronaldtse to be on the same page we still plan to pack DMG or PKG for packed-mn. If so do we have a plan to distribute it via AppStore or somehow else?

@ronaldtse
Copy link
Contributor

Yes we should go the way of PKG or DMG. We will need to sign the DMG/PKG, which is doable. The problem is that this is a command line tool, which is a bit strange for a package, but I guess it’s something that we need to do.

@CAMOBAP
Copy link
Contributor

CAMOBAP commented Mar 25, 2021

PKG can be simply created by mkdir -p ./usr/local/bin && cp build ./usr/local/bin && productbuild --root ./usr/local/bin --timestamp --sign "${SING_IDENTITY}" Product-mn-2.pkg

To get this sign identity we need to register in Apple developer program https://developer.apple.com/enroll

To generate DMG we also need to be members of Apple developer program

FYI @ronaldtse

@ronaldtse
Copy link
Contributor

ronaldtse commented Dec 5, 2021

@CAMOBAP sorry I missed this. We are a member of the program. A signed binary requires Apple notarisation. This thread gives a good example of what needs to be done:

https://developer.apple.com/forums/thread/130379

Contents re-formatted below.


  1. Sign your dylibs
  2. Sign your executables
  3. Build an installer package
  4. Sign and notarize the installer package

You can incorporate all of that into your build process if you want. It is very easy. Back when Catalina disabled 32-bit apps, a few people freaked out over ghostscript. Apparently nobody had bothered to rebuild that since 32-bit days. I built and notarized a 64-bit version in a few minutes. The hardest part was fixing the bugs in ghostscript iteslf so it would build on a modern machine.

Sign executables:

codesign --timestamp --options=runtime -s "Developer ID Application: ***" -v bin/gs
codesign --timestamp --options=runtime -s "Developer ID Application: ***" -v bin/pdftoraster
codesign --timestamp --options=runtime -s "Developer ID Application: ***" -v cups/pstoraster
codesign --timestamp --options=runtime -s "Developer ID Application: ***" -v cups/pstopxl

I assume you will have to sign dylibs too. If your software is doing anything funky, you may need additional hardened runtime entitlements.

I was building this from source. So I signed the working copy and then installed.

sudo make install

Now, I needed to create a temp install for the installer package. Your files will, of couse, be different.
This is also on a VM where there is nothing in /usr/local except for ghostscript.

sudo mkdir /tmp/ghostscript
ditto /usr/local/bin /tmp/ghostscript/usr/local/bin
ditto /usr/local/share /tmp/ghostscript/usr/local/share
ditto /usr/libexec/cups/filter/pdftoraster /tmp/ghostscript/usr/libexec/cups/filter/
ditto /usr/libexec/cups/filter/pstoraster /tmp/ghostscript/usr/libexec/cups/filter/
ditto /usr/libexec/cups/filter/pstopxl /tmp/ghostscript/usr/libexec/cups/filter/
ditto /private/etc/cups/pdftoraster.convs /tmp/ghostscript/private/etc/cups/
ditto /private/etc/cups/pstoraster.convs /tmp/ghostscript/private/etc/cups/

Now create the installer.

productbuild --identifier "com.***.ghostscript64.pkg" --sign "Developer ID Installer: ***" --timestamp --root /tmp/ghostscript / ghostscript64.pkg

Notarize the installer.

xcrun altool --notarize-app --primary-bundle-id "com.***.ghostscript64.pkg" --username “developer@***" --password "..." --file ghostscript64.pkg

Wait for the e-mail or ping the server if you are impatient. An automated system would need to do something clever here. The
altool can emit XML output that is easier to parse if you need to.

xcrun altool --notarization-history 0 -u "developer@***" -p "..."

Once you are notarized, staple the ticket.

xcrun stapler staple ghostscript64.pkg

@ronaldtse ronaldtse changed the title osx: Uploaded compiled asset to github release loose execute permissions Create signed/notarized macOS binary (was: "Compiled asset at GH release loses execute permissions") Dec 5, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

3 participants