Documentation/Nightly/Developers/Mac OS X Code Signing
This page contains information on code signing on OS X and on integrating code signing into the Slicer packaging process.
Some useful external references from the Mac Developer Library include:
- About Code Signing
- Distributing Apps Outside the Mac App Store
- OS X Code Signing In Depth
- Developer ID and Gatekeeper
The Gatekeeper feature in OS X helps protect against malicious software. If a user runs an application downloaded from the internet, Gatekeeper verifies the application's digital signature and displays a warning if verification fails. Reasons verification might fail include the app having been tampered with, or the app not having been signed at all.
Currently the OS X Slicer package is not digitally signed. Therefore, depending on system configuration, Gatekeeper may display a warning and confirmation dialog when running a new Slicer build for the first time.
Developer ID certificate
A Developer ID certificate is required to sign an application for distribution outside of the Mac App Store. Once Slicer is signed with this type of certificate, Gatekeeper's signature verification will succeed and users will be able to run Slicer without warnings.
Only the team agent for an organization in the Apple Developer program has authority to create Developer ID certificates. Certificates can be created using XCode or on the Apple Developer site: https://developer.apple.com/account/mac/certificate/.
There are two types of Developer ID certificates: Developer ID Application certificate and Developer ID Installer certificate. Only the Developer ID Application certificate is required to sign Slicer. The Developer ID Installer certificate is used to sign installers in .pkg format.
Code signing an application requires a unique app identifier. If each new build of an application is signed using the same identifier, Gatekeeper will recognize new builds as being an updated version and will transparently run the updated version as usually without requested verification from the user.
The unique app identifier can be specified in different ways:
- implicitly from the value of CFBundleIdentifier in the application's Info.plist
- explicitly on the command line when signing the code (e.g.
codesign -i <identifier>)
For Slicer, in the first case, the factory could set the CMake variable MACOSX_BUNDLE_GUI_IDENTIFIER (see CMake/MacOSXBundleInfo.plist.in). In the second case, a new CMake variable could be added and used when signing the code.
The unique app identifiers are typically hierarchical names in reverse DNS notation. Therefore, an appropriate identifier could be something like com.kitware.medical.Slicer.
Depending on the environment in which code signing is being performed, it may be necessary to take one or more of the following steps to use the codesign tool without user interaction (i.e. authentication):
security unlock-keychain, like here
- In Keychain Access, edit the certificate's private key to "allow all applications to access this item"
- Add the signing certificate to the system keychain instead of the login keychain
Also see the following discussions:
- StackOverflow: "User interaction is not allowed" trying to sign an OSX app using codesign
- Apple Developer Forums: code sign wants to sign using key - Doesn't allow or always allow but deny works
The codesign command signs the code; its usage is summarized below. See Signing Your Code for more information. Advanced options for specifying requirements and entitlements shouldn't be necessary when signing Slicer.
List all certificates to verify the name of the Developer ID Application certificate to use:
Sign Slicer using a Developer ID Application certificate:
codesign --deep --force --sign "Developer ID Application: <id>" ./Slicer.app
Sign Slicer using a self-signed certificate (for testing):
codesign --deep --force --sign "<certificate id>" ./Slicer.app
However, note that Apple does not recommend using the --deep option when signing.
Show signing info:
Show designated requirements:
codesign -d -r- ./Slicer.app
Verify signature (mimic what Gatekeeper does to check your app):
codesign --verify --deep --verbose=2 ./Slicer.app