This page is for security and IT teams deciding whether to allow Cmdr, a file manager for macOS. It describes Cmdr version 0.47.0 as of 2026-09-24. The source code is public on GitHub, so you can check every statement here. If something is missing or unclear, write to [email protected].
Summary
- Your files stay on your Mac. File contents never reach Cmdr’s servers. Cmdr has no user accounts and no cloud storage.
- On by default: update checks, usage stats, and crash reports. Each user can turn each one off in Settings. There’s no central (MDM) control yet.
- AI is off by default. If a user turns it on with their own API key, the app talks straight to that provider. Nothing goes through Cmdr’s servers.
- Signed and notarized with Apple’s Developer ID and the hardened runtime. Updates are signed separately and checked before they’re installed.
- Not App Sandboxed. A file manager needs to reach all your files, so Cmdr asks for Full Disk Access. Users can say no.
- Some data leaves the EU. The details are below.
- Made by one person at Rymdskottkärra AB, a Swedish company. The code is public under the Business Source License, and each version becomes open source (AGPL-3.0) three years after its release.
What the app sends over the network
This is every connection a release build of the app makes. All of it comes from the app’s native code. The
app’s user interface makes no network requests, and its content security policy would block any except to
getcmdr.com. There are no ads, no third-party trackers, and no remote fonts or scripts in the
app.
Update check and download
- Goes to:
api.getcmdr.com, thengetcmdr.com/latest.json. The update itself downloads fromgithub.comandrelease-assets.githubusercontent.com. - When: At most once every three hours, starting at launch. Users can set the interval from five minutes to 24 hours.
- Sends: The app version and CPU architecture, in the URL. The server keeps a one-way hash of the IP address, the date, the version, and the architecture. It deletes each record after seven days and keeps only daily totals.
- Default and how to turn it off: On by default. Turn off with Settings > Updates & privacy > “Automatically check for updates”. A found update downloads and installs by itself, then asks the user to restart.
Usage stats
- Goes to:
api.getcmdr.com/heartbeat. The app doesn’t contact PostHog: our server passes the feature events on to PostHog’s EU cloud. - When: At most once every three hours while the app is open. Feature events wait on the Mac and go with the next send.
- Sends: A random install id created on the Mac (not linked to a name, email, or license), app version, macOS version, CPU architecture, the names of features used, and a fixed list of settings values (like light or dark mode). No file names, paths, file contents, search terms, or AI prompts. That list is enforced by code review, not by an automatic filter.
- Default and how to turn it off: On by default during the open beta. The first-launch setup shows this, and the user can’t skip that step. Turn off with Settings > Updates & privacy > “Send usage stats”. When it’s off, nothing is sent.
Crash reports
- Goes to:
api.getcmdr.com/crash-report - When: On the next launch after a crash.
- Sends: App and macOS version, where in Cmdr’s code the crash happened, the crash message after it’s cleaned of personal data on the Mac (at most 2,000 characters), memory addresses of the crashing code, and a random report id. From macOS’s own crash report, only the one-line reason and the function names of the crashing thread. An email address only if the user ticks a box.
- Default and how to turn it off: On by default. Turn off with Settings > Updates & privacy > “Send crash reports”.
Error reports
- Goes to:
api.getcmdr.com/error-report - When: When the user picks Help > Send error report, which shows a preview first. Automatic sending exists but is off by default.
- Sends: A zip with the recent part of the app’s log, the app and macOS version, and the user’s note. Before it leaves the Mac, Cmdr replaces file and folder names in paths with placeholders, keeping only the extension and common folder names like Documents. Known gaps: a file name that appears in free text (outside a path) can get through, and the text of a natural-language search is in the log and can be included.
- Default and how to turn it off: Sent by hand only, by default. Automatic sending is Settings > Updates & privacy > “Send error reports automatically”, off by default.
License check
- Goes to:
api.getcmdr.com(older versions uselicense.getcmdr.com) - When: Only when a commercial license is installed: at activation, then once every seven days.
- Sends: The license’s transaction id, and a device id that’s a one-way hash (SHA-256) of the Mac’s hardware UUID. Activation sends the short license code.
- Default and how to turn it off: Free personal-use installs never make this call. The license itself is checked offline with a signature. If the server can’t be reached, the license keeps working for 30 days, then the app falls back to the free personal tier until a check succeeds.
Feedback and newsletter signup
- Goes to:
api.getcmdr.com/feedbackandapi.getcmdr.com/beta-signup - When: Only when the user sends feedback or types an email address to stay in touch.
- Sends: The message, app and macOS version, and an email address if the user adds one. No install id.
- Default and how to turn it off: Nothing is sent unless the user sends it.
AI features (optional)
- Goes to: The AI provider the user picks, straight from the Mac. None of it goes through Cmdr’s servers. Details in AI features and your files.
- When: Only after the user sets up a cloud provider with their own API key and turns on “Allow cloud AI”.
- Sends: File and folder names and, when asked, parts of file contents. See the AI section.
- Default and how to turn it off: Off by default. Settings > AI > Provider.
Local AI model and image-search model downloads (optional)
- Goes to:
huggingface.coand its download servers - When: Only when the user chooses local AI, or turns on semantic image search.
- Sends: A normal file download. The image-search model is checked against a fixed SHA-256 hash. The local AI model is checked by file size only.
- Default and how to turn it off: Nothing is downloaded unless the user asks for it.
Remote files the user opens
- Goes to: Only servers and devices the user connects to: SMB, SFTP, and WebDAV servers, and phones over USB.
- When: When the user browses them. To find SMB servers on the local network, Cmdr uses Bonjour (mDNS). It runs only while the Servers view is open, while Cmdr looks up the server behind an SMB share it connects to, and for 10 seconds after launch.
- Sends: What the protocol needs: credentials the user entered and the file operations the user asked for.
- Default and how to turn it off: SMB, phone (MTP), and Android (ADB) support are on by default and each can be turned off in Settings > File systems. Git support is local only and never fetches or pushes.
Hosts to allow on a proxy or firewall
-
api.getcmdr.com: update checks, license checks, usage stats, reports -
getcmdr.com: the update manifest (latest.json) -
github.com, release-assets.githubusercontent.com: update downloads -
license.getcmdr.com: license checks from older versions only -
huggingface.co: optional, only for local AI and image-search model downloads -
your AI provider: optional, only if a user sets up cloud AI
Cmdr uses the macOS system proxy settings and the macOS certificate store, so a company certificate for TLS inspection that’s installed in the system keychain should work. This hasn’t been tested behind an inspecting proxy yet, and PAC files are untested.
The website
getcmdr.com counts visits with Umami, which runs on Cmdr’s own server in Finland and uses no cookies. It also uses PostHog (EU cloud) for visit recordings and heatmaps, kept in memory only, so it sets no cookie either.
Does data leave the EU?
Yes. Rymdskottkärra AB is in Sweden, and much of the data stays in the EU, but not all of it:
- Downloads and updates come from GitHub (United States), which sees the IP address.
- Error reports, feedback, and signups create notifications in Discord and GitHub (United States). These include an email address if the user attached one.
- Emails with license keys, and notification emails about reports and feedback, pass through Resend and Gmail (both United States companies).
- Cloudflare runs the API server on its global network. Its database and file storage are placed in Eastern Europe, but that placement isn’t a contractual EU guarantee.
- Paddle, which handles payments, is in the United Kingdom.
- If a user sets up cloud AI, their data goes to wherever that provider runs.
Usage stats (PostHog EU cloud), the website (Hetzner, Finland), and newsletter sending (AWS, Stockholm) stay in the EU.
Subprocessors
These companies process data on Cmdr’s behalf.
Cloudflare (Workers, D1, R2, KV)
- What: The API server. Its database holds download records, update checks, usage stats, crash reports, feedback, and the list of issued licenses. Its file storage holds error-report zips.
- Where: The database and file storage are placed in Eastern Europe, but not locked to the EU by contract. The API code and the KV key-value store run on Cloudflare’s global network. (Partly outside the EU)
PostHog
- What: Usage stats from the app, which our API server passes on, and visit recordings and heatmaps from the website.
- Where: PostHog EU cloud (Frankfurt, according to PostHog). (In the EU)
Hetzner
- What: The website, self-hosted page analytics (Umami), the newsletter list (Listmonk), and blog comments (Remark42).
- Where: Helsinki, Finland. (In the EU)
GitHub
- What: Source code, release downloads and updates (GitHub sees the IP address), and a private issue tracker where error reports and feedback become issues. The email address and message sit in a separate comment that’s deleted on a schedule.
- Where: United States. (Outside the EU)
Discord
- What: A private notification channel for new crash reports, error reports, feedback, and signups. Includes an email address if the user attached one, and a download link to an error report that expires after 24 hours.
- Where: United States. (Outside the EU)
Resend
- What: Sends license emails (with the license key) and internal notification emails about reports and feedback.
- Where: US company. It sends Cmdr’s email from its Ireland region (eu-west-1). (Partly outside the EU)
Google (Gmail)
- What: Every email sent to an @getcmdr.com address, including security@, lands in a Gmail inbox. So do the notification emails above.
- Where: United States. (Outside the EU)
Amazon Web Services (SES)
- What: Sends newsletter emails.
- Where: Stockholm, Sweden (eu-north-1). (In the EU)
Paddle
- What: Payments, as merchant of record. Paddle keeps the buyer’s payment details; Cmdr never sees card numbers.
- Where: United Kingdom. (Outside the EU)
Services with no user data: healthchecks.io and UptimeRobot (uptime monitoring), and GitGuardian (scans the source code for leaked secrets). Hugging Face serves optional model downloads that the user starts.
What is stored where, and for how long
On the user’s Mac
Cmdr keeps its data in ~/Library/Application Support/com.veszelovszki.cmdr/ and its logs in
~/Library/Logs/com.veszelovszki.cmdr/. Cmdr doesn’t add its own encryption, so this data is as safe
as the Mac’s FileVault. It includes:
- An index of every file and folder name and path on each indexed drive, including network shares.
- For image search: text read from images (OCR), tags, and image fingerprints.
- A log of every copy, move, rename, and delete, with paths (up to 3 GB by default).
- Search and selection history, AI chats, and the AI assistant’s notes.
- Server addresses and usernames for saved network connections, settings, and the license key.
- Logs with full paths, up to 200 MB by default. Paths are cleaned only when a report is sent, not in the local file.
Passwords and API keys (for SMB, SFTP, WebDAV, and cloud AI) are stored in the macOS Keychain, never in Cmdr’s settings files.
On Cmdr’s servers
A daily job on the API server deletes data on this schedule:
- Update checks: Deleted after seven days. Daily totals per version are kept.
- Usage stats (heartbeats and feature events): Deleted after two years.
- Download records: IP hash and browser user agent removed after 90 days. Version, architecture, country, and referrer are kept.
- Crash reports: Email and report id removed after 90 days. The technical part (versions, crash location) is kept with no time limit.
- Error reports: Email, notes, and the issue-tracker comment removed after 90 days. The 90-day deletion of the report zip itself isn’t active yet, so older zips currently exist.
- Feedback: Email removed after two years. The message is kept.
- Issued licenses: Buyer email and license record kept with no time limit.
- App feature events (PostHog): PostHog’s free plan keeps them for at least one year and sets no end date. PostHog doesn’t offer a shorter setting.
- Website visit recordings (PostHog): Deleted after 30 days.
- Purchase records at Paddle: Seven years, as Swedish accounting law requires. Paddle keeps these.
Nothing in Cmdr’s code deletes old Discord notifications, emails in the Gmail inbox, or Resend’s delivery logs.
Signing, notarization, and updates
- Code signing: Developer ID Application: Rymdskottkarra AB, Team ID
83H6YAQMNP, bundle idcom.veszelovszki.cmdr. It runs on macOS 10.15 and later. - Notarized by Apple, with the ticket stapled to the app.
spctlreportssource=Notarized Developer ID. - Hardened runtime is on, and the released version 0.47.0 has no entitlements at all.
- Code requirement for a PPPC profile (to grant Full Disk Access through MDM):
identifier "com.veszelovszki.cmdr" and anchor apple generic and certificate 1[field.1.2.840.113635.100.6.2.6] /* exists */ and certificate leaf[field.1.2.840.113635.100.6.1.13] /* exists */ and certificate leaf[subject.OU] = "83H6YAQMNP". It stays the same across updates, so a Full Disk Access grant survives them. - Downloads: a disk image (DMG) from GitHub Releases, or the Homebrew cask. Each release
publishes SHA-256 checksums. There’s no
.pkginstaller yet. - Build provenance: every file in a release carries a signed
attestation (SLSA Build Level 2) saying which
commit and which GitHub workflow built it. To check a download, run
gh attestation verify <file> --repo vdavid/cmdrwith the GitHub CLI. - SBOMs: each release also includes software bills of materials in CycloneDX format, one for the Rust dependencies of each processor type and one for the JavaScript dependencies. From the next release on, they’re signed and tied to the builds they describe, the same way.
- Updates: the app downloads the new version from GitHub and checks its Ed25519 (minisign)
signature against a public key built into the app, before writing anything to disk. It only installs a
version newer than the one running, so an attacker can’t force a downgrade. macOS checks the Apple
signature again when the app starts. If the app is in an
/Applicationsfolder the user can’t write to, the update asks for an administrator password. - Turning updates off: per user only, in Settings > Updates & privacy. There’s no central way to pin a version yet.
- Signing keys: the release build signs with keys stored as GitHub secrets. The GitHub account that controls them signs in with two-factor authentication, using hardware security keys. Every signing key also has an encrypted backup outside GitHub.
Sandbox and permissions
Cmdr is not App Sandboxed and isn’t on the Mac App Store. The sandbox only lets an app open files the user picks one by one, which doesn’t work for a file manager. Cmdr runs as the logged-in user and can reach what that user can reach.
Full Disk Access: during first-time setup, Cmdr asks the user to grant it in System Settings, so macOS doesn’t ask separately for every protected folder. The user can say no; Cmdr then works with the usual macOS prompts.
Other macOS permissions Cmdr may ask for, and why:
- Desktop, Documents, and Downloads folders: to browse them.
- Network volumes and removable volumes: to browse network shares, USB drives, and SD cards.
- Local network: to connect to SMB file servers directly and find them on the network.
- Music and Photos: to read file metadata for icons and thumbnails. Cmdr doesn’t read the libraries.
Other things Cmdr does on the system that a reviewer might notice:
-
While an Android phone or camera is connected over USB (MTP), Cmdr pauses the macOS
ptpcameradservice, which would otherwise take the device, and starts it again afterwards. - It can read an SMB password that another app saved in the login keychain, only when the user connects, and macOS asks the user first.
-
The optional local AI runs
llama-server(from llama.cpp, SHA-256 pinned at build time and signed with Cmdr’s certificate) as a separate process, listening on127.0.0.1only. -
The optional MCP server, which lets outside AI tools control Cmdr, is off by default. When on, it listens
on
127.0.0.1only. Deleting and other actions that skip Cmdr’s confirmation need an access token; other commands are open to any program on the same Mac. -
Cmdr opens no port that other machines can connect to: everything it listens on is
127.0.0.1. The one exception is Bonjour (mDNS, UDP port 5353, over IPv4 and IPv6), which finds SMB servers on the local network. Firewall tools like Little Snitch may list the answers from other devices on the network as incoming connections to Cmdr.
AI features and your files
AI is off by default. Cmdr has no AI service of its own and never sees prompts or answers. A user can pick:
- Local AI: Cmdr’s own model, which runs on the Mac (downloaded on request). Nothing leaves the Mac.
- Cloud AI, with the user’s own API key where the service needs one: OpenAI, Anthropic, Google Gemini, Groq, Together AI, Fireworks AI, Mistral, OpenRouter, DeepSeek, Qwen (Alibaba), xAI, Perplexity, Azure OpenAI, a custom endpoint, or an Ollama or LM Studio server, which can run on the same Mac or on another machine. The app talks straight to that provider, under that provider’s terms. The key is kept in the macOS Keychain, and Cmdr won’t send it over plain HTTP except to the same Mac.
Nothing reaches a cloud AI service until the user turns on “Allow cloud AI” in Settings, which lists what each feature sends. The app’s backend enforces this for every AI feature. Cmdr’s own on-device model needs no switch, because nothing leaves the Mac.
With cloud AI, this is what reaches the provider:
- Ask Cmdr (the assistant): file and folder names, paths, sizes, and dates. When the user’s question needs it, also parts of text files, text from PDF pages, archive listings, photo metadata (which can include GPS location), and text read from images. The assistant can’t change or delete files.
- Folder name suggestions, select-by-description, and natural-language search: up to a few hundred file and folder names from the current folder, or the search text.
Text recognition in images, image tags, and image search always run on the Mac, using Apple’s built-in frameworks. IT can’t yet turn AI off centrally or limit which providers are allowed.
How Cmdr is built
The full answer to “Do you have a secure development lifecycle, and do you keep the software up to date?”, stage by stage and with measured numbers, is on its own page: How Cmdr is built and kept up to date. In short:
- The code that touches files, the network, and the system is Rust. 135 automated checks, including about 9,500 Rust tests with deliberately hostile cases, run during development and again on GitHub after each change.
- Development is AI-assisted. One person owns every change; as a one-person company, there’s no second-person code review.
- 22 releases in the last 92 days. New dependency versions wait three days before use, and known vulnerabilities in dependencies are scanned for automatically.
- The app installs updates by itself. About 52% of active installs run a new release within 24 hours.
Data safety (how Cmdr avoids losing files during copies and deletes) has its own page: How Cmdr protects your files.
Company, license, and continuity
- Company: Rymdskottkärra AB, Vattmyragränd 47, 177 39 Järfälla, Sweden. Org. nr 559471-0401, VAT SE559471040101. Swedish law applies.
- Team: one person, David Veszelovszki, designs, builds, and ships Cmdr (over 98% of all commits are under his name). He holds every signing key.
- License: Business Source License 1.1. Free for personal use; commercial use needs a paid license. Each version converts to AGPL-3.0-or-later three years after its release (the current change date is 2029-09-19).
- If the company stops: the full source is public today, and each version becomes open source on its change date. There’s no faster continuity promise in the terms yet.
- Terms: the terms and the privacy policy. For company agreements, write to [email protected].
Report a vulnerability
Email [email protected], or use GitHub’s private reporting (the Report a vulnerability button on the repository’s Security tab). There’s no PGP key, by choice: send details you’d rather not email through GitHub’s private reporting. Please don’t open a public GitHub issue. The full policy, including scope and safe harbor, is SECURITY.md on GitHub, also linked from security.txt. Only the latest version gets fixes. What to expect:
- Acknowledgment within five business days.
- A first assessment within 14 days.
- A fix for critical and high-severity issues within 30 days where technically possible, and within 90 days for the rest.
- Status updates at least every 14 days until the issue is closed.
Not in place yet
These are the gaps a careful review would find. They’re listed here so you don’t have to look for them.
- No central administration. No MDM configuration profile or managed preferences. Every setting (usage stats, crash reports, updates, AI) is per user, and the user can change it back.
- Usage stats and crash reports are on by default. Each user can turn them off.
- No update control for IT. Updates install automatically. There are no update channels, no staged rollout, and no way to pin a version centrally.
- No
.pkginstaller and no published PPPC profile for granting Full Disk Access through MDM. The code-signing requirement on this page is what such a profile needs. - Data leaves the EU (see above), and Cloudflare storage isn’t locked to the EU jurisdiction.
- No data processing agreement (DPA) ready to sign.
- The 90-day deletion of error-report zips isn’t active yet.
- Error-report cleaning has known gaps: a file name in free text, or a search query, can be included.
- No central control over AI. IT can’t disable AI or limit which providers users can pick.
- No reproducible builds, and release tags aren’t signed. Each release publishes SHA-256 checksums and signed build provenance. The SBOMs are published but not yet signed; that starts with the next release.
- No second-person code review. Cmdr has one maintainer, and development is AI-assisted. Automated checks stand in for a reviewer (details).
- One maintainer account can publish a release to every install, and the signing keys are GitHub repository secrets without a protected environment.
- No threat model for the app as a whole. Security decisions are written down per part of the app.
- Checks on GitHub run after a change lands, on Linux. A release waits for a full, green run of the commit it’s cut from, but the maintainer’s release script enforces that, not GitHub. The macOS-only code and the macOS end-to-end tests run only on the maintainer’s Mac.
- No automated tests on older macOS versions. A release-time check catches system frameworks and functions that are too new for them.
- No third-party audit or penetration test, and no SOC 2 or ISO 27001.
- No fuzzing, although Cmdr parses untrusted input (network protocols, archives, PDFs, images).
- One person maintains Cmdr and holds all signing keys. There’s no continuity clause in the terms and no written support commitment.
- No offline license file. A commercial license that can’t reach
api.getcmdr.comfor 30 days falls back to the free personal tier. - Local data isn’t encrypted by Cmdr, so it relies on FileVault. There’s no option to exclude Cmdr’s index from backups.
- Not tested behind a TLS-inspecting proxy, and PAC files are untested.
- No published security advisories yet, so there’s no track record of how Cmdr handles a reported issue.