macOS 10.15 Catalina requires binaries are notarized to run without annoying additional steps. See the issue here: hashicorp/terraform#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.
You first need an Apple Developer Account ($99/year). You need to accept all the agreements and stuff.
You first need a "Developer ID Application" certificate. You get this by:
- Open Xcode
- "Xcode => Preferences" in menu bar
- "Accounts"
- 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 42C333379546C93C3B2624E40D3029D735CA3EA9
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
The flags -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.
We use 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
Now you submit for notarization:
$ xcrun altool \
--notarize-app \
--primary-bundle-id "com.example.terraform" \
-u "jane.doe@gmail.com" \
-p "abcd1234" \
-f ./terraform.zip
The primary-bundle-id
doesn't really matter, but we should use some consistent value like the one proposed.
The -u
and -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 "jane.doe@gmail.com" \
-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.
Some notes:
- 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.
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.