Skip to content

Signing macOS Executables

Requirements

  • App-Specific password
  • Developer ID Application certificate
    • Certificate file (developerID_application-2023.cer)
    • Private key (developerID_application-2023.p12)
  • Developer ID Installer certificate
    • Certificate file (developerID_installer-2023.cer)
    • Private key (developerID_installer-2023.p12)

How to generate an app-specific password

  1. Sign in to appleid.apple.com.
  2. In the Sign-In and Security section, select App-Specific Passwords.
  3. Select Generate an app-specific password or select the Add button Blue plus sign icon, then follow the steps on your screen.
  4. Enter or paste the app-specific password into the password field of the app.

Generate and Managing Certificates

Certificates may be found in the Certificate, Identities & Profiles page in the Apple Developer site. For our purposes we need an admin to manually grant these certificates for us.

The Installer certificate will be used to sign the executable and the Application certificate will be used to sign the .pkg file that contains the executable:

drs_downloader.pkg  <- the macOS installer package (signed with Developer ID Installer cert)
└── drs_downloader  <- the macOS executable (signed with Developer ID Application cert)

Importing Certificates into Keychain

  1. Create a new keychain: File > New Keychain...
  2. Import the two certificate files (.cer) and the two private keys (.p12): File > Import Items...
  3. Verify that the certificates are in the My Certificates section of the keychain.

Signing and Notarizing

Get certificate information required for signing:

security find-identity -p codesigning -v
# 1) 8F4A703A12915B3D0AAC50CA28F0FDE0BBB9C7EC "Developer ID Application: Oregon Health & Science University Apps (ZA685R3CWP)"
# 2) B28C698CDE4BC47C6647C8231528AA18919773D5 "Developer ID Installer: Oregon Health & Science University Apps (ZA685R3CWP)"
#    2 valid identities found
  • 1) is the Application certificate used to sign the executable
  • 2) is the Installer certificate used to sign the installer

Sign the drs_downloader executable located in the build directory:

codesign --sign "Developer ID Application: Oregon Health & Science University Apps (ZA685R3CWP)" --timestamp --force --options=runtime --verbose ./build/drs_downloader
# drs_downloader: signed Mach-O thin (arm64) [drs_downloader]

Build and sign the installer package:

productbuild --sign "Developer ID Installer: Oregon Health & Science University Apps (ZA685R3CWP)" --resources ./resources --distribution ./distribution.xml drs_downloader.pkg
# productbuild: Using timestamp authority for signature
# productbuild: Signing product with identity "Developer ID Installer: Oregon Health & Science University Apps (ZA685R3CWP)" from keychain /Users/turing/Library/Keychains/ACED-development.keychain-db
# productbuild: Adding certificate "Developer ID Certification Authority"
# productbuild: Adding certificate "Apple Root CA"
# productbuild: Wrote product to drs_downloader.pkg

Submit the installer package to Apple's notarization service:

xcrun notarytool submit drs_downloader.pkg --apple-id turing@ohsu.edu --team-id ZA685R3CWP
# Conducting pre-submission checks for drs_downloader.pkg and initiating connection to the Apple notary service...
# Password for turing@ohsu.edu:
# Submission ID received
#   id: da5dc982-9636-49ff-8ffb-1ce0aaf77c5b
# Upload progress: 100.00% (7.62 MB of 7.62 MB)
# Successfully uploaded file
#   id: da5dc982-9636-49ff-8ffb-1ce0aaf77c5b
#   path: /Users/turing/drs_downloader/build/drs_downloader.pkg

Wait for the notarization process to complete ("status": "Accepted", should take only a couple minutes):

xcrun notarytool log da5dc982-9636-49ff-8ffb-1ce0aaf77c5b --apple-id turing@ohsu.edu --team-id ZA685R3CWP
# {
#   "logFormatVersion": 1,
#   "jobId": "da5dc982-9636-49ff-8ffb-1ce0aaf77c5b",
#   "status": "Accepted",
#   "statusSummary": "Ready for distribution",
#   "statusCode": 0,
#   "archiveFilename": "drs_downloader.pkg",
#   "uploadDate": "2023-06-28T16:36:02.450Z",
#   "sha256": "a1aa6c43203da365a595223dd7721d07be2d88e0541a715fd880d2f393568c74",
#   "ticketContents": [
#     {
#       "path": "drs_downloader.pkg/drs_downloader",
#       "digestAlgorithm": "SHA-256",
#       "cdhash": "accc6b8433faa0ac1fc6dca9623330b1bbc6dd6b",
#       "arch": "arm64"
#     }
#   ],
#   "issues": null
# }

Append the notarization results to the installer package:

xcrun stapler staple drs_downloader.pkg
# Processing: /Users/turing/drs_downloader/drs_downloader.pkg
# The staple and validate action worked!

The executable (and the package) are now signed and ready to share with users!

Resources