How to Sign macOS Applications With codesign and Notarization
Follow the complete macOS application signing workflow: configure an Apple signing identity, protect the private key, enable Hardened Runtime, sign the application and nested code, add a timestamp, verify the signature, notarize the release, staple the ticket and validate the final artifact.
Core workflow: Build → configure signing → sign nested components → sign the app → verify → package → notarize → staple → Gatekeeper assessment → verify the exact distributed artifact.
What You Need Before Signing a macOS Application
macOS signing depends on the Apple developer environment, the application bundle and the capabilities the application actually uses. Prepare the signing inputs before you begin the release signing step.
.app bundlesecurity find-identity -v -p codesigning
Do not copy signing private keys into source control. Keep the private key in a protected keychain or an appropriate controlled signing environment. Release teams should define access controls and follow a private key protection workflow before automating signing.
Choose a Signing Certificate for macOS Distribution
For software distributed outside the Mac App Store, confirm the appropriate Developer ID signing identity and distribution requirements before preparing the release. Review the macOS-specific certificate option alongside the wider certificate catalog.
Choose the Correct Apple Signing Identity
macOS signing identities are provided through Apple's developer ecosystem. For applications distributed outside the Mac App Store, a Developer ID Application certificate is generally used to sign the application.
security find-identity -v -p codesigning
Look for the appropriate Developer ID Application identity before beginning the signing process. Use the exact identity available in the keychain rather than copying an example identity name into production.
Enable Hardened Runtime
Applications intended for notarization generally need to be configured appropriately for Apple's Hardened Runtime requirements. In Xcode, enable Hardened Runtime from the application's Signing & Capabilities configuration.
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> </dict> </plist>
Use only required entitlements. Incorrect entitlements can cause signing, notarization or application runtime problems.
Sign the macOS Application With codesign
Apple provides the codesign command line utility for signing macOS applications. The platform-specific workflow differs from Windows Authenticode signing, so use the tools and validation steps designed for macOS.
codesign --force --deep --options runtime --sign "Developer ID Application: Your Name" "MyApp.app"
--options runtime
Enables the runtime option used for applicable Hardened Runtime workflows.
--sign
Specifies the exact Apple signing identity from the keychain.
Production note: do not blindly rely on --deep as a substitute for understanding nested code. Frameworks, helper applications and embedded binaries may need to be signed in the appropriate order.
Sign Nested Frameworks and Components
A macOS application may contain frameworks, dynamic libraries, helper applications, embedded executables, plug-ins and other nested code. These components need to be signed correctly as part of the application signing process.
codesign --force --options runtime --sign "Developer ID Application: Your Name" "MyApp.app/Contents/Frameworks/MyFramework.framework"
codesign --force --options runtime --sign "Developer ID Application: Your Name" "MyApp.app"
The exact order depends on the application's bundle structure.
Sign With the Required Entitlements
If the application requires entitlements, provide the appropriate entitlements file when signing. The entitlements should correspond to capabilities the application actually needs.
codesign --force --options runtime --entitlements entitlements.plist --sign "Developer ID Application: Your Name" "MyApp.app"
Incorrect entitlements can cause signing, notarization or runtime problems, so keep them minimal and intentional.
Add a Secure Timestamp
A timestamp helps establish when the signature was created. For production releases, timestamping should be part of the normal signing process, with the timestamp evidence checked during verification. The broader code signing timestamping process explains why trusted time evidence matters.
codesign --force --timestamp --options runtime --sign "Developer ID Application: Your Name" "MyApp.app"
Verify the macOS Application Signature
After signing, verify the exact application bundle using codesign. Verification should happen before packaging and again on the final release artifact. Use a consistent code signature verification process to check the exact bundle that will be distributed.
codesign --verify --deep --strict --verbose=2 "MyApp.app"
codesign --display --verbose=4 "MyApp.app"
Check Gatekeeper Assessment
A valid code signature does not automatically mean that macOS will accept an application through every distribution scenario. Gatekeeper assessment is an important release validation step for applicable outside App Store distribution.
spctl --assess --type execute --verbose "MyApp.app"
Package and Notarize the Application
For software distributed outside the Mac App Store, notarization is an important part of Apple's modern distribution workflow. Code signing and notarization are related but are not the same operation.
xcrun notarytool submit MyApp.zip --keychain-profile "notary-profile" --wait
Protect notarization credentials. Do not embed Apple account passwords or sensitive credentials directly into scripts or source repositories.
Staple the Notarization Ticket
After Apple accepts the submission, staple the notarization ticket to the application or appropriate distribution package.
xcrun stapler staple "MyApp.app"
xcrun stapler validate "MyApp.app"
Verify the Complete Release Artifact
The final artifact should be tested after signing and notarization. Verify the same artifact that will actually be distributed.
codesign --verify --deep --strict --verbose=2 "MyApp.app"
spctl --assess --type execute --verbose "MyApp.app"
xcrun stapler validate "MyApp.app"
Release rule: do not sign one application bundle, modify it afterward and then distribute the modified version.
Protect Signing Keys Across Release Workflows
Signing credentials need controlled access, clear ownership, and a repeatable approval process. Teams evaluating hardware-backed signing can review HSM options before moving signing operations into production automation.
Common macOS Signing Errors
When a release fails, identify whether the problem is the signing identity, nested code, signature integrity, notarization or Gatekeeper assessment.
| Problem | First thing to check |
|---|---|
| Code object is not signed at all | Inspect the application bundle and identify unsigned nested code. |
| Code signature invalid | Check whether the application or a nested component was modified after signing. |
| No identity found | Run security find-identity -v -p codesigning and check the current keychain. |
| Notarization rejected | Review Apple's notarization response, fix the reported issue and resubmit. |
| Gatekeeper rejection | Check the complete signature, trust, notarization and distribution state. |
| Nested component fails verification | Inspect and sign the nested framework, helper, library or embedded executable before signing the main application. |
Automate macOS Code Signing in CI/CD
Frequent application releases benefit from a controlled signing pipeline rather than manual signing on a developer workstation. A documented code signing CI/CD pipeline helps keep credentials, approval steps, and verification gates consistent.
macOS Code Signing Checklist
| Check | Requirement |
|---|---|
| Correct Apple signing identity available | Required |
| Private key protected | Required |
| Application components signed | Required |
| Appropriate entitlements configured | When required |
| Hardened Runtime configured | Required for applicable notarization workflows |
| Timestamp included | Recommended |
| Code signature verified | Required |
| Application notarized | Required for applicable outside App Store distribution |
| Notarization ticket stapled | Recommended for applicable distribution |
| Gatekeeper assessment performed | Recommended |
| Final distributed artifact verified | Required |
Frequently Asked Questions
Is macOS code signing the same as Windows Authenticode?
No. macOS uses Apple's code signing architecture and tools such as codesign, while Windows commonly uses Authenticode and tools such as SignTool.
What command is used to sign a macOS application?
Apple's codesign command line utility is used to sign macOS applications.
Do I need a Developer ID certificate to distribute a Mac application outside the App Store?
For applications distributed outside the Mac App Store, Developer ID signing is generally the relevant Apple signing mechanism. The exact requirements depend on the distribution scenario and the applicable code signing requirements for each platform.
Is code signing the same as notarization?
No. Code signing establishes a cryptographic signature for the application. Notarization is Apple's separate process for checking software submitted for notarization and recording Apple's assessment.
How can I verify a macOS application signature?
Use codesign --verify --deep --strict --verbose=2 "MyApp.app". You can also inspect Gatekeeper's assessment using spctl.
Can macOS signing be automated?
Yes. Signing and notarization can be incorporated into a controlled CI/CD release process, provided signing credentials and private keys are securely managed.
Can I modify an application after signing it?
You should not modify signed code after signing. Changes to signed components can invalidate the signature and require the affected code to be signed again.
Prepare the macOS Release for Distribution
Prepare the final application, select the correct Apple signing identity, configure Hardened Runtime and entitlements where required, sign nested components and the main bundle, timestamp, verify, notarize, staple the ticket, run Gatekeeper assessment, and verify the exact artifact before distribution.
