Privacy & data flow
The short version: your fleet's data never leaves your Mac. The longer version is on this page — what Noxen reads, where it stores it, what (if anything) syncs to iCloud, and what outbound network traffic Noxen actually makes.
What gets read on your Mac
~/.ssh/config— only on explicit import via SSH config import. Never read otherwise.- Referenced SSH private keys — read once at host enrolment time, copied into the macOS Keychain, then the on-disk key file is never re-read. The Keychain entry is scoped to Noxen's app group so the scheduled-scan agent can read it for nightly runs.
- System network info — your primary interface's subnet for LAN discovery defaults. Read once when you open the discovery UI; not transmitted anywhere.
What gets stored locally
- SwiftData
(
~/Library/Application Support/app.noxen/default.store) — Host catalog (display name, hostname, port, username, tags), Scan history (timestamps, status), Findings (severity, category, title, detail, remediation), Installed package inventory (per-host, time-stamped). - Keychain — SSH private keys, license keys.
Marked
kSecAttrSynchronizable=falseso iCloud Keychain doesn't replicate them across your other Macs. - App Support —
cves-latest.sqlite(the imported CVE feed),noxen-feed-baseline-YYYYMMDD.jsonl.gz(the downloaded snapshot),custom-checks/(your user-authored checks). - UserDefaults — preferences (theme, scheduled-scan time, webhook URLs), feature flags, the per-day "last checked" timestamps used to throttle feed polls.
What syncs to iCloud (when enabled)
v1.0 status: CloudKit sync is wired and the
entitlements are provisioned, but the database is opened with
cloudKitDatabase: .none until the iOS view-only
companion ships. The fields below describe the schema once
sync is flipped back on; until then, every record stays on
your Mac.
Optional and off by default. When sync is enabled, a private CloudKit container (visible in Settings → Advanced → Runtime audit) replicates:
- Host catalog entries (names, hostnames, ports, usernames, tags).
- Scan records (timestamps, status, scan IDs).
- Finding records (severity, category, title, detail, remediation, KEV/EPSS tags).
Explicitly excluded from CloudKit sync:
- SSH private keys — Keychain marked non-synchronisable.
- License keys — same.
- The CVE feed snapshot itself — it's the same on every Mac, no point replicating.
- Webhook URLs containing tokens — these are stored in Keychain (not SwiftData) so they don't sync even if you turn iCloud on.
iCloud sync is what powers the iCloud-synced replicas on your other Macs — your phone sees the host catalog and findings via the same private CloudKit container, no separate auth or backend required.
What outbound network traffic Noxen makes
Three (and only three) destinations:
feed.noxen.app- The signed CVE feed manifest + snapshot. One GET per check (cadence depends on tier — see CVE feed reference). No request body. The Cloudflare worker behind it sees the request IP (any standard CDN log). It does not see anything about your fleet — there's no fleet identifier in the request.
noxen.app/appcast.xml- Sparkle update check. One GET per app launch (cached for 24 h). Used to determine if a newer Noxen build is available. Exposes your installed Noxen version and OS version (Sparkle's default headers); doesn't expose anything about your fleet.
SSH / TCP / HTTP(S) to your enrolled hosts- Initiated by you (manual scan, scheduled scan, batch scan). Goes to your own hosts at IPs you specify; doesn't touch any third-party network. Encrypted (SSH for inventory, TLS for HTTPS probes); plaintext for HTTP probes only on ports you've enrolled.
What Noxen does NOT do
- Send fleet inventory to any server. CVE matching happens in-process on your Mac after the feed is downloaded.
- Send scan results to any server. Even when webhooks are configured, the webhook target is your own Slack / Discord / Teams / custom endpoint — Noxen doesn't relay through its own servers.
- Use third-party analytics. The marketing site
(
noxen.app) loads Google Analytics, but the Mac app itself ships zero analytics or telemetry. - Scan networks you didn't enrol. Discovery only runs on the subnet you specify; scans only target hosts you've explicitly added.
Runtime audit
Settings → Advanced → Runtime audit shows a live snapshot of Noxen's privacy posture:
- Sparkle public key present + valid.
- App Group container reachable.
- CloudKit container configured (or "no iCloud account" if not).
- Debug bypass disabled (must be false in shipping builds — see the entitlement-gating tests).
The audit re-runs on every launch and surfaces anything anomalous as a settings-pane warning. Useful when triaging "is my install configured correctly?" questions.
Privacy policy
The full legal text — including processor disclosures and EU data-rights walkthrough — lives at noxen.app/privacy.