I have successfully notarized a plugin via command line for a Mac application i'm developing plugins for. This plugin is intended for distribution outside of Mac appstore.
xcrun altool --notarize-app --primary-bundle-id "com.demo.bundle.id" --username "email#abc.com" --password "xxx-x-xxxx-xx" --file Plugin.zip
Got an email that it has been successfully notarized and the email has instructions on how to export for distribution. However, it's an instruction for XCode UI but I did the notarization via command line so the instructions doesn't apply for me. Is there a commandline to download the notarized file(Plugin.zip) or else how do I get the Plugin.zip file from Apple to distribute it on my website?
UPDATE:
Turns out you can notarize a .zip file but you can't staple it. So I decided to create a .pkg to distribute my plugin instead of distributing via a zip file.
Here's the steps I followed to successfully notarize and staple my plugin, lets say my plugin name is FileConvertor.PluginExtension
Code sign your binaries to be included in your installer. codesign --sign "Developer ID Application: Developer Name" --verbose=4 --deep --force --strict FileConvertor.PluginExtension
Create your installer (.pkg) adding the above code signed .PluginExtension
Now sign your installer with the installer certificate. productsign --sign "Developer ID Installer: Developer Name" ./FileConvertor.pkg ./FileConvertorSigned.pkg
Send the signed installer for notarization xcrun altool --notarize-app --primary-bundle-id "com.demo.plugin" --username xyz#abc.com" --password "xxxx-xxxx-xxxx-xxxx" --file FileConvertorSigned.pkg
If sucessfully notarized, staple your installer xcrun stapler staple FileConvertorSigned.pkg
Distribute your installer on the web
You don't download your plugin.zip from Apple - just work with the same archive you originally uploaded to them. You are the one that actually staples the notarization ticket to whatever you are notarizing.
I haven't tried it myself with a .zip, but this is the process pieced together from the documentation.
Notarizing Your App Before Distribution says:
Notarize Your Preexisting Software
[...]
Upload your software to the Apple notary service, as described in Upload Your App to the Notarization Service.
You've already done this step.
Staple the returned ticket to your existing software, as described in Staple the Ticket to Your Distribution.
You have to attach the notarization ticket to whatever you're distributing, so Gatekeeper can find it even without a network connection. Normally you use the stapler tool to do this:
xcrun stapler staple MyApp.app
However, stapler doesn't support zip files. Customizing the Notarization Workflow says:
While you can notarize a ZIP archive, you can’t staple to it directly. Instead, run stapler against each individual item that you originally added to the archive. Then create a new ZIP file containing the stapled items for distribution.
So; expand your .zip and run stapler staple {filename} against each item contained inside. Then create a new .zip archive of the stapled contents.
Apple do not return anything from Notarization. Your signed file has a unique ID, in the signature, that Apple have stored. Once notarized, the signed file is accepted if downloaded.
Related
There is a professor at the university I work at that has developed a MacOS application he needs to get signed so that it doesn't get blocked by MacOS when users try to run it. I've gotten his CSR and gotten an Apple Developer cert created for him (using the 'ad hoc' distribution option, which created a cert file named 'distribution.cer').
I've searched the Apple Developer site for information on how to sign the application using XCode, but I can't quite grasp the instructions, not being an XCode user or Apple dev.
From what I can gather, you can also sign an app from a terminal, is that correct? If so, does it only work with .pkg installers, or also pre-compiled applications (.app files)?
Code signing
Apple Certificates
Developer ID Application Certificate - sign a macOS application for distribution outside of the Mac App Store.
Developer ID Installer Certificate - sign an application's Installer Package (if any) for distribution outside of the Mac App Store.
Signing an app
On the command line in a Terminal:
codesign -f -o runtime --timestamp -s "Developer ID Application: YOUR NAME (TEAM_ID)" /path/to/bundle.app
Notarization
Be aware that since macOS 10.14.5 (Mojave), software signed with a new Apple developer certificate must be notarized. Code signing is no longer sufficient to bypass Gatekeeper.
Apple's notary service requires you to:
Enable code-signing for all of the executables you distribute.
Enable the Hardened Runtime capability for your application and command line targets (include -o runtime option when running the codesign tool).
Use a “Developer ID” application, kernel extension, or installer certificate for your code-signing signature.
Include a secure timestamp with your code-signing signature (include the --timestamp option when running the codesign tool).
Don’t include the com.apple.security.get-task-allow entitlement with the value set to any variation of true.
Link against the macOS 10.9 or later SDK.
Step 1 - Create a disk image
Create a disk image of the app by opening a Terminal and running the following command:
hdiutil create -volname MyApp -srcfolder /path/to/MyApp.app -ov -format UDBZ MyApp.dmg
Step 2 - Code sign the disk image
Code sign the disk image by opening a Terminal and running the following command:
codesign -s "Developer ID Application: YOUR NAME (TEAM ID)" --timestamp MyApp.dmg
Step 3 - Generate an app-specific password
Generate an app-specific password, refer to this Apple Support article. Note: this is a password that will be specific to the notarization application (xcrun altool) and not to the application being notarized. You therefore only need to do this once, but make sure you copy the generated password and save it somewhere.
Step 4 - Upload disk image to notary service
Note: When you notarize the container disk image, altool also notarizes the application inside, so you can skip the step of notarizing the application itself.
Upload the disk image file to the Apple notary service by opening a Terminal and running the following command:
xcrun altool --notarize-app --primary-bundle-id "<your identifier>" -u "<your email>" -p "<app-specific pwd>" -t osx -f /path/to/MyApp.dmg
The primary-bundle-id helps you keep track of automated correspondence from the notarization service. The value you give doesn’t need to match the bundle identifier of the submitted app or have any particular value. It only needs to make sense to you. The notarization service includes the value whenever it emails you regarding the given altool submission.
If the upload is successful you should receive output similar to the following:
No errors uploading 'MyApp.dmg'.
RequestUUID = 3af4e56f-162b-75bc-827f-7233f92bf20c
Step 5 - Check the notarization process
The notarization process generally takes less than 15 minutes, so you may want to check its progress from time to time by opening a Terminal and running the following command:
xcrun altool --notarization-history 0 -u "<your email>" -p "<app-specific pwd>"
When the notarization process completes successfully the above command will return information similar to the following:
Notarization History - page 0
Date RequestUUID Status Status Code Status Message
------------------------- ------------------------------------ ------- ----------- ----------------
2019-12-08 06:24:03 +0000 3af4e56f-162b-75bc-827f-7233f92bf20c success 0 Package Approved
You should also receive an email from Apple similar to the following for a successful notarization:
Dear <First_Name>,
Your Mac software has been notarized. You can now export this software and distribute it directly to users.
Bundle Identifier: com.example.MyApp.001
Request Identifier: 3af4e56f-162b-75bc-827f-7233f92bf20c
For details on exporting a notarized app, visit Xcode Help or the notarization guide.
Best Regards,
Apple Developer Relations
Step 6 - Staple the ticket to the disk image
The notarization process produces a ticket that tells Gatekeeper that your application is notarized. After notarization completes successfully, the next time any user attempts to run your application on macOS 10.14 or later, Gatekeeper will find the ticket online. This includes users who downloaded your application before notarization.
After step 5 receives the "Package Approved" status message, you should also attach the ticket to the disk image file using the stapler tool, so that future distributions include the ticket. This ensures that Gatekeeper can find the ticket even when a network connection is not available.
To staple the ticket to the disk image file, open a Terminal and run the following command:
xcrun stapler staple /path/to/MyApp.dmg
If the command completes successfully, the output should be similar to:
Processing: /Path/to/MyApp.dmg
Processing: /Path/to/MyApp.dmg
The staple and validate action worked!
Step 7 - Verify notarization of the disk image
To verify the notarization of the disk image, open a Terminal and run the following command:
spctl -a -vv -t install MyApp.dmg
A successful verification of the notarization process should produce output similar to the following:
MyApp.dmg: accepted
source=Notarized Developer ID
origin=Developer ID Application: <Developer Name> (<TEAM_ID>)
Step 8 - Verify notarization of the application
To verify the notarization of the application, install the application, open a Terminal and run the following command:
spctl -a -vv /Applications/MyApp.app
A successful verification of the notarization process should produce output similar to the following:
/Applications/MyApp.app: accepted
source=Notarized Developer ID
origin=Developer ID Application: <Developer Name> (<TEAM_ID>)
Important: test the application by putting it in the Applications directory. It's treated differently by the Gatekeeper when in the "installed" location.
Alternatively, the Apple-recommended way to verify the notarization of an application is to open a Terminal and run the following command:
xcrun stapler validate MyApp.app
A successful verification of the notarization process should produce output similar to the following:
Processing: MyApp.app
The validate action worked!
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?
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 and Developer ID Installer certificates configured in XCode, skip this step
Create a developer account with Apple
https://developer.apple.com and shell out $99 for a developer account. Theives
Download and install X-Code from the Apple App Store
Open and run X-Code app and install whatever extras it requires
Open the preferences pane (cmd+,) and choose Accounts
click the + in the lower left corner
choose Apple ID
enter your apple ID and password
Previously created keys can be downloaded and installed from https://developer.apple.com
Select the developer account you wish to use
Choose Manage Certificates...
Click the + in the lower left corner and choose Developer ID Application
Click the + in the lower left corner and choose Developer ID Installer
Create an App-Specific password for altool to use
Instructions from Apple
Open KeyChain Access
Create a "New Password Item"
Keychain Item Name: Developer-altool
Account Name: your developer account email
Password: the application-specific password you just created
Create an executable binary with Pyinstaller or other tool
NB! Additional args such as --add-data may be needed to build a functional binary
Create a onefile binary
pyinstaller --onefile myapp.py
Sign the executable
Add the entitements.plist to the directory (see below)
List the available keys and locate a Developer ID Application certificate:
security find-identity -p basic -v
1) ABC123 "Apple Development: aaronciuffonl#gmail.com ()"
2) XYZ234 "Developer ID Installer: Aaron Ciuffo ()"
3) QRS333 "Developer ID Application: Aaron Ciuffo ()"
4) LMN343 "Developer ID Application: Aaron Ciuffo ()"
5) ZPQ234 "Apple Development: aaron.ciuffo#gmail.com ()"
6) ASD234 "Developer ID Application: Aaron Ciuffo ()"
7) 01010A "Developer ID Application: Aaron Ciuffo ()"
7 valid identities found
codesign --deep --force --options=runtime --entitlements ./entitlements.plist --sign "HASH_OF_DEVELOPER_ID APPLICATION" --timestamp ./dist/foo.app
Package as a pkg for installation
Create a temp directory to build the package:
mkdir /tmp/myapp
Use ditto to build the pkg installer structure
ditto /path/to/myapp /tmp/myapp/path/to/install/location
to install application "WhizBang" into /Applications/ on the target use: ditto ~/src/whiz_bang/dist/whizBang /tmp/whiz_bang/Applications/
repeat for all files that should be packaged
build the package
productbuild --identifier "com.your.pkgname.pkg" --sign "HASH_OF_INSTALLER_ID" --timestamp --root /tmp/myapp / myapp.pkg
NB! the format for the --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="developer#foo.com" --password "#keychain:Developer-altool" --file ./myapp.pkg
Check email for successful notarization
Alternatively check status using:
xcrun altool --notarization-history 0 -u "developer#***" -p "#keychain:Developer-altool"
If notarization fails use the following to review a detailed log:
xcrun altool --notarization-info "Your-Request-UUID" \
--username "username#example.com" \
--password "#keychain:Developer-altool"
Staple notarization to pkg
add the notariztaion to the pkg
xcrun stapler staple ghostscript64.pkg
Useful Resources
Norarize a Commandline utility
This blog details setting up:
a developer profile & certificates
one time passwords
creating keychain entries to allow the -p "#keychain:Key" switch to work
Signing and Notarizing
Satpling
Adding an entitlements.plist to the signing process
ensure that embedded python libraries can be access appropriately
Signing and Notarizing tools compiled outside of XCode
covers:
signing
packaging
notarizing
stapling
DMG 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.
mkdir DistributionFolder
xattr -cr ./DistributionFolder
Then move the binary into that folder and create an appropriately sized DMG
hdiutil create -fs HFS+ -volname MyApp -srcfolder ./DistributionFolder ./Distribution.dmg
Eject the drive. Sign the DMG and upload. Once notarised you can staple the same as in Aaron's answer.
I'm trying to codesign my macOS screensaver project to get rid of the "unidentified developer" warning message. Both Apple's documentation and this person on Apple's forums say that you should use the "Developer ID Application" signing certificate to do it. But that doesn't appear to work for me.
When I follow Apple's instructions on how to test for proper signatures the response I get is as follows:
Screensaver.saver: rejected (the code is valid but does not seem to be an app)
My signing settings look like this:
I'm not sure what else I should try at this point. Mostly I'm worried about the rumor future mac apps will have to be signed/notarized and what does that means for screensavers?
Here are additional notarization notes:
You can’t notarize the .saver directly, but you can in a round-about-way notarize a ZIP file, which is how I distribute my screen saver. Here are the steps I use for my simple saver, your mileage will undoubtably vary:
/usr/bin/codesign -f -o runtime --timestamp --sign “insert Developer
ID Installer certificate identifier here” XYZZY.saver
compress the code signed .saver e.g. XYZZY.saver.zip
/usr/bin/xcrun altool --verbose --notarize-app --primary-bundle-id “insert identifier here" -u “xyzzy#plugh.com" -p “insert app-specific PW for your Apple ID here" -t osx -f XYZZY.saver.zip
Aside: store the App-specific password in your keychain and
reference it from the command line like this:
/usr/bin/xcrun altool
--store-password-in-keychain-item
"AC_PASSWORD" -u xyzzy#plugh.com -p “insert App-specific PW from Apple here”
wait for notarization, check status like this:
/usr/bin/xcrun altool --notarization-history 0 -u “xyzzy#plugh.com"
-p "#keychain:AC_PASSWORD”
While you can notarize a ZIP archive, you can’t staple the
notarization ticket to it directly. Instead, run stapler against
each individual item that you originally added to the archive. Then
create a new ZIP file containing the stapled items for distribution.
/usr/bin/xcrun stapler staple XYZZY.saver
Re-zip the saver and
distribute
Just in case someone else stumbles in here...
For now I've realized that a good way around this is to create an installer package and then sign that following Apple's instructions.
I ended up using some free software called Packages to create the installer. After building the installer, I copied it to another folder and used the following command to sign it.
/usr/bin/productsign --sign "<Name of Developer ID Installer Cert in Keychain>" source.pkg destination-signed.pkg
Hope this helps someone out there. As far as I can tell this gets around the unidentified developer warning.
This query on how to staple ticket with unix executable after notarization. I am new to MAC OSX environment. Following steps are used to notarize and staple unix executable :-
1) Created the directory codesign_utilities
2) Added all the codesigned unix executables into it and compressed it to zip file as :- zip -r codesign_utilities.zip codesign_utilities
3) Run command for notarization:- xcrun altool --notarize-app --primary-bundle-id "com.def.ghi" --username "developer ID" --password "related password" --file codesign_utilities.zip. I am able to notarize the zip file.
4) Later, I am trying to staple the ticket with one of the unix executable which was part of the zip file with command:- xcrun stapler staple "unix executable". But, it is throwing error as:-
"Could not remove existing ticket from /Contents/CodeResources ... {Error Domain=NSPOSIXErrorDomain Code=20 "Not a directory"}}
The staple and validate action failed! Error 73.
I believe the error is occurring because it is just unix executable and not a executable bundle in .app format.
Queries:-
Can you help me what are the best ways to staple the ticket with unix executable?
Is it mandatory to create executable bundle for notarization and stapling? If yes, please provide the steps?
man stapler has this to say:
SUPPORTED FILE FORMATS
stapler works only with UDIF disk images, signed "flat" installer packages, and certain code-signed
executable bundles such as ".app". Passing an unsigned "flat" installer package or an unsigned executable bundle in path to stapler is considered an error.
It seems impossible to staple a notarization ticket to a Unix executable, and I'm not sure why you want to.
Here is how I solved it by notarizing my executable:-
https://medium.com/#nimit95/fix-macos-catalina-caused-app-failures-1f9a05d2b0ec
Currently, only some file formats are supported for stapling.
Staple man says
SUPPORTED FILE FORMATS stapler works only with UDIF disk images, signed "flat" installer packages, and certain code-signed executable bundles such as ".app". Passing an unsigned "flat" installer package or an unsigned executable bundle in path to stapler is considered an error.
You should also attach the ticket generated ticket to your software using the stapler tool, so that future distributions include the ticket. This ensures that Gatekeeper can find the ticket even when a network connection isn’t available. It is not mandatory as if the network connection is there gatekeeper will check online.
Currently I am working on submitting an app to the mac app store. I have gone through several steps but am stuck on the last one. This is as I am trying to build my .app file (made in unity) into a .pkg so I am able to Deliver it to iTunes connect via application loader.
I am entering this command into terminal:
productbuild --component GAMENAME.app /Applications --sign "3rd Party Mac Developer Installer: DEVELOPER NAME" GAMENAME.pkg
For some reason though, after entering even though I don not get an error:
Usage: productbuild [--product <requirements-plist>] {--component <component-path> <install-path>} <product-output-path>
Build product with a self-contained bundle, e.g. for the Mac App Store
Usage: productbuild {--content <content-path>} <product-output-path>
Build product with in-app content
Usage: productbuild [--product <requirements-plist>] {--root <root-path> <install-path>} <product-output-path>
Build product with an xcodebuild destination root
Usage: productbuild [options] --distribution <dist-path> [--package-path <search-path>] <product-output-path>
Build product with a distribution and the packages it references
Usage: productbuild --synthesize [--product <requirements-plist>] {--package <pkg-path>} <distribution-output-path>
Synthesize and write a distribution from component packages
See productbuild(1) for details.
I cannot find the .pkg file that has just been built...
I am not sure if this is because it is hidden somewhere or if I have made a mistake I'm unaware of, but any help would be appreciated
So, in short This question basically is how to make a .app to a .pkg which can be using application loader uploaded to iTunes connect...
EDIT:
Ok as someone suggested I might have gotten the initial terminal command wrong after all so any suggestions on where I went wrong would be appreciated.
Your developer name must be followed by the team ID.
Like - "DEVELOPER NAME (ABC123456)"