Notarization and Gatekeeper

~3 min read

Notarization and Gatekeeper

When macOS blocks the app or one of its parts.

First-launch warning

“Apple could not verify Lettuce is free of malware…”

Or:

“Lettuce can’t be opened because Apple cannot check it for malicious software.”

This is normal on the first launch after a fresh download from outside the Mac App Store.

Fix:

  1. Right-click the Lettuce icon in Applications → OpenOpen in the prompt.

  2. After this once, every subsequent launch is fine.

  3. Alternatively: System Settings → Privacy & Security → scroll to “Lettuce was blocked…” → Open Anyway.

This works because Lettuce is notarised. macOS just requires explicit user assent the first time for any app from outside the App Store.

“Damaged and can’t be opened”

“Lettuce is damaged and can’t be opened. You should move it to the Bin.”

Not actually damaged. The DMG was downloaded but the quarantine flag confused Gatekeeper.

Fix:

xattr -d com.apple.quarantine /Applications/Lettuce.app

You’ll be prompted for an admin password. Re-launch the app.

QuickLook plugin not working

Markdown previews in Finder don’t appear.

Check:

qlmanage -m | grep -i lettuce

Should show Lettuce.qlgenerator.

Fix:

qlmanage -r       # reload QuickLook
qlmanage -r cache # clear thumbnail cache

If you still don’t see previews:

  1. Lettuce.app is in /Applications (not the user’s Applications/).

  2. The QuickLook plugin is at /Applications/Lettuce.app/Contents/Library/QuickLook/Lettuce.qlgenerator.

  3. macOS Privacy & Security hasn’t blocked it (rare; check the Privacy & Security pane).

CLI not found

lettuce --help
# zsh: command not found: lettuce

The lettuce symlink isn’t set up. The CLI is the same binary inside the app bundle — there’s no separate installer.

Fix: symlink it onto your $PATH:

sudo ln -sf /Applications/Lettuce.app/Contents/MacOS/Lettuce /usr/local/bin/lettuce

If /usr/local/bin isn’t in your $PATH, that’s a shell config issue:

echo 'export PATH="/usr/local/bin:$PATH"' >> ~/.zshrc
source ~/.zshrc

Code-sign verification

To verify the app is genuinely from Anthropic / DrBaher:

codesign --verify --verbose=2 /Applications/Lettuce.app
spctl --assess --type execute --verbose /Applications/Lettuce.app

Expected output (paraphrased):

/Applications/Lettuce.app: valid on disk
/Applications/Lettuce.app: satisfies its Designated Requirement
/Applications/Lettuce.app: accepted
  source=Notarized Developer ID
  origin=Developer ID Application: Baher Alhakim (74X34KA4X6)

If spctl says “rejected”, the notarisation didn’t stick — re-download from https://lettuce.drbaher.com/Lettuce.dmg.

Why spctl says “no usable signature” on the DMG

The DMG (container) is unsigned. The .app inside is signed and notarised. macOS checks the inside, not the container. So:

spctl --assess --type open --context context:primary-signature /path/to/Lettuce.dmg
# rejected

is expected. Trust the .app check above.