All tests run on an 8-year-old MacBook Air (Intel). Every Hiyoko app ships unsigned, so I've become intimately familiar with every way macOS can block an app from launching.
Building a great app is only half the battle. If you're a solo developer who isn't paying Apple's $99/year Developer Program fee, your users are greeted with "App is damaged" or "Developer cannot be verified" dialogs. This is the reality of distributing unsigned macOS software in 2026. Here's the full picture of what happens, why, and how to handle it.
TL;DR
- macOS attaches a
com.apple.quarantineextended attribute to every downloaded file—this triggers Gatekeeper. -
xattr -cr /path/to/App.appis the reliable fix, but users need clear instructions. - Privacy permissions (Full Disk Access, USB) require separate handling in System Settings.
- Entitlements and
Info.plistkeys are essential even for unsigned apps.
How Gatekeeper Actually Works
When a user downloads any file through Safari, Chrome, or curl, macOS adds an extended attribute called com.apple.quarantine. For signed and notarized apps, Gatekeeper verifies the signature and removes the flag silently. For unsigned apps, this flag triggers the "damaged" or "unverified developer" error.
You can see it for yourself:
# Check quarantine status of a downloaded app
xattr -l /Applications/HiyokoMTP.app
# Output:
# com.apple.quarantine: 0083;66a1b2c3;Safari;F2E4A6B8-...
# The quarantine attribute contains:
# - flags (0083 = downloaded + executed check pending)
# - timestamp
# - download source (browser name)
# - download UUID
The xattr Fix
The most reliable way to clear Gatekeeper for your users is a single terminal command:
# Clear ALL extended attributes recursively from the app bundle
sudo xattr -cr /Applications/HiyokoMTP.app
# -c = clear all attributes (not just quarantine)
# -r = recursive (covers every file inside the .app bundle)
# sudo = required because some attributes are root-owned
# Verify it worked:
xattr -l /Applications/HiyokoMTP.app
# (should output nothing)
I include this command in every Hiyoko app's README, download page, and first-launch error dialog. The key is making it impossible for users to miss.
Beyond Gatekeeper: Privacy Permissions
Clearing xattr gets the app to launch, but apps like HiyokoMTP need deeper system access. macOS requires explicit user consent for:
- Full Disk Access — needed for file transfer across all volumes
- Accessibility — needed for keyboard-driven automation
- USB Device Access — needed for MTP and ADB connections
These permissions must be declared in your Info.plist, even for unsigned apps:
<!-- Info.plist — privacy usage descriptions -->
<key>NSAppleEventsUsageDescription</key>
<string>HiyokoMTP needs automation access for device detection.</string>
<key>NSDesktopFolderUsageDescription</key>
<string>HiyokoMTP needs access to transfer files to/from your Desktop.</string>
<key>NSDocumentsFolderUsageDescription</key>
<string>HiyokoMTP needs access to transfer files to/from Documents.</string>
<key>NSRemovableVolumesUsageDescription</key>
<string>HiyokoMTP needs access to external drives for file transfers.</string>
Without these keys, macOS silently denies the access request—no error, no dialog, just a silent failure. I spent two days debugging a "file not found" error that turned out to be a missing Info.plist entry.
Entitlements for Unsigned Apps
Even without code signing, you can embed entitlements in your app bundle. Tauri v2 handles this through the build configuration:
{
"bundle": {
"macOS": {
"entitlements": "./Entitlements.plist",
"minimumSystemVersion": "10.15"
}
}
}
<!-- Entitlements.plist -->
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "...">
<plist version="1.0">
<dict>
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
<true/>
<key>com.apple.security.device.usb</key>
<true/>
</dict>
</plist>
macOS Version Differences
Gatekeeper behavior varies across macOS versions, and my 8-year-old MacBook Air has seen several:
- macOS 12 (Monterey) — "Cannot verify developer" dialog with an "Open Anyway" button in System Preferences.
- macOS 13 (Ventura) — "Open Anyway" moved to Privacy & Security → Security section.
-
macOS 14+ (Sonoma/Sequoia) — Stricter enforcement. Some users report needing to run
xattreven after clicking "Open Anyway."
I document all three paths in my support guides, with screenshots for each macOS version.
Why Not Just Sign?
Fair question. Apple's Developer Program costs $99/year and requires identity verification. For some solo developers, that's fine. For others—especially those distributing free tools or working outside the US—the bureaucracy and ongoing cost aren't justified.
By being transparent about the unsigned status and providing clear, tested instructions, you build trust through honesty rather than through corporate certificates. Every Hiyoko download page includes a "First Launch Guide" section that walks users through the xattr process step by step.
Gatekeeper is designed to keep users safe, but it shouldn't be a wall between independent developers and their users. Master the tooling, document it clearly, and your users will appreciate the transparency.
Have you dealt with Gatekeeper rejection for your indie apps? Did you eventually sign, or did you find workarounds that stuck?
If this was helpful, check out HiyokoMTP — Android↔Mac MTP file transfer with custom nusb-based stack.
Built with Rust + Tauri v2. Tested on an 8-year-old MacBook Air.
Top comments (0)