Hi, I am a long time programmer in C#, and newer to Rust, and a rookie to MacOS 15.1.
Over the past few days I have made numerous attempts to run a Rust GUI binary that I compiled on Mac.
Here are some examples of things I have tried using.
Executable compiled in M1 mac not running on Apple Silicon Mac - help - The Rust Programming Language Forum
And here....
How to run unsigned apps in macOS 15.1
Also here... "sudo spctl --master-disable"
There are many more that I have tried.
I also tried moving the binary from my developer folder to the Application folder and running....
xattr -r -d com.apple.quarantine /Applications/csv
Note that "csv" is the name of my binary.
You have probably seen this 100 times, so can you point me to me to something that allows my Rust binaries to run under MacOS?
PS The Rust program code works just fine under Linux. I can either type Cargo Run and run the binary from the Terminal or go directly to the executable and double click on it to open the GUI application. The only thing that MacOS lets me do it open the GUI from the Terminal. Commander One says that I do not have the proper credentials to open the file directly. Finder also does not allow me to open the binary directly.
Thanks, Jim
Gatekeeper
RSS for tagGatekeeper on macOS helps protect users from downloading and installing malicious software by checking for a Developer ID certificate from apps distributed outside the Mac App Store.
Posts under Gatekeeper tag
44 Posts
Sort by:
Post
Replies
Boosts
Views
Activity
I built Mac app with Electron-forge and sign and notarize my app with Developer ID Application Certification and @electron/osx-sign, @electron/notarize module.
I built my app on macOS Sonoma 14.7.
Then I ran the built app on other mac with "App Store and identified developers" Gatekeeper of macOS version 12.7.3 And it worked well.
But when I ran it on another mac PC of macOS Sonoma 14.4.1, it said my app is damaged.
Why does it happen and How can I solve this issue?
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.
I am working on releasing my macOS arm64 app. My problem is that after the user downloads the dmg, double-clicking my.app in the dmg, a Gatekeeper pop-up box will appear with a warning that the developer cannot be verified.
Question: Can an application signed with "com.apple.security.cs.disable-library-validation" be published as trusted?
If yes, what steps have I missed?
If not, can I get an official response from Apple?
(Because I referred to this post, it seems to mention that it is possible to publish trusted software.I have looked up similar questions on the forum and tried many things, but nothing works. )
Here are my steps:
Use the codesign to sign my.app. Because my app needs to access third-party dynamic libraries, entitlements.plist contains a "com.apple.security.cs.disable-library-validation". After the "codesign -dvvv" check, the signature was successful.✅
Use the "xcrun notarytool" command to notarize my app, and the status is displayed as accepted.✅
Use "xcrun stapler staple" to attach the notarization to my app, and it returns success.✅
Use the "spctl -a -v " command to verify whether my app has passed Gatekeeper, and it returns that it has passed.✅
Then I packaged my.app into a dmg, and then attached the notarization mark to the dmg, which was successful.✅
I completed the above steps and distributed the dmg. When I downloaded the dmg as a user test and double-clicked my.app in it, the Gatekeeper pop-up box still appeared, and the developer cannot be verified.❌
We get a "The application "Finder" does not have permission to open "(null)“" error message in macOS 15.1 when trying to open unsigned applications.
Is this a known bug in macOS 15.1 ? If so any indications of whether it will be fixed in the future.
In macOS 15.0.1 the workaround for launching unsigned applications still worked.
Adobe says that Animate works with the latest Mac OS.
When I publish apps with Animate, they work on my computer.
With a self-signed certificate, they work on some older Mac OS versions, but not on the 2 most recent.
How can I test my apps on others' Mac computers?
Robert
Hello I build an application in Xcode for MacOS. But the exported app I cannot open on different Mac systems. I get the message 'The application X can't be opened'. I can only run the application on the Mac where Xcode is installed.
I used different signing certificates: Apple Distribution, Developer ID application (this should be the one), Mac App Distribution.
I archive the application, then use Direct Distribution, then after complished the notary service, I export the app.
I am creating a macOS app with the following requirements:
Automatic Startup: After initial installation, the app should automatically start, even after the OS restarts.
Notarized Installation: The installation package (.pkg) should be notarized to avoid user have to make security exception.
In my current setup I’ve created a script, ci_scripts/ci_post_xcodebuild.sh, which uploads the package file $CI_APP_STORE_SIGNED_APP_PATH/<appName>.pkg to GitHub via Xcode Cloud. While I can successfully download the app, I’m encountering two main issues:
Notarization (I assume): I’m unsure how to get Xcode Cloud to notarize the .pkg file. Currently, upon opening the .pkg file for the first time, users have to go to System Settings > Privacy & Security to allow an exception for the package, after which installation proceeds successfully on second try. I’d like to automate the notarization process to eliminate this extra step.
Adding Additional Files to PKG installer: My current .pkg file only includes the app binary. I need to configure Xcode Cloud to include a postinstall script and a launchd daemon configuration file within the package. This would ensure that necessary files are set up on installation and that the app is properly registered as a launch daemon.
Hi all,
I found an issue by chance where, when we copy an .app bundle (a large one), Gatekeeper can choose to try to scan the app before the file copying finishes (without the app having been launched). This of course fails, and then the app can't open because "it's damaged", even though spctl and codesign checks of the completed copied app come out fine. Then Gatekeeper remembers this setting forever, not rescanning the app.
I'm wondering if anyone else has seen this happen and if so, if there's a best practice for keeping Gatekeeper's hands off until the copy is done?
I imagine copying into a folder not named .app, then renaming it might work, or maybe saving the plist or main binary copy until last, although both require a more complex copy operation.
Maybe there's a more elegant way?
Thanks!
In the past, I used to export a developer-signed test version of my macOS app in Xcode, create a zip archive from the Finder, upload it to my website and share the link to the testers. The last time I did this with macOS 14 the tester was still able to download the test app and run it.
But it seems that with macOS 15 the trick to open the context menu on the downloaded app and click Open to bypass the macOS warning that the app couldn't be checked when simply double-clicking it, doesn't work anymore. Now I'm always shown an alert that macOS couldn't check the app for malware, and pushes me to move it to the bin.
In this StackOverflow topic from 10 years ago they suggested to use ditto and tar to compress and uncompress the app, but neither worked for me.
How can I share macOS apps that I signed myself with testers without physically handing them a drive containing the uncompressed app?
Hi, my app's direct distribution archive is stuck at "In progress" state in Organizer window.
What is wrong with it? What should I do?
Thank you.
Topic:
App Store Distribution & Marketing
SubTopic:
App Review
Tags:
Xcode
macOS
Gatekeeper
Notarization
I am packaging an app with QtWebEngine in it, after codesign the app and the QtWebEngine Framework, the app can run properly.
The codesign result is:
valid on disk
staisfies its Designated requirements
Then I notarized and stapled the dmg file, after the dmg installed on Mac, gatekeeper still failed the check.
Here is the result for spctl:
spctl -a -t open -vvv --context context:primary-signatue Remote\ Graphics\ Workstation_.dmg
Remote Graphics Workstation_.dmg: rejected
source=Insufficient Context
Need help to identify the codesign process and the root cause why gatekeeper fail here, thanks.
We have a native ARM64 application. The application is a development environment and native compiler for the language Common Lisp. CL has a foreign function interface, which allows loading of .dylib files into CL and calling functions in them from CL. For this reason, we add certain entitlements. See below.
It is notarized and installed on macOS 14.7. When I run spctl on it I get this:
$ spctl --assess -v /Applications/AllegroCL64.app
/Applications/AllegroCL64.app: rejected (the code is valid but does not seem to be an app)
That’s before I run it. Which is odd because the app is notarized. When I run the app, it asks for a license file and installs it into /Applications/AllegroCL64.app/Contents/Resources/ and after that, the spctl shows this:
$ spctl --assess -v /Applications/AllegroCL64.app
/Applications/AllegroCL64.app: a sealed resource is missing or invalid
I assume the mere act of copying the license (a file called devel.lic which is a small text file) is causing this. Why does it say it “does not seem to be an app”?
This self-modification of the files in the Contents/Resources directory is a huge feature. We allow downloading of patches, which add features and fix bugs in the product. Is this going to be a problem, going forward? I don’t remember seeing this result from spctl before and I have a feeling it’s a new , due to tightening of security policies, etc.
All of this is quite worrying to us.
More details of the app:
$ codesign -vvvv mlisp
mlisp: valid on disk
mlisp: satisfies its Designated Requirement
$ codesign -d --entitlements - /Applications/AllegroCL64.app
Executable=/Applications/AllegroCL64.app/Contents/MacOS/AllegroCL64
[Dict]
[Key] com.apple.security.cs.allow-dyld-environment-variables
[Value]
[Bool] true
[Key] com.apple.security.cs.allow-jit
[Value]
[Bool] true
[Key] com.apple.security.cs.disable-library-validation
[Value]
[Bool] true
[Key] com.apple.security.get-task-allow
[Value]
[Bool] true
$
Other details:
The app was built with the Command Line tools version 2395 on macOS 12.x.
App is signed, notarized and stapled, I send that dmg file with file transfer tool, it can open correctly on other mac without any warning or error. However, if I send that dmg file through IM to the same mac, it will produces the "cannot check it for malicious software" error.
I check the transfered dmg with spctl -a -t open -vvv --context context:primary-signature MyApp.dmg, it show source=Notarized Developer ID; origin=***
How can I resolve this issue?
Trusted execution is a generic name for a Gatekeeper and other technologies that aim to protect users from malicious code.
General:
DevForums tag: Gatekeeper
Developer > Signing Mac Software with Developer ID
Apple Platform Security support document
Safely open apps on your Mac support article
Hardened Runtime document
WWDC 2022 Session 10096 What’s new in privacy covers some important Gatekeeper changes in macOS 13 (starting at 04: 32), most notably app bundle protection
WWDC 2023 Session 10053 What’s new in privacy covers an important change in macOS 14 (starting at 17:46), namely, app container protection
WWDC 2024 Session 10123 What’s new in privacy covers an important change in macOS 15 (starting at 12:23), namely, app group container protection
Updates to runtime protection in macOS Sequoia news post
Testing a Notarised Product DevForums post
Resolving Trusted Execution Problems DevForums post
App Translocation Notes DevForums post
Most trusted execution problems are caused by code signing or notarisation issues. See Code Signing Resources and Notarisation Resources.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
This post is part of a cluster of posts related to the trusted execution system. If you found your way here directly, I recommend that you start at the top.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
Resolving Gatekeeper Problems
Gatekeeper strives to ensure that only trusted software runs on a user’s Mac. It’s important that your code pass Gatekeeper. If not, you’re likely to lose a lot of customers, and your users’ hard-won trust.
There are four common Gatekeeper problems:
App blocked by a dangling load command path
Broken code signature
Lack of notarisation
Command-line tool blocked by Gatekeeper
The first problem is by far the most common. For the details, see Resolving Gatekeeper Problems Caused by Dangling Load Command Paths.
For general information about Gatekeeper, read Apple > Developer > Signing Mac Software with Developer ID and Apple > Support > Safely open apps on your Mac.
IMPORTANT This post focuses on Developer ID-signed code. Gatekeeper should not block App Store apps. If an app downloaded from the App Store fails to run, it’s likely to be some other trusted execution issue. For more about this, read Resolving Trusted Execution Problems.
macOS 14 introduced gktool, a very minimal interface to Gatekeeper. Run the tool with the help argument to learn more:
% gktool help
Verify Your Signature
A good first step in any Gatekeeper investigation is to verify that your code is signed correctly. Use the codesign tool for this:
% codesign -v -vvv --strict --deep MyApp.app
The -vvv options increase verbosity to the point where codesign will give you useful diagnostics. For example:
% codesign -v -vvv --strict --deep "Munged.app"
Munged.app: a sealed resource is missing or invalid
file added: …/Munged.app/Contents/Resources/names/Adam.txt
file modified: …/Munged.app/Contents/Resources/names/Morgan.txt
file missing: …/Munged.app/Contents/Resources/names/Rhonda.txt
This app was changed after it was signed in three different ways:
Adam.txt was added.
Morgan.txt was modified.
Rhonda.txt was removed.
You might see some results that make no sense. For example:
Start with an app with a valid code signature:
% codesign -v -vvv --strict --deep "NotNormal.app"
NotNormal.app: valid on disk
NotNormal.app: satisfies its Designated Requirement
Use the Finder to create a zip archive (File > Compress).
Use the Finder to unpack that archive.
Check the code signature of the unpacked file:
% codesign -v -vvv --strict --deep "NotNormal 2.app"
NotNormal 2.app: a sealed resource is missing or invalid
file added: …/NotNormal 2.app/Contents/Resources/names/Zoë Schrödinger.txt
file missing: …/NotNormal 2.app/Contents/Resources/names/Zoë Schrödinger.txt
There are two things to note here. First, just compressing and decompressing the app broke its code signature. Weird! Second, look at the error messages. It seems that the Zoë Schrödinger.txt file is was both added and removed. Weirder!
To see what’s going on here you have to look at a hex dump of the file name:
% ls "NotNormal.app/Contents/Resources/names" | xxd
00000000: 5a6f c3ab 2053 6368 726f cc88 6469 6e67 Zo.. Schro..ding
00000010: 6572 2e74 7874 0a er.txt.
% ls "NotNormal 2.app/Contents/Resources/names" | xxd
00000000: 5a6f 65cc 8820 5363 6872 6fcc 8864 696e Zoe.. Schro..din
00000010: 6765 722e 7478 740a ger.txt.
The names are not the same! The app started out with the ë in precomposed form and the ö in decomposed form. Compressing and decompressing the app converted the ë to its decomposed form, and that change broke the code signature.
Programs that deal with Unicode are expected to ignore differences in normalisation. Sadly, Apple’s code signing implementation missed that memo (r. 68829319). For more details see this post but the executive summary is that it’s best to stick to ASCII when naming files in a bundle.
Identify a Notarisation Problem
Gatekeeper requires that your app be notarised. If not, it will block the execution of your app with a generic, user-level message. If you find your app blocked by Gatekeeper, check if this is a notarisation issue by looking in the system log for an entry like this:
type: info
time: 2022-05-11 14:57:21.812176 -0700
process: syspolicyd
subsystem: com.apple.syspolicy
category: default
message: ticket not available: 2/2/8b7410713591e6c79ea98f0132136f0faa55d22a
Note If the ticket details show as <private>, enable private data in the system log. For information on how to do that, see Recording Private Data in the System Log. For general information about the system log, see Your Friend the System Log.
The long hex number is the code directory hash, or cdhash, of the offending code. In this example, it’s the cdhash of the app itself:
% codesign -d -vvv /Applications/NotNotarised.app
…
CDHash=8b7410713591e6c79ea98f0132136f0faa55d22a
…
However, in some cases it may be the cdhash of some library referenced by the app.
For more information about cdhashes, see TN3126 Inside Code Signing: Hashes.
Resolve a Notarisation Problem
The obvious cause of this problem is that you haven’t notarised your app. For information on how to do that, see Notarizing macOS Software Before Distribution.
If you have notarised your app and yet you still see this problem, something more subtle is happening. For example, your app might reference a dynamic library that wasn’t seen by the notary service.
To investigate this:
Fetch the notary log for your app. For advice on that, see Fetching the Notary Log.
Confirm that the notary log matches the app you installed. Look in the notary log for the sha256 property. Its value is a SHA-256 hash of the file received by the notary service. Check that this matches the SHA-256 hash of the file you used to install your app. If not, see Hash Mismatch, below.
Search the notary log for the cdhash value from the Gatekeeper log message.
If the notary log doesn’t contain that cdhash, that code wasn’t included in the notarised ticket. It’s possible that you failed to submit the code to the notary service, that it was switched out with a different version after you notarised your app, that it was package in some way that the notary service couldn’t see it, or that something went wrong within the notary service.
Hash Mismatch
If you stapled your notarised ticket to the file used to install your app then the hashes in step 2 of the previous section won’t match. What to do depends on the file type:
If the file used to install your app was a zip archive (.zip), you definitely have the wrong file. Zip archives don’t support stapling.
If the file used to install your app was a signed disk image (.dmg), compare the disk image’s cdhash with the cdhash for the disk image in the notary log. If those match, you know you’re working with the same disk image.
To dump a disk image’s cdhash, run the codesign tool as follows:
% codesign -d -vvv DISK_IMAGE
…
CDHash=d963af703ac2e54af6609e9ad309abee7b66fae2
…
Replace DISK_IMAGE with the path to your disk image.
If the file used to install your app was a disk image but it wasn’t signed, switch to a signed disk image. It’s generally a better option.
If the file used to install your app was an installer package (.pkg), there’s no good way to know if this is the correct package. In this case, modify your notarisation workflow to retain a copy of the file before it was modified by stapler.
Tool Blocked by Gatekeeper
If your product includes a command-line tool, you might notice this behaviour:
When you double click the tool in Finder, it’s blocked by Gatekeeper.
When you run the tool from within Terminal, it works.
This is a known bug in macOS (r. 58097824). The issue is that, when you double click a tool in the Finder, it doesn’t run Gatekeeper’s standard execution logic. Rather, the Finder passes the tool to Terminal as a document and that opens a window (and associated shell) in which to run that document. This triggers Gatekeeper’s document logic, and that logic always blocks the tool.
There are two ways around this:
Embed your tool in an application. If the user runs the application first, Gatekeeper runs its normal application check. If the user allows the app to run, Gatekeeper records that decision and applies it to the app and any code within the app, including your tool.
Install your tool using an installer package. When the user goes to install the package, Gatekeeper checks it. Assuming that check passes, Gatekeeper does no further checks on the content it installed.
Revision History
2024-11-11 Added a mention of gktool.
2022-05-20 Added the Verify Your Signature section. Made other minor editorial changes.
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. Make sure to add relevant tags — like Gatekeeper, Code Signing, and Notarization — so that I see your post.
IMPORTANT macOS 14 has a new tool, syspolicy_check, that was specifically designed to help diagnose problems like this. I plan to update this post once I have more experience with it. In the meantime, however, if you hit a trusted execution problem and it reproduces on macOS 14, please try out syspolicy_check and let us know how that pans out.
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. The remaining sections address the most common ones.
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.
macOS requires that third-party kernel extensions use the arm64e architecture. In other circumstances, stick to arm64 for your shipping products. If you want to test arm64e code locally, see Preparing Your App to Work with Pointer Authentication.
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 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
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.
Hi,
I've recently observed a sudden increase in support requests for one of my apps on the Mac App Store, reporting the error " is damaged and can't be opened. Please re-download it from the Mac App Store", all on different systems: macOS 12, macOS 13, and macOS 15 Sequoia.
Re-downloading does not resolve the issue most of the time.
One user reported that being connected to the internet resolved it - perhaps this is an OCSP issue again?
I myself cannot reproduce this issue.
Has there been a change in code-signing recently? Have some certificates changed? Anything else I should be aware of?
What is the best course of action to have users take who experience this, when re-downloading the app from the Mac App Store does not work?
Thank you,
– Matthias
I have tried to manually install binaries using Finder by clicking and dragging from the Desktop into "/usr/local/bin/". The binaries come with a collection of frameworks etc. All the binaries are adhoc signed. macOS asks for Admin credentials which is fine. But then, when I execute the binaries in Terminal, Gatekeeper shows the now expected "'[binary"] Not Opened Apple could not verify ........" etc. It shows that dialog for every component and requires user input 2-3 times to allow each component of which there are perhaps dozens.
BUT, none of that happens if I install those binaries using AppleScript. So, it might have a call like this:
do shell script "curl -L " & download_URL & " -o " & download_binary_zip with administrator privileges
do shell script "unzip -o " & download_binary_zip & " -d " & usr_bin_folder with administrator privileges
The resulting installs work perfectly.
Is this intended ? Using both install methods requires Admin credentials. Why does using a script work but using Finder does not ?
Hello all,
I am building a macOS application that I codesign and notarize for distribution. I am able to download my zip, unzip and run my application successfully, but when I attempt to update to a new version I hit an error with ditto that "operation not permitted" when attempting to replace my .app with the new version.
For example, here is a sample output of the failure:
Update failed: binary update failed during ditto:
ditto: /Applications//tooler.app/Contents/_CodeSignature/CodeResources: Operation not permitted
ditto: /Applications//tooler.app/Contents/MacOS/tooler: Operation not permitted
ditto: /Applications//tooler.app/Contents/Resources/icons.icns: Operation not permitted
ditto: /Applications//tooler.app/Contents/Info.plist: Operation not permitted
My application code updates the user to a new version by executing a curl command to download the versions zip and then uses ditto to unzip. I am able to successfully download the zip with the curl command and remove the file with the rm command, but when I try to use ditto to copy and replace my application contents it fails. Here is my application code that does that (The directories are correct for the application and the zip is downloaded):
// Download the zip (Works)
homeDir, _ := os.UserHomeDir()
downloadPath := filepath.Join(homeDir, "Downloads", "tooler.zip")
err := exec.Command("curl", "-L", "-H", "Accept: application/octet-stream", "-H", "Authorization: Bearer REMOVED_TOKEN", "-H", "X-GitHub-Api-Version: 2022-11-28", release.AssetURL, "-o", downloadPath).Run()
if err != nil {
return fmt.Errorf("binary update failed during curl: %v", err)
}
// Get the executeable path (Works)
cmdPath, err := os.Executable()
appPath := strings.TrimSuffix(cmdPath, "tooler.app/Contents/MacOS/tooler")
if err != nil {
appPath = "/Applications/"
}
// Cleanup function to remove the downloaded .zip (Works)
defer func() {
err = exec.Command("rm", downloadPath).Run()
if err != nil {
// return fmt.Errorf("binary update failed during removal: %v", err)
}
}()
// Update application contents (This fails from the operation not permitted)
cmd := exec.Command("ditto", "-xk", downloadPath, appPath)
var out bytes.Buffer
var stderr bytes.Buffer
cmd.Stdout = &out
cmd.Stderr = &stderr
err = cmd.Run()
if err != nil {
return fmt.Errorf("binary update failed during ditto: %v \n Args: %v \n CmdPath: %v \n AppPath %v", stderr.String(), cmd.Args, cmdPath, appPath)
}
return nil
Also, here are my entitlements:
<?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>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.network.client</key>
<true/>
<key>com.apple.security.network.server</key>
<true/>
<key>com.apple.security.files.user-selected.read-write</key>
<true/>
<key>com.apple.security.files.downloads.read-write</key>
<true/>
</dict>
</plist>
Anyone have any ideas on why the ditto command won't let me update the application contents and returns operation not permitted?