MacOS Codesign Binaries with Custom Certificates
A script to codesign MacOS binaries with a custom certificate(different from the logged in keychain).
It first creates a temporary keychain, imports the certificate, signs the binary and then deletes the keychain.
This is useful when dealing with multiple local accounts and for CI/CD pipelines where you need to codesign the binaries before distributing them.
The following environment variables are required in a .env
file
bash
APPLE_SIGNING_IDENTITY="Developer ID Application: NAME (XXXXXXXXXX)"
APPLE_CERTIFICATE=<certificate_content_in_base64_for_codesign>
APPLE_CERTIFICATE_PASSWORD=<certificate_password>
ENTITLEMENTS=<path to entitlements>
BINARY_PATH=<path to binary file to codesign>
This expects the certificate in base64. If it's already in .p12
, use it directly in the script.
Code on Github Gist -
NOTE
Remove the --options runtime
argument when not signing executables with hardened runtime.
Using it for quicklookjs in 3dviewer.xyz
Related -
- Create and destroy temporary keychains - https://stackoverflow.com/a/44138621/2229899
- macos-sign script in tauri v2 - https://github.com/tauri-apps/tauri/blob/073bb4f459a923541b94970dfa7e087bccaa2cfd/tooling/macos-sign/src/keychain.rs#L1
- Apple - Common notarisation issues - https://developer.apple.com/documentation/security/resolving-common-notarization-issues
Script
bash
#!/bin/bash
keychains=$(security list-keychains -d user)
keychainNames=();
for keychain in $keychains
do
basename=$(basename "$keychain")
keychainName=${basename::${#basename}-4}
keychainNames+=("$keychainName")
done
echo "User keychains on this machine: ${keychainNames[@]}";
# Create a temporary keychain
KEYCHAIN_NAME="temp-code-sign.keychain"
KEYCHAIN_PASSWORD="temp_password"
security create-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_NAME"
# Unlock the keychain
security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_NAME"
# Import the certificate to the keychain
echo "$APPLE_CERTIFICATE" | base64 --decode > cert.p12
security import cert.p12 -k "$KEYCHAIN_NAME" -P "$APPLE_CERTIFICATE_PASSWORD" -T /usr/bin/codesign -T /usr/bin/pkgbuild -T /usr/bin/productbuild
security set-keychain-settings -t 3600 -u "$KEYCHAIN_NAME"
# Set keychain search list
security list-keychains -d user -s "$KEYCHAIN_NAME" "${keychainNames[@]}"
# Allow codesign to access the keychain
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$KEYCHAIN_PASSWORD" "$KEYCHAIN_NAME"
#echo 'Keychain setup complete'
#echo "$APPLE_SIGNING_IDENTITY $BINARY_PATH $ENTITLEMENTS"
# Sign the binary
codesign --sign "$APPLE_SIGNING_IDENTITY" --force --keychain "$KEYCHAIN_NAME" --entitlements "$ENTITLEMENTS" --options runtime "$BINARY_PATH"
# Note above --options runtime only required for executables
# Clean up
security delete-keychain "$KEYCHAIN_NAME"
rm cert.p12