macOS 10.15 Catalina requires binaries are notarized to run without annoying additional steps. See the issue here: https://github.com/hashicorp/terraform/issues/23033
These are steps to notarize a direct binary. This does not cover stapling, installers (pkg), etc. This is primarily useful for static binary developers such as Go developers.
Apple Developer Account
You first need an Apple Developer Account ($99/year). You need to accept all the agreements and stuff.
Get a Developer ID Cert
You first need a "Developer ID Application" certificate. You get this by:
- Open Xcode
- "Xcode => Preferences" in menu bar
- Add your Apple ID account if its not there. This has to be the one associated with the Apple developer account we want to use for builds.
- Click "Manage Certs"
- TO ADD: click "+" in bottom left and choose "Developer ID Application"
- Right click the cert, hit "export" and it'll export as a p12. You can copy this wherever.
Next, find the developer ID to use:
$ security find-identity -v 1) 8F5E555F64B68F2BA5DA6FBD4F8414CF8F48BA46 "com.apple.idms.appleid.prd.2b6c4f417a324d417363384362744a71694448484b773d3d" 2) 42C333379546C93C3B2624E40D3029D735CA3EA9 "Developer ID Application: Mitchell Hashimoto (GK79KXBE4F)"
In this case, the value is
First step is to sign the binary. You sign the binary, not the zip.
$ codesign -s <cert ID> -v --timestamp --options runtime <binary> # example: $ codesign -s 42C333379546C93C3B2624E40D3029D735CA3EA9 -v --timestamp --options runtime ./terraform
-v --timestamp --options runtime are critical. These are necessary requirements for notarization to succeed.
Note: This will pop-up requesting the password for the certificate. There is a way to automate around this. I don't directly remember what it is but we did it for Vagrant Mac builds years ago, so the answer is there.
Make a Zip
ditto cause the Apple docs tell us to, I guess to make a "valid" zip format.
$ ditto -c -k <binary> <zip name> # example: $ ditto -c -k ./terraform ./terraform.zip
Submit for Notarization
Now you submit for notarization:
$ xcrun altool \ --notarize-app \ --primary-bundle-id "com.example.terraform" \ -u "email@example.com" \ -p "abcd1234" \ -f ./terraform.zip
primary-bundle-id doesn't really matter, but we should use some consistent value like the one proposed.
-p are the username and password of the Apple account in use. The password should probably be an app-specific password.
This will output a request ID. Copy that!
Next you poll the status:
$ xcrun altool \ --notarization-info fa18dd71-2789-429d-b4d8-008de9ge1d19 \ -u "firstname.lastname@example.org" \ -p "abcd1234" No errors getting notarization info. Date: 2019-10-30 22:57:35 +0000 Hash: 5730fbe04f67746c786d7fd2a7141bf11c2c6a69402b11dc8db6bc4faf5506d1 LogFileURL: https://osxapps-ssl.itunes.apple.com/itunes-assets/Enigma113/v4/26/9b/3c/269b3cdf-bd72-a35b-25b2-4cb7769fb19b/developer_log.json?accessKey=denied RequestUUID: fa18dd71-2789-429d-b4d8-008de9ge1d19 Status: success Status Code: 0 Status Message: Package Approved
You want to wait for "success". I forget the failure values.
- The message will go to "Packaged Approved" before the status is actually "success". You have to wait for the latter otherwise it means it isn't propagated yet.
- The log file is really good. It is also JSON. That's useful.
Upload the Zip. Success!
You can now upload the exact same zip you submitted for notarization. The SHA-256 hash must match for Catalina machines to verify the notarization.
You do not need to staple. The downside to this is that the computer that downloads the package must have internet to verify the signature on first run. It is then cached and subsequent execution can happen offline. If you insist on stapling, you'll need to package your binary into an App Bundle (
.app/ directory structure) and probably wrap that up in a
dmg and resign that. It is quite an additional process.