Security
Noxen is a security tool. Its own posture matters. This page documents what we ship, what we sign, what data leaves your Mac, and what doesn't. It is written for the engineer or evaluator running Noxen through a procurement or InfoSec checklist, not as marketing copy. Everything below describes the app as it currently ships.
Distribution and signing
Noxen is an Apple Silicon binary for macOS 26
and later, distributed as a notarised Developer ID build. It is not
on the Mac App Store: the App Sandbox blocks the raw socket and
~/.ssh/config access Noxen needs to do its job - see
Why Developer ID, not the
Mac App Store for the full reasoning. Gatekeeper still verifies
every build through Apple's notarisation service on first launch.
Updates ship through Sparkle. The appcast at
https://noxen.app/appcast.xml
is served over TLS and every release entry carries an Ed25519
signature. The corresponding public key is bundled inside the app
bundle at build time, which means a malicious appcast - even one
served from our own infrastructure - cannot push a Noxen update
without the matching private signing key.
What data leaves your Mac
Exactly two things, and they are both opt-out-by-uninstall rather than opt-out-by-toggle so they are worth being precise about:
-
Daily CVE-feed manifest fetch from
feed.noxen.app. The app polls a JSON manifest, compares snapshot versions, and - if a newer snapshot exists - downloads a signed NDJSON snapshot. No fleet data, host inventory, findings, IP addresses, hostnames, or scan history is uploaded as part of that fetch. The request body is empty; the server only sees the standard HTTP fetch metadata Cloudflare's edge records. -
iCloud private-database sync via CloudKit - not active
in v1.0. The code path and entitlements are provisioned,
but the store is opened with
cloudKitDatabase: .noneand there is no setting to change that. Nothing syncs to iCloud today. When it is enabled alongside the iOS view-only companion, the host catalog and scan history will sync to your own Apple ID's private CloudKit database, encrypted by Apple in transit and at rest, and Noxen will still never see any of it.
No analytics SDK runs inside the app. No telemetry payloads, no
third-party trackers, no crash reporter that forwards stack traces
to a vendor. The website at noxen.app uses Google
Analytics with IP-truncation forced on - that is browser-side, not
app-side, and is documented in /privacy.
What stays on your Mac
Everything else:
- Scan history, host inventory, findings - in a SwiftData store at
~/Library/Application Support/Noxen/. - SSH credentials and private keys - in the macOS Keychain, never in the SwiftData store, never synced through CloudKit even when sync is on.
- Your Noxen licence key - Keychain.
- Webhook URLs (Slack / Discord / Teams / generic) - Keychain.
- Custom-check definitions - flat JSON files in
~/Library/Application Support/app.noxen/custom-checks/.
When iCloud sync is eventually enabled it will cover the SwiftData store only. Keychain items stay device-local either way.
CVE feed integrity
The feed is a signed, gzipped NDJSON snapshot. On every download, Noxen verifies an Ed25519 signature against a public key bundled with the app - using Apple's CryptoKit, not a third-party crypto library - before swapping the new snapshot in atomically. A tampered or truncated download is rejected; the previous good snapshot keeps serving until the next successful verified fetch.
Sources for the feed are NVD (primary, fetched directly from the NVD 2.0 API), OSV.dev (secondary, used for Debian / Ubuntu / Rocky / AlmaLinux distro triage), and GHSA (tertiary, in scope but currently not surfaced in the marketing dashboard until Noxen scans language ecosystems). The pipeline is deliberately boring: pure mirror plus a CPE index. We never enrich, never re-score, never re-rate. Severity buckets come from the upstream advisories.
App permissions
Noxen requests the minimum macOS authorisations needed to do its job, and no more:
- Local Network - for the LAN-discovery subnet sweep on the TCP/22 port.
- Bonjour service browse -
_ssh._tcp,_workstation._tcp,_sftp-ssh._tcp. Used to populate the LAN-discovery host list with mDNS-advertised endpoints. - Full Disk Access - optional, only requested if you choose to import
~/.ssh/config. Skip this and you can still add hosts manually or via bulk paste.
App Sandbox is disabled at build time, because the sandbox forbids
both raw-socket port scanning and reading
~/.ssh/config from outside the container. This is the
same reason Noxen is not on the Mac App Store.
What we don't do
- No credential brute-forcing. Noxen will flag an exposed admin surface - a Grafana login, an unauthenticated Redis, a Portainer panel - and tell you it is reachable from the internet. It will never try a default password, a wordlist, or any authentication attempt against it. Why we hold this line.
- No web-application crawl scanning. No directory bruteforce, no XSS fuzzer, no SQLi probes. Noxen is a fleet vulnerability scanner, not a DAST tool.
- No outbound submission of scan findings. The findings the app produces stay in your local store unless you explicitly fire a webhook or export NDJSON / CSV / PDF yourself.
Reporting vulnerabilities in Noxen
Email snyman.ps@icloud.com with a description of the issue and steps to reproduce. PGP key available on request - reply will arrive from the same address within one UTC business day. We work on a 90-day coordinated disclosure window from the day the report is acknowledged, with flexibility either way when circumstances warrant.
If a fix lands inside the disclosure window, it ships through the normal Sparkle appcast - so any user running a current Noxen build receives it as a standard auto-update without any separate out-of-band channel.
Related reading: Privacy policy · Terms of service · Why Developer ID, not MAS · Flag only, never authenticate