Gatekeeper & Quarantine
xattr com.apple.quarantine, notarization, and how macOS decides whether to run your download.
Gatekeeper & Quarantine
When you download a .dmg, unzip it, and double-click the app inside, macOS doesn't just run it. It stops, looks at a handful of flags, and decides: launch silently, show a warning dialog, or block. That decision is Gatekeeper, and the flag it looks at most is the quarantine xattr.
Analogy
Gatekeeper is the customs booth at an international airport. Every suitcase that arrives from abroad gets a little sticker slapped on it at the jet bridge — that's the quarantine attribute. A bag picked up at your own car in the parking lot never got the sticker, so customs waves it through without a second look. At the gate, the officer checks two things: is the bag from a known, registered shipper (code signing), and has our inspection service x-rayed it and cleared it (notarization). A bag with sticker and both stamps walks through silently; sticker but no x-ray clearance gets the "please declare" conversation; sticker and no shipper ID gets refused entry. Peeling the sticker off yourself is legal — but it's also how someone smuggles something in by saying "I vouch for it, trust me."
The quarantine extended attribute
When a browser, mail client, or messaging app writes a file to disk, it tags that file with an extended attribute called com.apple.quarantine. Inspect it:
xattr -p com.apple.quarantine ~/Downloads/MyApp.dmg
# 0083;65e3b0e4;Safari;INSERT-UUID-HERE
The four semicolon-separated fields: flags, timestamp (hex), source application, and a UUID for the download. The flags field is what Gatekeeper cares about — 0083 means "has not yet been cleared by the user."
On first launch, Gatekeeper reads this attribute. If it's missing, Gatekeeper isn't consulted at all — the file didn't come from a download, so by assumption it's fine. This is why binaries you build with make locally don't trigger Gatekeeper, and why a file rsyncd from another Mac escapes the check.
What Gatekeeper actually checks
Given a file with quarantine, Gatekeeper walks a decision tree:
- Is the user's approval already on file? (right-click → Open, or "Open Anyway" in System Settings → Privacy & Security). If yes → launch.
- Is it signed with a valid Developer ID certificate AND notarized by Apple? If yes → launch.
- Is it signed but not notarized? → Show the "this is from an identified developer but hasn't been verified by Apple" dialog. User can click through.
- Is it unsigned and not yet approved? → Block. "This app cannot be opened because it is from an unidentified developer."
The block isn't permanent — the user can approve in System Settings → Privacy & Security or by right-clicking → Open the first time. But it's the correct default for 99% of cases.
Notarization, not signing
A Developer ID signature proves the app came from a real registered developer. Notarization is an extra step: the developer uploads the signed binary to Apple's service, Apple scans it for malware, and if clean returns a ticket that's stapled back into the app. A notarized app has been seen by Apple and found non-malicious at submission time.
Since macOS Catalina (10.15), Gatekeeper requires notarization for the "launch silently" path. Signed-but-not-notarized apps get the warning dialog.
The spctl tool
spctl (security policy control) is the CLI Gatekeeper uses internally. You can ask it to assess a file the way Gatekeeper would:
spctl --assess -vv /Applications/MyApp.app
spctl --assess -vv -t install ~/Downloads/MyApp.dmg
# Is Gatekeeper even on?
spctl --status
# Turn Gatekeeper off entirely (recovery/diagnostic only!)
sudo spctl --master-disable
spctl --status will say "assessments enabled" on any healthy Mac. If you ever see "assessments disabled" you want to know why.
Removing quarantine — safely
Sometimes you legitimately need to strip the attribute — for example, a DMG from a trusted vendor that failed a notarization check because the developer forgot to re-staple after a patch release. The tool is xattr:
xattr -d com.apple.quarantine path/to/file
xattr -r -d com.apple.quarantine /Applications/Tool.app # recursive
Do this knowingly. Stripping quarantine from an app you don't trust bypasses Gatekeeper entirely — you've just told macOS "I vouch for this binary."
Quarantine on directories
The xattr propagates from DMGs and zips into extracted content. If you unzip a tarball, everything inside still carries quarantine, and Gatekeeper fires for every binary in there. xattr -r -d on the unzipped directory clears them all at once.
Why this matters
Gatekeeper is not just UI friction. The model — quarantine xattr set on download → Developer ID check → notarization ticket check — is what kept macOS relatively free of drive-by malware for a decade. Bypassing it once in a while is fine; bypassing it by habit (xattr -d in your dotfiles as an alias) is how you end up running something nasty. When Gatekeeper blocks a file, the first question should always be "why is this file unsigned or not notarized?", not "how do I turn Gatekeeper off?"