Signing Application Packages
This document outlines the code signing and notarization process for Slicer on macOS and Windows platforms.
The Gatekeeper feature in macOS helps protect against malicious software. If a user runs an application downloaded from the internet, Gatekeeper verifies the application's digital signature as well as its notarization status and displays a warning if the verification fails. Reasons verification might fail include the app having been tampered with, or the app not having been signed & notarized at all.
The following steps guide the code signing and notarization process for macOS:
The steps described below are expected to be performed by a @kitware employee and requires to be connected to the internal network.
-
SSH to
your.name@sign-srv-mac.kitware.com
.To request an account, email Kitware Sysadmin cc'ing Jean-Christophe Fillion-Robin and Sam Horvath using the subject
Grant access to sign-srv-mac.kitware.com to Your Name
Once the account is created, log in through the console using RealVNC for full initialization and ensure the home directory created.
-
Download signing scripts:
mkdir -p ~/tmp cd ~/tmp if [[ ! -e slicer-macos-codesign-scripts ]]; then git clone https://github.com/KitwareMedical/slicer-macos-codesign-scripts fi
-
Download the unsigned package:
Set the
download_url
variable specifying the URL reported on CDash after clicking on the 📦 icon.download_url=https://slicer-packages.kitware.com/api/v1/file/hashsum/SHA512/17bb74c8fbad8ca11ad47b7209de5349c6561b8712e8161a8800bed045d0c6e821bb18f3ae4a019cf0ce02b5595b12b9d23dc8909ee5043e875731b3d5b985b8/download cd ~/tmp curl -L# $download_url -O -J
-
Verify the downloaded package:
Replace
X.Y.Z
with the expected version.PACKAGE_NAME=Slicer PACKAGE_VERSION=X.Y.Z cd ~/tmp shasum -a 512 ./${PACKAGE_NAME}-${PACKAGE_VERSION}-macosx-amd64.dmg
⚠️ The computed checksum should match the one specified in the download URL. -
Run signing script:
Replace
X.Y.Z
with the expected version.PACKAGE_NAME=Slicer PACKAGE_VERSION=X.Y.Z PACKAGE_IDENTIFIER=org.slicer.slicer cd ~/tmp ./slicer-macos-codesign-scripts/sign.bash \ ${PACKAGE_IDENTIFIER} ${PACKAGE_VERSION} \ "Developer ID Application: Kitware Inc. (W38PE5Y733)" \ "Developer ID Installer: Kitware Inc. (W38PE5Y733)" \ ./${PACKAGE_NAME}-${PACKAGE_VERSION}-macosx-amd64.dmg
-
Generate an app-specific password
- Your Apple ID needs to be associated with Kitware's provider.
- Email Kitware Sysadmin cc'ing Jean-Christophe Fillion-Robin and Sam Horvath using the subject
Add <Your Name> to Kitware's Apple Team
and providing your Apple ID. - Visit https://appleid.apple.com/account/manage to generate an app-specific password.
- Enter the name, e.g.
notarytool-credentials
.
-
Installing
xcnotary
is not needed anymore. See https://github.com/akeru-inc/xcnotary/issues/22#issuecomment-1179170957
The following steps are expected to be performed by a @kitware employee and require to be connected to the internal network.
-
SSH to
your.name@sign-srv-mac.kitware.com
.Instructions for creating an account are documented in the Code Signing section.
-
Unlock the keychain:
security unlock-keychain "$HOME/Library/Keychains/login.keychain"
Source: https://docs.j7k6.org/osx-keychain-unlock-commandline/
-
Store the notarization credentials in the keychain:
apple_id_email=<your-apple-id> team_id=<your-team-id> # "W38PE5Y733" is kitware team ID keychain_profile=notarytool-credentials xcrun notarytool store-credentials "$keychain_profile" --apple-id "$apple_id_email" --team-id "$team_id"
The requested password corresponds to the application specific one created above in the Notarization Initial Setup.
-
Notarize
apple_id_email=<your-apple-id> team_id=<your-team-id> # "W38PE5Y733" is kitware team ID PACKAGE_NAME=Slicer PACKAGE_VERSION=X.Y.Z keychain_profile=notarytool-credentials xcrun notarytool submit ./$PACKAGE_NAME-$PACKAGE_VERSION-macosx-amd64.dmg --keychain-profile "$keychain_profile" --wait
The
--keychain-profile "$keychain_profile"
argument references the app-specific password stored in your keychain usingnotarytool store-credentials
.
If notarization returns Gateway Timeout
and an email titled Your Mac software was successfully notarized.
was received,
manually perform the stapling using:
xcrun stapler staple -v ./$PACKAGE_NAME-$PACKAGE_VERSION-macosx-amd64.dmg
You can look at your own notarization history like this:
$ xcrun altool --notarization-history -u $appleid -p @keychain:altool-notarize --asc-provider KitwareInc
To see detailed results from one of the runs, take its uuid:
$ xcrun altool --notarization-info $uuid -u $appleid -p @keychain:altool-notarize
It will print out a LogFileURL
you can visit in a browser to get the results.
This section provides additional details that may be helpful to better understand the signing process.
A Developer ID certificate
is required to sign an application for distribution outside of the Mac App Store. Once a Slicer package is signed with this type of certificate, Gatekeeper's verification will succeed and users will be able to run the application 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:
- The
Developer ID Application
certificate is used to sign installers in the.dmg
format. - The
Developer ID Installer
certificate is used to sign installers in.pkg
format.
Using a self-signed certificate as opposed to a Developer ID certificate
is appropriate while testing the packaging process. To create a self-signed certificate, follow the steps in Obtaining a Signing Identity described in the section titled "To obtain a self-signed certificate using Certificate Assistant."
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 identifiers are typically hierarchical names in reverse DNS notation. The default value for Slicer is org.slicer.slicer
and the value for Slicer-based applications is set in the top-level CMakeLists.txt
.
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):
- Run
security unlock-keychain
- In Keychain Access, edit the certificate's private key to "allow all applications to access this item" (right click on the private key, then choose Get Info)
- Add the signing certificate to the system keychain instead of the login keychain
-
2023
-
Updated the
Notarization
section to use Kitware macOS signing server instead of developer workstation. -
Added
Code Signing Details
section adapted fromPrerequisites
section originally written by Max Smolens and referenced below.
-
-
2022
-
Renamed
macos-codesign-scripts
toslicer-macos-codesign-scripts
-
Transferred
macos-codesign-scripts
repository fromjcfr
GitHub user toKitwareMedical
GitHub organization. -
Jean-Christophe Fillion-Robin updated entitlements to support installing Slicer extensions or python packages providing unsigned libraries. See Slicer#6065
-
-
2020: Jean-Christophe Fillion-Robin updated the signing script and included the required entitlements to support notarization.
-
2018: Jean-Christophe Fillion-Robin created
https://github.com/jcfr/macos-codesign-scripts
adapted from an original script contributed by Chuck Atkins. -
2016: Max Smolens created the original page https://www.slicer.org/wiki/Documentation/Nightly/Developers/Mac_OS_X_Code_Signing.
The steps described below are expected to be performed by a @kitware employee and requires to be connected to the internal network.
For reference, the command below was used to sign the Slicer installers starting with version 4.6.
signtool.exe sign /f "C:\Users\dashboard\Downloads\codecert.pfx" /p <password> /fd sha256 /tr http://timestamp.digicert.com /td sha256 /v "C:\Users\dashboard\Downloads\installer.exe"
Then, with recent version of Slicer, the use of /f "C:\path\to\cert.pfx" /p <password>
was switched with /a
to support use of a hardware token.
/f specifies the path to the code signing certificate
/p specifies the password for the code signing certificate
/a select the best signing cert automatically
/fd specifies the file digest algorithm
/tr specifies the URL of the RFC-3161 timestamp server
/td specifies the digest algorithm to be used by the timestamp server
/v displays verbose output
-
2021: Windows signing semi-automated through private upload on
https://kwgitlab.kitware.com
-
2019: Windows signing semi-automated through private upload on
https://data.kitware.com
-
2016: Max Smolens created the original page https://www.slicer.org/wiki/Documentation/Nightly/Developers/Windows_Code_Signing.