The picture
Why each target is separate
privacycommandCore carries no UI on purpose. It runs from the CLI, from
tests, from the GUI, and from the helper. Keeping the views out means a detector
change is testable in seconds with swift test, and that the same analysis code
runs everywhere rather than being reimplemented per surface. The Analysis/
half imports nothing from AppKit; three files under Monitoring/ do, because
launching a bundle, reading the pasteboard, and driving a VM front-end have no
Foundation equivalent.
The helper is tiny on purpose. It exposes only what genuinely needs root:
version, start/stop file monitor, the BTM dump, install/remove kill switch,
uninstall. No general run-as-root path. It validates callers by code signature —
Apple anchor plus matching Team ID — so a binary signed by anyone else can’t
talk to it. That check depends on the helper itself being team-signed; see
How it protects itself for what a
no-team build does instead.
The guest protocol has zero dependencies on purpose. The agent has to build
and run inside a VM without compiling Core, so the wire format lives in its own
target that both sides import.
auditctl exists partly as a test. It’s the smallest path that exercises
the analyzer end to end, which makes it the fastest way to notice you broke
something.
How an audit flows
1
Ingest
A
.app — or a .dmg, mounted and unmounted around the analysis — becomes
a bundle path.2
Static pass
Roughly forty detectors under
Analysis/ run over the bundle: signing,
entitlements, Mach-O inspection, string scanning, SDK fingerprinting,
Privacy Manifest reading, and the rest. Each emits signals.3
Classification
A behaviour pass turns combinations of signals into findings with a risk
tier. This is what drives the summary and the batch scan
table.
4
Enrichment
Optional and network-bound: App Store privacy labels for Mac App Store
bundles.
5
Dynamic pass (optional)
The app is launched under observation.
Monitoring/ collects file events
(via the helper), network destinations, processes, device access, USB, and
resource usage — or receives the same from a VM guest.6
Report
Persisted to History, and exportable as JSON, HTML or PDF.
Reading the source
Sources/privacycommandCore/Analysis/— the detectors, roughly forty filesSources/privacycommandCore/Monitoring/— dynamic observationSources/privacycommandCore/Classification/— signals to findingsSources/privacycommandCore/KnowledgeBase/— the plain-English explanationsSources/privacycommandCore/IPC/— the helper’s XPC protocolSources/privacycommandCore/Batch/— fleet scanningSources/privacycommandCore/Reporting/— exports
ARCHITECTURE.md carries the longer version.