MacOS now requires that all applications are hardened, signed and notarized. How does one sign and notarize an application created outside of XCode with a tool like PyInstaller?
I’ve sorted out the signing and notarization for .app
files created outside of XTools. There’s a really helpful thread here that shows how to add an entitlements.plist
which fulfills the hardening of PyInstaller .app
files. I believe this also works on command line utilities as well, but could be missing something. Submitting a .dmg
containing a .app
for notarization using altool
will pass the tests and be notarized by Apple.
Submitting a single command line utility using the same process will also pass Notarization, but does not appear signed or notarized to the GateKeeper function on other machines. I assume this has something to do with the fact that a valid Info.plist
file is not included in the PyInstaller binary as detailed in this blog post about building and delivering command line tools for Catalina.
Checking the signature of a signed file using codesign -dvv
indicates that the Info.plist
is "not bound".
$ codesign -dvv ./dist/helloworld
Executable=/Users/aaronciuffo/Documents/src/toy/codesign/dist/helloworld
Identifier=helloworld
Format=Mach-O thin (x86_64)
CodeDirectory v=20500 size=72086 flags=0x10000(runtime) hashes=2244+5 location=embedded
Signature size=9054
Authority=Developer ID Application: Aaron Ciuffo (4H9P6Q65AM)
Authority=Developer ID Certification Authority
Authority=Apple Root CA
Timestamp=Nov 2, 2020 at 9:03:30 PM
Info.plist=not bound
TeamIdentifier=4H9P6Q65AM
Runtime Version=10.11.0
Sealed Resources=none
Internal requirements count=1 size=172
One suggested solution is using the Go gon package but gon does not cover adding the required Info.plist
as far as I can tell.
Is there a workflow or application that can assist in this? How does one create an CL application outside of XCode and successfully sign it?
2
Answers
How to Sign and Notarize a Command Line Tool Manually
Apple requires that all distributed binaries are signed and notarized using a paid Apple Developer account. This can be done using commandline tools for binaries created with tools such as PyInstaller, or compiled using gcc.
Automated Python Script for this Process
The script linked below allows you to automate this process using project specific
.ini
files.codesign.py
Setup
If you already have a developer account with
Developer ID Application
andDeveloper ID Installer
certificates configured in XCode, skip this step+
in the lower left cornerApple ID
+
in the lower left corner and choose Developer ID Application+
in the lower left corner and choose Developer ID InstallerCreate an App-Specific password for altool to use
Instructions from Apple
KeyChain Access
Create an executable binary with Pyinstaller or other tool
NB! Additional args such as
--add-data
may be needed to build a functional binarypyinstaller --onefile myapp.py
Sign the executable
security find-identity -p basic -v
codesign --deep --force --options=runtime --entitlements ./entitlements.plist --sign "HASH_OF_DEVELOPER_ID APPLICATION" --timestamp ./dist/foo.app
Package as a pkg for installation
mkdir /tmp/myapp
ditto /path/to/myapp /tmp/myapp/path/to/install/location
/Applications/
on the target use:ditto ~/src/whiz_bang/dist/whizBang /tmp/whiz_bang/Applications/
productbuild --identifier "com.your.pkgname.pkg" --sign "HASH_OF_INSTALLER_ID" --timestamp --root /tmp/myapp / myapp.pkg
--root
option is as follows:--root
<ditto path>
<relative path on target system to install from>
<signed .pkg file>
Notarize
xcrun altool --notarize-app --primary-bundle-id "com.foobar.fooapp" --username="[email protected]" --password "@keychain:Developer-altool" --file ./myapp.pkg
xcrun altool --notarization-history 0 -u "developer@***" -p "@keychain:Developer-altool"
Staple notarization to pkg
xcrun stapler staple ghostscript64.pkg
Useful Resources
-p "@keychain:Key"
switch to workentitlements.plist
to the signing processDMG distribution
Using Aaron Ciuffo’s post swap the PKG commands with this
If you want to distribute your binary in a DMG, in addition to calling codesign on the binary you must create the DMG correctly.
Start by creating your folder and clearing any junk or upload will fail.
Then move the binary into that folder and create an appropriately sized DMG
Eject the drive. Sign the DMG and upload. Once notarised you can staple the same as in Aaron’s answer.