macOS Signing
Sign your macOS applications with Developer ID certificates. KestrelSign handles the complexity of inside-out signing, entitlements, and hardened runtime so you can focus on building your app.
Prerequisites
- A Developer ID Application certificate in your Keychain
- Xcode Command Line Tools installed (
xcode-select --install) - The keychain containing your certificate must be unlocked
Note: KestrelSign uses Apple's native codesign tool
under the hood. It does not modify or replace any system tools -- it orchestrates
them with the correct flags and signing order.
How macOS Signing Works
Apple requires that all distributed macOS applications be signed with a Developer ID certificate and include a hardened runtime. Without this, Gatekeeper will block your application from running on users' machines.
For simple single-binary applications, signing is straightforward. But most real-world applications contain nested components -- frameworks, helper apps, plugins, and dynamic libraries -- that must each be signed individually, from the inside out.
The Signing Process
When you click Sign in your project, KestrelSign performs the following steps:
1. Bundle Analysis
KestrelSign walks your .app bundle and builds a dependency map
of all signable components. It identifies frameworks in
Contents/Frameworks, helper applications, XPC services, plugins,
and any .dylib or .so files.
2. Inside-Out Signing
Components are signed starting from the deepest nested items and working outward. For example, in an Electron app, the signing order would be:
- Dynamic libraries within Electron Framework
- Electron Framework itself
- Helper applications (GPU, Renderer, Plugin helpers)
- The main application binary
- The outer
.appbundle
3. Entitlements
KestrelSign applies the entitlements you configured in your project settings. The hardened runtime entitlement is always included, as Apple requires it for notarization. Additional entitlements you may need include:
- Allow JIT -- required for apps that use just-in-time compilation
- Allow unsigned executable memory -- needed for some frameworks that load code dynamically
- Disable library validation -- allows loading third-party frameworks not signed with the same team ID
- Allow DYLD environment variables -- permits use of DYLD_LIBRARY_PATH and similar variables
4. Verification
After signing, KestrelSign automatically verifies the signature using
codesign --verify --deep --strict and reports the result.
If verification fails, the log will contain details about which component
has an issue.
Keychain Management
KestrelSign needs access to the keychain that contains your Developer ID certificate. The setup wizard detects available keychains and certificates automatically.
If your certificate is in a non-default keychain, you may need to unlock it before signing. KestrelSign can prompt for the keychain password or you can unlock it in advance using Keychain Access.
Common Issues
Code signature invalid
Usually caused by a component being modified after signing or by signing in the wrong order. Let KestrelSign handle the signing order -- if you see this error, try a clean re-sign.
No identity found
The certificate cannot be found in the specified keychain. Check that your Developer ID certificate is installed and that the keychain is unlocked. Run the setup wizard to diagnose.
Resource fork, Finder information, or similar detritus not allowed
This happens when files have extended attributes that interfere with signing. KestrelSign can strip these automatically before signing. Check your project settings if you encounter this.