Signing Applications for OSX - gemini-hlsw/ocs GitHub Wiki
Since OSX 10.7.3 a feature called Gatekeeper restrict running or installing applications in OSX. Applications should be signed by a valid Apple Developer Certificate to exist on the Mac App Store and for applications freely distributed, signing is recommended since the user gets a warning otherwise. In same cases corporate policy may completely forbid the installation of unsigned applications in OSX
On the OCS we have 3 applications that are released for OSX in the form of a DMG: PIT, OT and QPT. The PIT case is particularly important as it is released externally where there is no control of the security policy. We want these dmgs to contain signed applications
Apple doesn't make it very easy to get a certificate, especially for applications not written with XCode, however after some digging a Developer ID certificate was obtained. To do this, Gemini ITS has a developer account and they can request a certificate. Note that certificates are valid for 5 years so this procedure may change by the time the current certificate expires:
- Login as the Team Agent onto Apple Developer, then go to MacApps -> Certificates -> Production

- Select Developer ID

- You must create now a CSR using the instructions

- Now upload the CSR and submit

- The certificate is ready and can be imported into the keychain (Note, at this stage only the Team Agent can import the key

- From the Keychain Access the Team Agent can export the key in p12 format where you should set it a password

Once you get the .p12 file, import it into the Keychain Access application, using the correct password. Once installed you should see a certificate on the list with the name Developer ID Application: AURA Gemini Observatory (CERTIFICATE ID)
You can verify that the certificate is present with the command
security find-identity -v -p codesigning
1) [CERTIFICATE SHA] "Developer ID Application: AURA Gemini Observatory ([CERTIFICATE ID])"
1 valid identities found
The build process will sign the application, first checking if the certificate is present. All the executables in the application need to be signed. The general command for signing is
codesign -f -s [CERTIFICATE SHA] file
You may need to enable codesign to open the key, otherwise the build could fail it particular over SSH.
As an alternative move the certificate to the System keychain
You can check that the app is properly signed for Gatekeeper with the following command
spctl -a -v <Application>.app
<Application>.app: accepted
source=Developer ID
An extra step is to notarize the app, this is an asynchronous process where Apple verify the application follows certain rules. Notarized app show a message saying that Apple has verified them thus they feel more secure.

To notarize, after signing you need to issue this command
xcrun notarytool submit --team-id <team-id> --username <username-email> --password <pwd>
The credentials are an app-specific password for the given user
As a result you'll get a message with a request id
Successfully uploaded file
id: 6c0a7f7b-5144-49f7-b32c-8d83f826f41f
path: /Users/carlos.quiroz/code/noirlab/ocs/app/qpt/target/qpt/2024B-test.1.1.3/MacOS/mac/qpt_2024B-test.1.1.3_macos.dmg
That UUID can be used to follow the notarization process which is asynchronous, e.g.:
xcrun notarytool info --team-id <team-id> --username <username-email> --password <pwd> <request-id>
Eventually you'll get a positive answer
Once notarized the operating system will check the apple db to ensure the app was notarize
You can staple the notarization info in the app to also ensure it works if the user is offline
xcrun stapler staple <App>.dmg
As we are embedding the jre with the applications, we need a JRE that is amenable to notarization, in particular they need to be built with certain xcode version and specific compliation flags.
A version known to work is from Adoptium JRE jdk8u382-b05