Security overview
Download the Security & Architecture Guide (PDF, 13 pages)
Architecture and data location
- Self-hosted: one Linux service (Ubuntu 22.04/24.04, Debian 12) or one container on your network. There is no vendor cloud. Cache status, statistics, device records and history never leave your server unless you turn on a feature that sends them (listed under "Outbound connections").
- Browser → Cachard (HTTPS, your certificate) → SSH with Cachard's own key → each caching Mac. No agent is installed on the Macs.
- All data is stored as files in
/var/lib/cachard(Docker: the/datavolume), owned by the unprivilegedcachardservice account and not readable by other users (keys and secrets 0600). There is no database server. - License keys are verified offline with a public key; there is no license check-in.
Outbound connections
Only these, and only when used:
- SSH (TCP 22) to your caching Macs.
- Your SMTP relay and/or Microsoft Teams webhook, if you set up alerts.
- api.anthropic.com, if you turn on AI insights (off by default) with your own API key.
- OpenStreetMap: overpass-api.de once if you build the street map, and nominatim.openstreetmap.org with the address text when you search for a site's location.
- Microsoft or Google, if you turn on single sign-on.
- (The site checks ask each Mac to run Apple's networkQuality test, so the Macs contact Apple's test servers.)
- updates.cachard.app, to check for and download updates. Can be turned off (Settings → Updates → Never check); offline update files work without it.
What the Macs allow
Root access on each Mac is limited by a visudo-validated sudoers file, /etc/sudoers.d/zz-cachard. The Mac enforces it, not Cachard. It is installed by the setup wizard (or scripts/prepare-mac.sh) and published here in full.
Full mode:
Cmnd_Alias CACHARD_UTIL = /usr/bin/AssetCacheManagerUtil
Cmnd_Alias CACHARD_PREFS = /usr/bin/defaults write /Library/Preferences/com.apple.AssetCache.plist *, /usr/bin/defaults delete /Library/Preferences/com.apple.AssetCache.plist *
Cmnd_Alias CACHARD_REBOOT = /sbin/shutdown -r now
Cmnd_Alias CACHARD_SWU = /usr/sbin/softwareupdate
Cmnd_Alias CACHARD_SWPREF = /usr/bin/defaults write /Library/Preferences/com.apple.SoftwareUpdate *
cacheadmin ALL=(root) NOPASSWD: CACHARD_UTIL, CACHARD_PREFS, CACHARD_REBOOT, CACHARD_SWU, CACHARD_SWPREF
Monitoring-only mode:
Cmnd_Alias CACHARD_READ = /usr/bin/AssetCacheManagerUtil -j status, /usr/bin/AssetCacheManagerUtil -j settings, /usr/bin/AssetCacheManagerUtil status, /usr/bin/AssetCacheManagerUtil settings, /usr/bin/AssetCacheManagerUtil canActivate
cacheadmin ALL=(root) NOPASSWD: CACHARD_READ
(cacheadmin is replaced by the account you choose. Settings → Security shows the exact file for your mode.)
Without root, Cachard's SSH account can do whatever that macOS account can do. If it's a Mac administrator (the wizard installs the key into the account you prepare with), it can still use sudo with its own password for anything; the sudoers file decides only what runs without a password. Cachard never keeps that password unless you save one for scheduled macOS updates (removed automatically in monitoring-only mode). Use a dedicated account for Cachard and, if you like, restrict its key to the console's address (from="10.0.0.5" in ~/.ssh/authorized_keys).
Operating mode and the remote terminal
- Monitoring-only mode (
install.sh --monitor-only,sudo cachard mode monitor,CACHARD_MODE=monitor): caching configuration, actions, Mac updates (including ones scheduled earlier) and the terminal are switched off for every account, Macs prepared in this mode get the read-only rule above, and a saved Mac administrator password is deleted. Only root on the server can change the mode, never the web console. - Remote terminal (live SSH shell to one Mac; fleet-wide commands): off by default. When a platform administrator turns it on (Settings → Security), sessions are recorded in the audit log with a transcript of their output (up to 5 MB) and close after 30 minutes without input. Running anything as root beyond the sudoers file needs the account's password.
install.sh --no-terminalorsudo cachard terminal forbid(CACHARD_TERMINAL=off) means it can't be turned on from the console at all. With the terminal off, the console can only run its fixed list of commands: settings are validated (types, ranges, IP addresses) and shell-quoted on the server, and the browser can't send commands.
Roles
Each role can do everything the one before it can.
| Role | Can |
|---|---|
| Viewer | See cache health, statistics, map, history, alerts and the audit log |
| Technician | Run site checks and diagnostics, ask the AI analyst, scan for updates, restart or reload the caching service |
| Administrator | Change caching configuration, run other actions (flush, restart Mac, deactivate), run and schedule Mac updates, manage standards, sites, map and alerts |
| Platform administrator | Add/remove Macs, accounts and invitations, sign-in and single sign-on, two-step policy, remote terminal, security settings, Cachard updates, license, branding, HTTPS, AI settings, support bundles |
The built-in admin account (for break-glass access) is always a platform administrator. Its password is set in the setup wizard and stored as a PBKDF2 hash (sudo cachard reset-admin-password); an optional alternative, ACC_ADMIN_PASSWORD in /etc/cachard/cachard.env, is stored in plain text, so leave it unset unless you need it. Monitoring-only mode and the terminal switch override every role.
Site safeguard
"Minimum available caches per site" (default 1, Settings → Security). A Mac update waits, then skips with an explanation, rather than take a cache out of service while its site would have fewer available caches than that. Restarting a Mac or switching caching off asks for confirmation in the same situation, and an override is audited. Sites with a single cache can't stay covered; the update plan points them out.
Accounts and sessions
- Passwords: PBKDF2-SHA256, 310,000 iterations, per-password salt, minimum 10 characters. Sign-in is rate limited (8 failures per address per 5 minutes).
- Two-step sign-in: TOTP (RFC 6238) with one-time recovery codes; replayed codes are refused. Can be required for administrators or for everyone.
- Single sign-on: Microsoft Entra ID or Google, OpenID Connect authorization-code flow with PKCE, allowed-domain checks, and a default role (or none) for people without an account.
- Sessions: signed, HTTP-only cookies,
SameSite=Lax,Securewhen HTTPS is on, 12-hour lifetime. Role changes and deleted accounts take effect on the next request. Sessions are stateless: signing out ends the session in that browser, but a copied cookie stays valid until it expires. - The first-run wizard can only be started with a one-time code generated on the server.
- Email invitations: single-use links, stored as hashes, expiring after 72 hours.
Browser protections
- Content-Security-Policy on pages (
default-src 'self',object-src 'none',base-uri 'none',frame-ancestors 'self'; scripts and styles also allow'unsafe-inline'for the console's own inline code),X-Frame-Options: SAMEORIGIN,X-Content-Type-Options: nosniff,Referrer-Policy: same-origin,Permissions-Policy, HSTS when HTTPS is on,Cache-Control: no-storeon API responses. - Cross-site request forgery: browsers always send
Originon cross-site requests, and every state-changing request or WebSocket with anOriginother than the console is refused (scripts and the CLI send none). Cookies areSameSite=Laxtoo. - Uploaded logos and branding images: PNG, JPEG, WebP and script-free SVG only, served with
nosniffand a sandboxing Content-Security-Policy.
Secrets and keys
- Cachard's SSH private key (Ed25519) is generated on the server and kept in the data folder with permissions 0600. It is never shown in or downloadable from the console (only the public key is), and support bundles leave it out. It is not passphrase-protected, because the service uses it unattended, so protect the server's disk (for example full-disk or VM encryption).
- SSH host keys are pinned on first contact (fingerprints shown) and verified on every connection.
- The Mac administrator password used to prepare Macs is held in memory for that step only; it is never written to disk or logs.
- The AI API key and the Mac-update administrator password (if you save it for scheduled updates) are encrypted with a key derived from the server's own secret. Other secrets (SMTP password, Teams webhook, SSO client secret) are stored in files only the service account can read, and are never sent back to the browser.
- Backups (
sudo cachard backup) contain the SSH key and secrets and are written with permissions 0600. Store them like a password vault. - Support bundles have passwords, hashes, two-step secrets, SSH/TLS private keys, API keys, webhooks and the license key removed. Device records and terminal transcripts are never included. The CLI bundle's service log has invitation links, sign-in codes and the setup code removed. IP addresses can be masked (
--mask-ips, or the console option).
Data collected from the Macs
Cachard reads, from each caching Mac:
- content-caching status and settings (AssetCacheManagerUtil): cache size and usage, bytes served, peers and parents;
- macOS version, model, computer name, boot time, free disk space, power settings;
- available macOS updates and update history (softwareupdate --list / --history);
- the content-caching log: for each request, the client device's IP address, device type, OS build and what was downloaded (for example "iOS 18.1 update").
It doesn't collect user names, Apple Accounts, files, browsing or anything else from the devices that use your caches. Device records stay on your server (30 days) and are visible only to signed-in accounts. The optional public map for signed-out viewers is off by default (ACC_PUBLIC_MAP=1); when on, it shows Mac and site names, locations, status, traffic rates, cache fill, content categories and anonymous device icons, without IP addresses, settings or errors.
Telemetry
- Cachard sends no usage analytics.
- Update checks (every 6 hours) send the installed version, the release channel and, if licensed, the license ID; like any web request, they also reveal your public IP address. Downloading an update also sends the license key so support can be confirmed. Turn checks off in Settings → Updates.
- AI insights (off by default) send an aggregated fleet snapshot (organization name, Mac and site names, states, settings, your public IP addresses, traffic totals, findings) to Anthropic under your API key. Client device IP addresses and identities, passwords and keys are not sent. Settings → AI insights shows the exact snapshot.
Updates
- Releases are signed with an Ed25519 release key that is separate from the license key. The console and the root updater each verify the feed's signature and the archive's SHA-256 before anything is installed; a tampered feed or mirror is rejected.
- The console runs unprivileged and can't change its own program files. A root-owned updater re-verifies the release, backs up the data, installs it and rolls back automatically if the new version doesn't start.
- Python dependencies are installed from PyPI at install time (or from a bundled wheels folder offline). Security fixes in Cachard or its dependencies ship as signed patch releases (1.2.x), which consoles set to "install fixes automatically" apply on their own.
Hardening of the service
- Runs as an unprivileged system account with systemd sandboxing (
ProtectSystem=strict,ProtectHome,PrivateTmp,NoNewPrivileges, kernel and control-group protections, write access only to its data folder). - The audit log (
audit.jsonl, one JSON line per event) records configuration changes and actions with the exact commands and results, Mac updates with theirsoftwareupdatecommands, Mac preparation, accounts, roles, invitations, password and two-step changes, single sign-on, security settings, safeguard overrides, terminal sessions, Cachard updates, andsudo cachard mode/terminal/reset-admin-password/reset-2step. Read-only diagnostics and site checks aren't audited. For tamper evidence, forward the file to your log server or SIEM.
Backup and recovery
sudo cachard backupwrites everything (data and service settings) to one file;sudo cachard restore FILEbrings it back on the same or a new server. Every update makes its own backup first and keeps the previous version forsudo cachard update rollback.- If the Cachard server is lost, the caches keep working: Apple's content caching doesn't depend on Cachard. Restore the backup to a new server and Cachard picks up where it left off (same SSH key, so no Mac needs preparing again).
Reporting a vulnerability
Email security@cachard.app with details and how to reproduce the issue. We acknowledge reports within two business days, keep you informed, credit you if you wish, and ask for 90 days to ship a fix before publication. Please test only systems you own.