Klar blog

How to check what a Mac app is actually allowed to do

The App Store, TestFlight and a notarized DMG are three different guarantees. What each one checks, and the one command that tells you whether a Mac app can send your data anywhere.

You cannot read the source of an app before you install it. Nobody can: everything on the App Store is a closed binary, ours included. What you can do is check what an app is allowed to do, on your own machine, after it downloads and before you ever open it. On macOS that check is real, and it takes about a minute.

That check is the whole basis of Klar’s privacy claim, so this post is also the instructions for auditing us. The commands at the end work on any Mac app.

Three ways an app reaches your Mac

Klar uses all three, and they do not promise the same thing. The free app is on the Mac App Store. Betas go out through TestFlight, which is where Klar for Messages, the iPhone filter, will open first. Klar Plus, the optional paid companion, will ship as a notarized DMG from this site.

ChannelWhat Apple doesWhat it does not do
Mac App StoreReviews every build, and requires the app to run in the sandboxSay anything about what an app does with the data it is already allowed to see
TestFlightA lighter beta review, with the same sandbox requirementStay settled: beta builds update in place, and a new build can declare new permissions
Notarized DMGAn automated malware scan, and a signature tied to a named developer Apple can identifyRequire the sandbox. Outside the store, sandboxing is the developer’s choice

Notarization is the one most often over-read. It means Apple scanned the build for known malware and knows who signed it. It is not a review of what the app does, and it does not force the app into a sandbox.

The sandbox is the part that actually protects you

macOS grants an app access to a resource only if the app carries the matching entitlement, and entitlements are embedded in and sealed by the code signature. Apple’s Platform Security guide puts it plainly: because entitlements are part of and sealed by the code signature, “the App Sandbox trusts that these are the resources the developer intended to request.” Modify the bundle and the seal breaks, and the app will not launch.

So the declared capabilities are the real capabilities. A developer cannot declare no network and quietly open a connection anyway, because opening one requires the network entitlement, and the entitlement cannot be hidden. That makes the entitlement list, rather than the privacy policy, the thing worth reading.

The one line that matters

It is com.apple.security.network.client. If an app declares it, it can connect anywhere, and the permission says nothing about where. If it does not declare it, macOS refuses every outbound connection it attempts, and no code inside the app changes that. For a tool that reads your mail, that is the difference between “trust us” and “it cannot”.

Where a filter reads your mail is the companion question to what it is allowed to do. We mapped the four tiers of that in an earlier post.

What Klar declares

BuildHow it is signedNetwork entitlement
Klar, free, Mac App StoreApple Distribution, sandboxed, hardened runtimeNone, on neither the app nor the Mail extension
Klar on TestFlightThe same build settings as the store buildNone, but re-check after each beta update
Klar Plus, notarized DMGDeveloper ID, notarized and stapled, sandboxed, hardened runtimeYes: licence check and model updates

The free app ships exactly one loadable component, KlarMailExtension.appex, and it is a Mail extension: inert until you switch it on in Mail’s settings. No background services, no login items, no launch agents, nothing that starts on its own. Beyond the sandbox it holds one privacy-relevant permission, Contacts, which is what keeps mail from people in your address book from ever being filtered. macOS prompts for it, and it is read on your Mac.

Klar Plus is the exception, and we would rather write it down than let you find it. It is sold from this site rather than the App Store, it declares the network entitlement for a licence check and model downloads, and it uses AppleScript to move messages in Mail. Neither network call carries your mail, and sending spam samples back to us is a separate switch that is off until you turn it on. But once an app holds the network entitlement, the entitlement stops being the proof. What is left is our word, plus an outbound firewall such as Little Snitch or LuLu if you want to watch the wire yourself. The full list of what touches the network is on the local-first page.

Check it yourself, in a minute

Run this after installing Klar from the App Store and before you open it. Do it with networking off if you want to close the gap between the download landing and you looking at it.

APP="/Applications/Klar.app"
EXT="$APP/Contents/PlugIns/KlarMailExtension.appex"

# 1. Who signed it. Apple re-signs what a developer uploads, so the Team ID is
#    the constant, not the authority name.
codesign -dv --verbose=4 "$APP" 2>&1 | grep -Ei 'TeamIdentifier|Authority='
#    expect: TeamIdentifier=437587CCNF
#            Authority=Apple Mac OS Application Signing  (an App Store download)
#            Authority=TestFlight Beta Distribution      (a TestFlight build)

# 2. What can run: one Mail extension, nothing that starts by itself
find "$APP/Contents" \( -name "*.appex" -o -path "*XPCServices*" \
  -o -path "*LoginItems*" -o -path "*LaunchAgents*" \)
#    expect: exactly one line, KlarMailExtension.appex

# 3. Can either one reach the network, or drive another app?
codesign -d --entitlements - "$APP" > /tmp/klar-app.ent 2>/dev/null || echo "FAILED to read the app"
codesign -d --entitlements - "$EXT" > /tmp/klar-ext.ent 2>/dev/null || echo "FAILED to read the extension"
grep -icE 'network|apple-events' /tmp/klar-app.ent /tmp/klar-ext.ent
#    expect: no FAILED line, and a count of 0 for both files

The first check will not name us, and that is expected: Apple re-signs what a developer uploads, so an App Store download reads Apple Mac OS Application Signing and a TestFlight build reads TestFlight Beta Distribution. The developer’s own certificate is on the upload, not on your copy. What identifies us is the Team ID, and it stays 437587CCNF.

The third check is the one that counts, and it passes by printing a count of 0 for both files. It counts rather than trusting silence on purpose: if codesign cannot read the bundle, no output would look exactly like a clean result, so the check prints a number and says so loudly when it fails. Any non-zero count means the app declares network or automation capability, and you are back to deciding whether you believe what it says it does with that. If a check does not match, delete the app: nothing has run yet.

One caveat for beta builds: TestFlight updates in place, and a new build is a new bundle that can declare new permissions. Re-run the checks after an update, or turn automatic TestFlight updates off.

The engine is open source

The scoring engine, the part that reads a message and returns a spam score, is AGPLv3 at github.com/klar-im/engine, along with the Postfix milter that embeds it for mail servers. You can read how a message becomes a score, and build it. To be exact about the boundary: the Mac app’s interface and the trained model weights are not in that repository. What is open is the part that does the classifying.

What we do not claim

  • That you can verify anything before you install. You cannot, for any closed binary, on any platform. The check happens after the download and before you open it.
  • That macOS asks before an app connects to the internet. It does not, there is no prompt. The guarantee comes from the permission being absent and inspectable, not from a dialog.
  • That a missing network entitlement means zero data can ever leave. It means no silent connection of the app’s own. A running app can still hand a URL to your browser, which is why checking offline, or behind an outbound firewall, is worth the trouble.
  • That an independent third party has audited us. None has. Everything above is checkable by you, which is the point of writing it down.

Klar is free on the Mac App Store. macOS 14 or later, Apple Silicon.

All posts

The on-device option

Free, private, in Apple Mail.

Download on the App Store