Demystify code signing and its importance in app development. Get help troubleshooting code signing issues and ensure your app is properly signed for distribution.

Posts under General subtopic

Post

Replies

Boosts

Views

Activity

Unsigned macOS app installed in /Applications does not appear in Launchpad
Hello, I have a macOS app built with Flutter’s macOS target (native Xcode project). The app is unsigned (no Developer ID code signing / notarization). The .app bundle looks valid: CFBundlePackageType = APPL Unique CFBundleIdentifier No LSUIElement or LSBackgroundOnly Executable exists and is runnable Placed at /Applications/MyApp.app (top-level), runs fine from Finder However, it does not show up in Launchpad. What I tried: Remove quarantine: xattr -dr com.apple.quarantine "/Applications/MyApp.app" Force Launch Services registration: /System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister -f "/Applications/MyApp.app" Rebuild LS caches: /System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister -kill -r -domain local -domain system -domain user Reset Launchpad DB and restart Dock: defaults write com.apple.dock ResetLaunchPad -bool true && killall Dock Verified bundle structure/type: mdls -name kMDItemContentType -name kMDItemKind "/Applications/MyApp.app" → shows com.apple.application-bundle / Application Questions Is code signing/notarization required for an app to appear in Launchpad (even if it runs from Finder)? What additional conditions cause Launchpad to skip an otherwise valid, unsigned .app in /Applications? Are there deeper Launch Services or Dock database checks I can run to diagnose why this specific app is excluded?
Topic: Code Signing SubTopic: General Tags:
2
0
165
Aug ’25
Upload failed Validation Issue WKApplication or WKWatchKitApp is required
I added a watchkit extension to an existing app. I get this error when uploading to App Store Connect. Building the archive itself is fine: Prepared archive for uploading Upload failed error: Validation failed Missing Info.plist value. A value for the key “WKApplication”, or “WKWatchKitApp” if your project has a WatchKit App Extension target, is required in “Runner.app/Watch/watch_Watch_App.app” bundle. For details, see: https://developer.apple.com/documentation/watchkit/creating_independent_watchos_apps/setting_up_a_watchos_project have the exact same issue when bundling. I added the flag manually in a additional plist fields entry with WKApplication=1 because my Info.Plist is generated and it didn't help. I wrote a custom Run Script Phase that added the flag and that didn't help as well. I need a reply from someone from Apple here. This needs to be fixed.
5
0
369
Aug ’25
Is there a tutorial or good resource about publishing a Python based app on Apple Store?
Hi guys, Is there any good up-to-date tutorial about publishing a Python based app on Apple Store? Now, I have developed a standalone Python app from PyCharm, and it's using Pyside6 for UI and some major Python libraries. It's a productivity app with a little A.I. features. I used PyInstaller to prepare the app. Currently, I am stuck at the stage of codesign and Apple Review process, because I am manually doing codesign and building the package from command-line. Without using Xcode, things can get messy or miss easily. It would be nice to follow a up-to-date tutorial about how to complete the codesign and Apple Review process for a Python based app. For example, what to do, how to do, what to be careful during the Apple Review process, etc. Thanks!
1
0
176
Aug ’25
App Bundle issue
We have an app which is hybrid using React Native and Native features. We released our app recently which showed issues related to missing packages/corrupt package but xCode didn't gave any error and we were able to Archive and submit app successfully.
Topic: Code Signing SubTopic: General
1
0
210
Aug ’25
Does NSXPCConnection.setCodeSigningRequirement perform dynamic code signature checks?
To validate incoming XPC connections from other executables, we perform SecCode checks for the dynamic signature of the connection (kSecCSDynamicInformation). Reading the setCodeSigningRequirement(_:) function documentation it appears to perform only static signing checks, is that so? If we use setCodeSigningRequirement(:) function in our listener(:, shouldAcceptNewConnection:) do we still need to check the dynamic information to be properly secure?
2
0
401
Aug ’25
Code signing fails with “unable to build chain to self-signed root for signer "(null)"” and errSecInternalComponent for Developer ID Application on macOS
Hello Apple Developer Support Community, I am encountering a persistent issue while trying to code sign my macOS application (PromptVault.app) using a valid Developer ID Application certificate. The signing process fails with the following warning and error for every native .so file inside the app bundle: `Warning: unable to build chain to self-signed root for signer "(null)" <file-path>: errSecInternalComponent` What I have tried so far: Verified that my Developer ID Application certificate and the associated private key exist correctly in the login keychain. Confirmed that the intermediate certificate "Apple Worldwide Developer Relations - G6" is installed and valid in the System keychain. Added Terminal to Full Disk Access in Security & Privacy to ensure signing tools have required permissions. Executed security set-key-partition-list to explicitly allow code signing tools to access the private key. Reinstalled both developer and Apple intermediate certificates. Used codesign to individually sign .so files and then sign the entire bundle. Ensured macOS and Xcode Command Line Tools are up to date. Created a clean Python virtual environment and rebuilt all dependencies. Tested code signing in multiple ways and with verbose logging. Current status: Despite all these efforts, the same warning and error persist during the signing process of every .so file. This prevents successful code signing and notarization, blocking distribution. Request for assistance: Could anyone confirm if my certificate and keychain setup sounds correct? Are there known issues or extra steps necessary to properly build the trust chain for Developer ID certificates on macOS 15.6.1 (Sequoia)? Any suggestions for resolving the errSecInternalComponent during signing native libraries? Guidance on ensuring the entire certificates chain is trusted and usable by codesign tools? I can provide debug logs, screenshots of my keychain and security settings, or any other diagnostic information if needed. Thanks in advance for your help!
1
0
391
Aug ’25
codesign Failure with errSecInternalComponent Error
I am experiencing a persistent issue when trying to sign my application, PhotoKiosk.app, using codesign. The process consistently fails with the error errSecInternalComponent, and my troubleshooting indicates the problem is with how the system accesses or validates my certificate's trust chain, rather than the certificate itself. Error Details and Configuration: codesign command executed: codesign --force --verbose --options=runtime --entitlements /Users/sergiomordente/Documents/ProjetosPhotocolor/PhotoKiosk-4M/entitlements.plist --sign "Developer ID Application: Sérgio Mordente (G75SJ6S9NC)" /Users/sergiomordente/Documents/ProjetosPhotocolor/PhotoKiosk-4M/dist/PhotoKiosk.app Error message received: Warning: unable to build chain to self-signed root for signer "(null)" /Users/sergiomordente/Documents/ProjetosPhotocolor/PhotoKiosk-4M/dist/PhotoKiosk.app: errSecInternalComponent Diagnostic Tests and Verifications Performed: Code Signing Identity Validation: I ran the command security find-identity -v -p codesigning, which successfully confirmed the presence and validity of my certificate in the Keychain. The command output correctly lists my identity: D8FB11D4C14FEC9BF17E699E833B23980AF7E64F "Developer ID Application: Sérgio Mordente (G75SJ6S9NC)" This suggests that the certificate and its associated private key are present and functional for the system. Keychain Certificate Verification: The "Apple Root CA - G3 Root" certificate is present in the System Roots keychain. The "Apple Worldwide Developer Relations Certification Authority (G6)" certificate is present and shown as valid. The trust setting for my "Developer ID Application" certificate is set to "Use System Defaults". Attempted Certificate Export via security: To further diagnose the problem, I attempted to export the certificate using the security find-certificate command with the exact name of my identity. Command executed (using double quotes): security find-certificate -c -p "Developer ID Application: Sérgio Mordente (G75SJ6S9NC)" &gt; mycert.pem Error message: security: SecKeychainSearchCopyNext: The specified item could not be found in the keychain. The same error occurred when I tried with single quotes. This result is contradictory to the output of find-identity, which successfully located the certificate. This suggests an internal inconsistency in the Keychain database, where the certificate is recognized as a valid signing identity but cannot be located via a simple certificate search. Additional Troubleshooting Attempts: I have already recreated the "Developer ID Application" certificate 4 times (I am at the limit of 5), and the issue persists with all of them. The application has been rebuilt, and the codesign command was run on a clean binary. Conclusion: The problem appears to be an internal macOS failure to build the trust chain for the certificate, as indicated by the errSecInternalComponent error. Although the certificate is present and recognized as a valid signing identity by find-identity, the codesign tool cannot complete the signature. The failure to find the certificate with find-certificate further supports the suspicion of an inconsistency within the keychain system that goes beyond a simple certificate configuration issue. I would appreciate any guidance on how to resolve this, especially given that I am at my developer certificate limit and cannot simply generate a new one.
1
0
901
Sep ’25
macOS 26 Launch Constraints
I've recently upgraded to the RC candidates of macOS 26 and Xcode 26. The app I'm building has a helper tool using SMAppService. When I run the app and helper tool in macOS 15 or macOS 26, all works as expected. When it runs on macOS 13 or 14, which previously worked. The helper now crashes on launch with the following reason: Termination Reason: CODESIGNING 4 Launch Constraint Violation I found this developer session which seems to address this, but the plist I've added doesn't seem to satisfy the constraint. https://developer.apple.com/videos/play/wwdc2023/10266/ Here are the contents of my new plist: Are there any gotchas here that I might be missing? Thanks!
12
0
1.3k
Sep ’25
The signature of the binary is invalid
I tried building a macOS app with Electron, but I ran into problems during notarization. I used notarytool to upload my DMG and got status: Invalid. xcrun notarytool log output { "logFormatVersion": 1, "jobId": "680bf475-a5f4-4675-9083-aa755d492b18", "status": "Invalid", "statusSummary": "Archive contains critical validation errors", "statusCode": 4000, "archiveFilename": "BODYPARK-v3.6.0-mac.app.zip", "uploadDate": "2025-09-25T02:50:41.523Z", "sha256": "e61074b9bba6d03696f2d8b0b13870daafc283960e61ab5002d688e4e82ef6f6", "ticketContents": null, "issues": [ { "severity": "error", "code": null, "path": "BODYPARK-v3.6.0-mac.app.zip/BODYPARK-v3.6.0-mac.app/Contents/Resources/plugin/XMagic/mac/libpag.framework/libpag", "message": "The signature of the binary is invalid.", "docUrl": "https://developer.apple.com/documentation/security/notarizing_macos_software_before_distribution/resolving_common_notarization_issues#3087735", "architecture": "x86_64" }, { "severity": "error", "code": null, "path": "BODYPARK-v3.6.0-mac.app.zip/BODYPARK-v3.6.0-mac.app/Contents/Resources/plugin/XMagic/mac/libpag.framework/libpag", "message": "The signature does not include a secure timestamp.", "docUrl": "https://developer.apple.com/documentation/security/notarizing_macos_software_before_distribution/resolving_common_notarization_issues#3087733", "architecture": "x86_64" }, { "severity": "error", "code": null, "path": "BODYPARK-v3.6.0-mac.app.zip/BODYPARK-v3.6.0-mac.app/Contents/Resources/plugin/XMagic/mac/libpag.framework/libpag", "message": "The signature of the binary is invalid.", "docUrl": "https://developer.apple.com/documentation/security/notarizing_macos_software_before_distribution/resolving_common_notarization_issues#3087735", "architecture": "arm64" }, { "severity": "error", "code": null, "path": "BODYPARK-v3.6.0-mac.app.zip/BODYPARK-v3.6.0-mac.app/Contents/Resources/plugin/XMagic/mac/libpag.framework/libpag", "message": "The signature does not include a secure timestamp.", "docUrl": "https://developer.apple.com/documentation/security/notarizing_macos_software_before_distribution/resolving_common_notarization_issues#3087733", "architecture": "arm64" } ] } I checked the signature of my .app file: codesign -v -vvv --deep --strict /Users/zhangheng/Desktop/development/coach-app/dist_electron/mac-universal/BODYPARK-v3.6.0-mac.app/Contents/MacOS/BODYPARK-v3.6.0-mac --prepared:/Users/zhangheng/Desktop/development/coach-app/dist_electron/mac-universal/BODYPARK-v3.6.0-mac.app/Contents/Frameworks/BODYPARK-v3.6.0-mac Helper (GPU).app --validated:/Users/zhangheng/Desktop/development/coach-app/dist_electron/mac-universal/BODYPARK-v3.6.0-mac.app/Contents/Frameworks/BODYPARK-v3.6.0-mac Helper (GPU).app --prepared:/Users/zhangheng/Desktop/development/coach-app/dist_electron/mac-universal/BODYPARK-v3.6.0-mac.app/Contents/Frameworks/BODYPARK-v3.6.0-mac Helper (Plugin).app --validated:/Users/zhangheng/Desktop/development/coach-app/dist_electron/mac-universal/BODYPARK-v3.6.0-mac.app/Contents/Frameworks/BODYPARK-v3.6.0-mac Helper (Plugin).app --prepared:/Users/zhangheng/Desktop/development/coach-app/dist_electron/mac-universal/BODYPARK-v3.6.0-mac.app/Contents/Frameworks/TXFFmpeg.framework/Versions/Current/. --validated:/Users/zhangheng/Desktop/development/coach-app/dist_electron/mac-universal/BODYPARK-v3.6.0-mac.app/Contents/Frameworks/TXFFmpeg.framework/Versions/Current/. --prepared:/Users/zhangheng/Desktop/development/coach-app/dist_electron/mac-universal/BODYPARK-v3.6.0-mac.app/Contents/Frameworks/Electron Framework.framework/Versions/Current/. --prepared:/Users/zhangheng/Desktop/development/coach-app/dist_electron/mac-universal/BODYPARK-v3.6.0-mac.app/Contents/Frameworks/Electron Framework.framework/Versions/Current/Helpers/chrome_crashpad_handler --validated:/Users/zhangheng/Desktop/development/coach-app/dist_electron/mac-universal/BODYPARK-v3.6.0-mac.app/Contents/Frameworks/Electron Framework.framework/Versions/Current/Helpers/chrome_crashpad_handler --validated:/Users/zhangheng/Desktop/development/coach-app/dist_electron/mac-universal/BODYPARK-v3.6.0-mac.app/Contents/Frameworks/Electron Framework.framework/Versions/Current/. --prepared:/Users/zhangheng/Desktop/development/coach-app/dist_electron/mac-universal/BODYPARK-v3.6.0-mac.app/Contents/Frameworks/TXSoundTouch.framework/Versions/Current/. --validated:/Users/zhangheng/Desktop/development/coach-app/dist_electron/mac-universal/BODYPARK-v3.6.0-mac.app/Contents/Frameworks/TXSoundTouch.framework/Versions/Current/. --prepared:/Users/zhangheng/Desktop/development/coach-app/dist_electron/mac-universal/BODYPARK-v3.6.0-mac.app/Contents/Frameworks/BODYPARK-v3.6.0-mac Helper.app --validated:/Users/zhangheng/Desktop/development/coach-app/dist_electron/mac-universal/BODYPARK-v3.6.0-mac.app/Contents/Frameworks/BODYPARK-v3.6.0-mac Helper.app --prepared:/Users/zhangheng/Desktop/development/coach-app/dist_electron/mac-universal/BODYPARK-v3.6.0-mac.app/Contents/Frameworks/BODYPARK-v3.6.0-mac Helper (Renderer).app --validated:/Users/zhangheng/Desktop/development/coach-app/dist_electron/mac-universal/BODYPARK-v3.6.0-mac.app/Contents/Frameworks/BODYPARK-v3.6.0-mac Helper (Renderer).app /Users/zhangheng/Desktop/development/coach-app/dist_electron/mac-universal/BODYPARK-v3.6.0-mac.app/Contents/MacOS/BODYPARK-v3.6.0-mac: valid on disk /Users/zhangheng/Desktop/development/coach-app/dist_electron/mac-universal/BODYPARK-v3.6.0-mac.app/Contents/MacOS/BODYPARK-v3.6.0-mac: satisfies its Designated Requirement It looks like local signing succeeded, but notarization is failing. I’m a beginner with macOS signing/notarization. Could you please help me figure out what I’m doing wrong and how to fix this? I’d really appreciate any guidance.
1
0
294
Sep ’25
Developer ID Installer certificate location
I want to export Mac OS application out side App Store and I need to have Developer Id installer certificate to do the same. When I go to certificate section in developer portal - I only see option of Mac App Distribution Mac Installer Distribution Developer ID Application Does anyone know where I can check the Developer ID installer part. Developer ID application doesn't work for signing the app manually.
1
0
226
Sep ’25
KeyChain Error
I'm experiencing an issue when exporting an Enterprise distribution certificate where the certificate and private key won't export together - the private key keeps getting left out. I'm running macOS Tahoe. Has anyone encountered the same issue or know of a solution? Any help would be appreciated.
Topic: Code Signing SubTopic: General
1
0
448
Dec ’25
Unable to run embedded binary due to quarantine
Hi! I've been scratching my brain for a few days now to no avail. I have a Perl project that I need to embed within my app. Perl includes a pp command (https://metacpan.org/pod/pp) which takes the runtime binary and then slaps the Perl code at the end of the binary itself which in brings some woes in a sense that the binary then needs to be "fixed" (https://github.com/rschupp/PAR-Packer/tree/master/contrib/pp_osx_codesign_fix) by removing the linker-provided signature and fixing LINKEDIT and LC_SYMTAB header sections of the binary. Nevertheless, I've successfully gotten the binary built, fixed up and codesigned it via codesign -s '$CS' mytool (where $CS is the codesigning identity). I can verify the signature as valid using codesign -v --display mytool: Identifier=mytool Format=Mach-O thin (arm64) CodeDirectory v=20400 size=24396 flags=0x0(none) hashes=757+2 location=embedded Signature size=4820 Signed Time=5. 1. 2026 at 8:54:53 PM Info.plist=not bound TeamIdentifier=XXXXXXX Sealed Resources=none Internal requirements count=1 size=188 It runs without any issues in Terminal, which is great. As I need to incorporate this binary in my app which is sandboxed, given my experience with other binaries that I'm including in the app, I need to codesign the binary with entitlements com.apple.security.app-sandbox and com.apple.security.inherit. So, I run: codesign -s '$CS' --force --entitlements ./MyTool.entitlements --identifier com.charliemonroe.mytool mytool ... where the entitlements file contains only the two entitlements mentioned above. Now I add the binary to the Xcode project, add it to the copy resources phase and I can confirm that it's within the bundle and that it's codesigned: codesign -vvvv --display MyApp.app/Contents/Resources/mytool Identifier=com.xxx.xxx.xxx Format=Mach-O thin (arm64) CodeDirectory v=20500 size=24590 flags=0x10000(runtime) hashes=757+7 location=embedded VersionPlatform=1 VersionMin=1703936 VersionSDK=1704448 Hash type=sha256 size=32 CandidateCDHash sha256=0a9f93af81e8e5cb286c3df6e638b2f78ab83a9e CandidateCDHashFull sha256=0a9f93af81e8e5cb286c3df6e638b2f78ab83a9edf463ce45d1cd3f89a6a4a00 Hash choices=sha256 CMSDigest=0a9f93af81e8e5cb286c3df6e638b2f78ab83a9edf463ce45d1cd3f89a6a4a00 CMSDigestType=2 Executable Segment base=0 Executable Segment limit=32768 Executable Segment flags=0x1 Page size=16384 CDHash=0a9f93af81e8e5cb286c3df6e638b2f78ab83a9e Signature size=4800 Authority=Apple Development: XXXXXX (XXXXXX) Authority=Apple Worldwide Developer Relations Certification Authority Authority=Apple Root CA Signed Time=9. 1. 2026 at 5:12:22 PM Info.plist=not bound TeamIdentifier=XXXXX Runtime Version=26.2.0 Sealed Resources=none Internal requirements count=1 size=196 codesign --display --entitlements :- MyApp.app/Contents/Resources/mytool <?xml version="1.0" encoding="UTF-8"?><!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "https://www.apple.com/DTDs/PropertyList-1.0.dtd"><plist version="1.0"><dict><key>com.apple.security.app-sandbox</key><true/><key>com.apple.security.inherit</key><true/></dict></plist> All seems to be in order! But not to Gatekeeper... Attempting to run this using the following code: let process = Process() process.executableURL = Bundle.main.url(forResource: "mytool", withExtension: nil)! process.arguments = arguments try process.run() process.waitUntilExit() Results in failure: process.terminationStatus == 255 Console shows the following issues: default 17:12:40.686604+0100 secinitd mytool[88240]: root path for bundle "<private>" of main executable "<private>" default 17:12:40.691701+0100 secinitd mytool[88240]: AppSandbox request successful error 17:12:40.698116+0100 kernel exec of /Users/charliemonroe/Library/Containers/com.charliemonroe.MyApp/Data/tmp/par-636861726c69656d6f6e726f65/cache-9c78515c29320789b5a543075f2fa0f8072735ae/mytool denied since it was quarantined by MyApp and created without user consent, qtn-flags was 0x00000086 Quarantine, hum? So I ran: xattr -l MyApp.app/Contents/Resources/mytool None listed. It is a signed binary within a signed app. There are other binaries that are included within the app and run just fine exactly this way (most of them built externally using C/C++ and then codesigned exectly as per above), so I really don't think it's an issue with the app's sandbox setup... Is there anyone who would be able to help with this? Thank you in advance!
4
0
403
Jan ’26
Testing a Notarised Product
To ship a product outside of the Mac App Store, you must notarise it. The notary service issues a notarised ticket, and the ultimate consumer of that ticket is Gatekeeper. However, Gatekeeper does not just check the ticket; it also applies a variety of other checks, and it’s possible for those checks to fail even if your notarised ticket is just fine. To avoid such problems showing up in the field, test your product’s compatibility with Gatekeeper before shipping it. To do this: Set up a fresh machine, one that’s never seen your product before. If your product supports macOS 10.15.x, x < 4, the best OS version to test with is 10.15.3 [1]. Download your product in a way that quarantines it (for example, using Safari). Disconnect the machine from the network. It might make sense to skip this step. See the discussion below. Install and use your product as your users would. If the product is signed, notarised, and stapled correctly, everything should work. If not, you’ll need to investigate what’s making Gatekeeper unhappy, fix that, and then retest. For detailed advice on that topic, see Resolving Trusted Execution Problems. Run this test on a fresh machine each time. This is necessary because Gatekeeper caches information about your product and it’s not easy to reset that cache. Your best option is to do this testing on a virtual machine (VM). Take a snapshot of the VM before the first test, and then restore to that snapshot when you want to retest. Also, by using a VM you can disable networking in step 3 without disrupting other work on your machine. The reason why you should disable networking in step 3 is to test that you’ve correctly stapled the notarised ticket on to your product. If, for some reason, you’re unable to do that stapling, it’s fine to skip step 3. However, be aware that this may cause problems for a user if they try to deploy your product to a Mac that does not have access to the wider Internet. For more background on this, see The Pros and Cons of Stapling. [1] macOS 10.15.4 fixes a bug that made Gatekeeper unnecessarily strict (r. 57278824), so by testing on 10.15.3 you’re exercising the worst case. The process described above is by far the best way to test your Gatekeeper compatibility because it accurately tests how your users run your product. However, you can also run a quick, albeit less accurate test, using various command-line tools. The exact process depends on the type of product you’re trying to check: App — Run syspolicy_check like this: % syspolicy_check distribution WaffleVarnish.app This tool was introduced in macOS 14. On older systems, use the older spctl tool. Run it like this: % spctl -a -t exec -vvv WaffleVarnish.app Be aware, however, that this check is much less accurate. Disk image — Run spctl like this: % spctl -a -t open -vvv --context context:primary-signature WaffleVarnish.dmg Installer package — Run spctl like this: % spctl -a -t install -vvv WaffleVarnish.pkg Other code — Run codesign like this: % codesign -vvvv -R="notarized" --check-notarization WaffleVarnish.bundle This command requires macOS 10.15 or later. Share and Enjoy — Quinn “The Eskimo!” @ Developer Technical Support @ Apple let myEmail = "eskimo" + "1" + "@" + "apple.com" Revision history: 2024-12-05 Added instructions for using syspolicy_check. Made other minor editorial changes. 2023-10-20 Added links to Resolving Trusted Execution Problems and The Pros and Cons of Stapling. Made other minor editorial changes. 2021-02-26 Fixed the formatting. 2020-04-17 Added the section discussing spctl. 2020-03-25 First version.
0
0
6.9k
3w
Signing code for older versions of macOS on Apple Silicon
IMPORTANT The underlying issue here (FB8830007) was fixed in macOS 11.3, so the advice in this post is irrelevant if you’re building on that release or later. Note This content is a repost of info from another thread because that thread is not world readable (it’s tied to the DTK programme). A number of folks have reported problems where: They have a product that supports older versions of macOS (anything prior to 10.11). If they build their product on Intel, everything works. If they build their product on Apple Silicon, it fails on those older versions of macOS. A developer filed a bug about this (FB8830007) and, based on the diagnosis of that bug, I have some info to share as to what’s going wrong and how you can prevent it. Let’s start with some background. macOS’s code signing architecture supports two different hash formats: sha1, the original hash format, which is now deprecated sha256, the new format, support for which was added in macOS 10.11 codesign should choose the signing format based on the deployment target: If your deployment target is 10.11 or later, you get sha256. If your deployment target is earlier, you get both sha1 and sha256. This problem crops up because, when building for both Intel and Apple Silicon, your deployment targets are different. You might set the deployment target to 10.9 but, on Apple Silicon, that’s raised to the minimum Apple Silicon system, 11.0. So, which deployment target does it choose? Well, the full answer to that is complex but the executive summary is that it chooses the deployment target of the current architecture, that is, Intel if you’re building on Intel and Apple Silicon if you’re building on Apple Silicon. For example: intel% codesign -d --arch x86_64 -vvv Test664892.app … Hash choices=sha1,sha256 … intel% codesign -d --arch arm64 -vvv Test664892.app … Hash choices=sha1,sha256 … arm% codesign -d --arch x86_64 -vvv Test664892.app … Hash choices=sha256 … arm% codesign -d --arch arm64 -vvv Test664892.app … Hash choices=sha256 … The upshot is that you have problems if your deployment target is less than 10.11 and you sign on Apple Silicon. When you run on, say, macOS 10.10, the system looks for a sha1 hash, doesn’t find it, and complains. The workaround is to supply the --digest-algorithm=sha1,sha256, which overrides the hash choice logic in codesign and causes it to include both hashes: arm% codesign -s - --digest-algorithm=sha1,sha256 Test664892.app arm% codesign -d --arch x86_64 -vvv Test664892.app … Hash choices=sha1,sha256 … % codesign -d --arch arm64 -vvv Test664892.app … Hash choices=sha1,sha256 … Share and Enjoy — Quinn “The Eskimo!” @ Developer Technical Support @ Apple let myEmail = "eskimo" + "1" + "@" + "apple.com"
0
0
2.8k
Jun ’25
Resolving Trusted Execution Problems
I help a lot of developers with macOS trusted execution problems. For example, they might have an app being blocked by Gatekeeper, or an app that crashes on launch with a code signing error. If you encounter a problem that’s not explained here, start a new thread with the details. Put it in the Code Signing > General subtopic and tag it with relevant tags like Gatekeeper, Code Signing, and Notarization — so that I see it. Share and Enjoy — Quinn “The Eskimo!” @ Developer Technical Support @ Apple let myEmail = "eskimo" + "1" + "@" + "apple.com" Resolving Trusted Execution Problems macOS supports three software distribution channels: The user downloads an app from the App Store. The user gets a Developer ID-signed program directly from its developer. The user builds programs locally using Apple or third-party developer tools. The trusted execution system aims to protect users from malicious code. It’s comprised of a number of different subsystems. For example, Gatekeeper strives to ensure that only trusted software runs on a user’s Mac, while XProtect is the platform’s built-in anti-malware technology. Note To learn more about these technologies, see Apple Platform Security. If you’re developing software for macOS your goal is to avoid trusted execution entanglements. You want users to install and use your product without taking any special steps. If, for example, you ship an app that’s blocked by Gatekeeper, you’re likely to lose a lot of customers, and your users’ hard-won trust. Trusted execution problems are rare with Mac App Store apps because the Mac App Store validation process tends to catch things early. This post is primarily focused on Developer ID-signed programs. Developers who use Xcode encounter fewer trusted execution problems because Xcode takes care of many code signing and packaging chores. If you’re not using Xcode, consider making the switch. If you can’t, consult the following for information on how to structure, sign, and package your code: Placing content in a bundle Embedding nonstandard code structures in a bundle Embedding a command-line tool in a sandboxed app Creating distribution-signed code for macOS Packaging Mac software for distribution Gatekeeper Basics User-level apps on macOS implement a quarantine system for new downloads. For example, if Safari downloads a zip archive, it quarantines that archive. This involves setting the com.apple.quarantine extended attribute on the file. Note The com.apple.quarantine extended attribute is not documented as API. If you need to add, check, or remove quarantine from a file programmatically, use the quarantinePropertiesKey property. User-level unarchiving tools preserve quarantine. To continue the above example, if you double click the quarantined zip archive in the Finder, Archive Utility will unpack the archive and quarantine the resulting files. If you launch a quarantined app, the system invokes Gatekeeper. Gatekeeper checks the app for problems. If it finds no problems, it asks the user to confirm the launch, just to be sure. If it finds a problem, it displays an alert to the user and prevents them from launching it. The exact wording of this alert varies depending on the specific problem, and from release to release of macOS, but it generally looks like the ones shown in Apple > Support > Safely open apps on your Mac. The system may run Gatekeeper at other times as well. The exact circumstances under which it runs Gatekeeper is not documented and changes over time. However, running a quarantined app always invokes Gatekeeper. Unix-y networking tools, like curl and scp, don’t quarantine the files they download. Unix-y unarchiving tools, like tar and unzip, don’t propagate quarantine to the unarchived files. Confirm the Problem Trusted execution problems can be tricky to reproduce: You may encounter false negatives, that is, you have a trusted execution problem but you don’t see it during development. You may also encounter false positives, that is, things fail on one specific Mac but otherwise work. To avoid chasing your own tail, test your product on a fresh Mac, one that’s never seen your product before. The best way to do this is using a VM, restoring to a snapshot between runs. For a concrete example of this, see Testing a Notarised Product. The most common cause of problems is a Gatekeeper alert saying that it’s blocked your product from running. However, that’s not the only possibility. Before going further, confirm that Gatekeeper is the problem by running your product without quarantine. That is, repeat the steps in Testing a Notarised Product except, in step 2, download your product in a way that doesn’t set quarantine. Then try launching your app. If that launch fails then Gatekeeper is not the problem, or it’s not the only problem! Note The easiest way to download your app to your test environment without setting quarantine is curl or scp. Alternatively, use xattr to remove the com.apple.quarantine extended attribute from the download before you unpack it. For more information about the xattr tool, see the xattr man page. Trusted execution problems come in all shapes and sizes. Later sections of this post address the most common ones. But first, let’s see if there’s an easy answer. Run a System Policy Check macOS has a syspolicy_check tool that can diagnose many common trusted execution issues. To check an app, run the distribution subcommand against it: % syspolicy_check distribution MyApp.app App passed all pre-distribution checks and is ready for distribution. If there’s a problem, the tool prints information about that problem. For example, here’s what you’ll see if you run it against an app that’s notarised but not stapled: % syspolicy_check distribution MyApp.app App has failed one or more pre-distribution checks. --------------------------------------------------------------- Notary Ticket Missing File: MyApp.app Severity: Fatal Full Error: A Notarization ticket is not stapled to this application. Type: Distribution Error … Note In reality, stapling isn’t always required, so this error isn’t really Fatal (r. 151446728 ). For more about that, see The Pros and Cons of Stapling forums. And here’s what you’ll see if there’s a problem with the app’s code signature: % syspolicy_check distribution MyApp.app App has failed one or more pre-distribution checks. --------------------------------------------------------------- Codesign Error File: MyApp.app/Contents/Resources/added.txt Severity: Fatal Full Error: File added after outer app bundle was codesigned. Type: Notary Error … The syspolicy_check isn’t perfect. There are a few issues it can’t diagnose (r. 136954554, 151446550). However, it should always be your first step because, if it does work, it’ll save you a lot of time. Note syspolicy_check was introduced in macOS 14. If you’re seeing a problem on an older system, first check your app with syspolicy_check on macOS 14 or later. If you can’t run the syspolicy_check tool, or it doesn’t report anything actionable, continue your investigation using the instructions in the following sections. App Blocked by Gatekeeper If your product is an app and it works correctly when not quarantined but is blocked by Gatekeeper when it is, you have a Gatekeeper problem. For advice on how to investigate such issues, see Resolving Gatekeeper Problems. App Can’t Be Opened Not all failures to launch are Gatekeeper errors. In some cases the app is just broken. For example: The app’s executable might be missing the x bit set in its file permissions. The app’s executable might be subtly incompatible with the current system. A classic example of this is trying to run a third-party app that contains arm64e code on systems prior to macOS 26 beta. macOS 26 beta supports arm64e apps directly. Prior to that, third-party products (except kernel extensions) were limited to arm64, except for the purposes of testing. The app’s executable might claim restricted entitlements that aren’t authorised by a provisioning profile. Or the app might have some other code signing problem. Note For more information about provisioning profiles, see TN3125 Inside Code Signing: Provisioning Profiles. In such cases the system displays an alert saying: The application “NoExec” can’t be opened. [[OK]] Note In macOS 11 this alert was: You do not have permission to open the application “NoExec”. Contact your computer or network administrator for assistance. [[OK]] which was much more confusing. A good diagnostic here is to run the app’s executable from Terminal. For example, an app with a missing x bit will fail to run like so: % NoExec.app/Contents/MacOS/NoExec zsh: permission denied: NoExec.app/Contents/MacOS/NoExec And an app with unauthorised entitlements will be killed by the trusted execution system: % OverClaim.app/Contents/MacOS/OverClaim zsh: killed OverClaim.app/Contents/MacOS/OverClaim In some cases running the executable from Terminal will reveal useful diagnostics. For example, if the app references a library that’s not available, the dynamic linker will print a helpful diagnostic: % MissingLibrary.app/Contents/MacOS/MissingLibrary dyld[88394]: Library not loaded: @rpath/CoreWaffleVarnishing.framework/Versions/A/CoreWaffleVarnishing … zsh: abort MissingLibrary.app/Contents/MacOS/MissingLibrary Code Signing Crashes on Launch A code signing crash has the following exception information: Exception Type: EXC_CRASH (SIGKILL (Code Signature Invalid)) The most common such crash is a crash on launch. To confirm that, look at the thread backtraces: Backtrace not available For steps to debug this, see Resolving Code Signing Crashes on Launch. One common cause of this problem is running App Store distribution-signed code. Don’t do that! For details on why that’s a bad idea, see Don’t Run App Store Distribution-Signed Code. Code Signing Crashes After Launch If your program crashes due to a code signing problem after launch, you might have encountered the issue discussed in Updating Mac Software. Non-Code Signing Failures After Launch The hardened runtime enables a number of security checks within a process. Some coding techniques are incompatible with the hardened runtime. If you suspect that your code is incompatible with the hardened runtime, see Resolving Hardened Runtime Incompatibilities. App Sandbox Inheritance If you’re creating a product with the App Sandbox enabled and it crashes with a trap within _libsecinit_appsandbox, it’s likely that you’re having App Sandbox inheritance problems. For the details, see Resolving App Sandbox Inheritance Problems. Library Loading Problem Most library loading problems have an obvious cause. For example, the library might not be where you expect it, or it might be built with the wrong platform or architecture. However, some library loading problems are caused by the trusted execution system. For the details, see Resolving Library Loading Problems. Explore the System Log If none of the above resolves your issue, look in the system log for clues as to what’s gone wrong. Some good keywords to search for include: gk, for Gatekeeper xprotect syspolicy, per the syspolicyd man page cmd, for Mach-O load command oddities amfi, for Apple mobile file integrity, per the amfid man page taskgated, see its taskgated man page yara, discussed in Apple Platform Security ProvisioningProfiles You may be able to get more useful logging with this command: % sudo sysctl -w security.mac.amfi.verbose_logging=1 Here’s a log command that I often use when I’m investigating a trusted execution problem and I don’t know here to start: % log stream --predicate "sender == 'AppleMobileFileIntegrity' or sender == 'AppleSystemPolicy' or process == 'amfid' or process == 'taskgated-helper' or process == 'syspolicyd'" For general information the system log, see Your Friend the System Log. Revision History 2025-08-06 Added the Run a System Policy Check section, which talks about the syspolicy_check tool (finally!). Clarified the discussion of arm64e. Made other editorial changes. 2024-10-11 Added info about the security.mac.amfi.verbose_logging option. Updated some links to point to official documentation that replaces some older DevForums posts. 2024-01-12 Added a specific command to the Explore the System Log section. Change the syspolicy_check callout to reflect that macOS 14 is no longer in beta. Made minor editorial changes. 2023-06-14 Added a quick call-out to the new syspolicy_check tool. 2022-06-09 Added the Non-Code Signing Failures After Launch section. 2022-06-03 Added a link to Don’t Run App Store Distribution-Signed Code. Fixed the link to TN3125. 2022-05-20 First posted.
0
0
12k
Aug ’25