SiteCMD does not upload your source code
Desktop audits run on your device and CLI audits run on the machine or CI runner that starts them. SiteCMD never uploads source files to its service. This page names the product's fixed network destinations and the dynamic classes controlled by a scan target or your own configuration, so you can verify the boundary yourself.
See how to verify it yourselfDesktop scan data stays on your machine
Derived scan results, issue history, scores, and project settings are stored in a local SQLite database. They do not reach a SiteCMD server unless you connect that site.
- Your source code, file paths, and file contents
- Page HTML, response bodies, and screenshots
- Scan results, scores, and issue history, unless you connect the site
- Project names, URLs, and configuration, unless you connect the site
- Core Web Vitals measurements and accessibility results, which stay in the local scan record
- Cookies, storage, or cache shared with your browser or carried over between scans
- Any new window, any download, or any top-level navigation to an internal address
- On macOS and Windows, any subresource request to a loopback, private, link-local, carrier-grade NAT, or reserved address or to a local hostname: private-network rules block those before the page loads, and the browser layer refuses to run if the rules fail to install. A scan of your own localhost dev server still loads that server's assets
- Any WebRTC or WebTransport connection: those interfaces are removed from every frame before the page's scripts run, so a page cannot open a connection around the rules
- On Linux, anything from this layer at all: the platform webview has no subresource filter yet, so web scans there skip Core Web Vitals and accessibility analysis rather than load the page with your local network reachable
- Any query to a SiteCMD-controlled or hardcoded third-party DNS service
- Scan results, page content, or anything beyond the domain name being looked up
Local scanning still makes network requests from your machine. It contacts the target and public subresources the page names, your configured DNS resolver, rdap.org for domain registration, and api.osv.dev for recognizable front-end library advisories. Those lookups do not send source files or completed scan results to SiteCMD.
- The scanned page itself, loaded in a hidden private webview to measure Core Web Vitals and, when accessibility analysis is on, run axe-core. The subresources that page then requests - images, scripts, stylesheets, fonts, fetch calls - are fetched by the platform's browser engine to the public hosts the page names, as they would be if you opened it yourself; SiteCMD does not choose them. The one request the private-network rules below cannot see is a public hostname that resolves to a private address, which is in the same position it would be in your own browser. Scheduled scans run this layer too
- The scanned site's domain name, as standard DNS queries (SPF/DMARC/DKIM/MX/DNSKEY/CAA, plus a CNAME and address lookup for the www subdomain to catch dangling aliases) to the machine's own configured DNS resolver - the same resolver every other app on the machine uses
The far side of that conversation is documented too. What the scanner requests lists every kind of request a scanned site receives, the identity SiteCMD sends, and how to block it.
Connecting a site, and what that changes
A connected site is the one feature that sends findings to a SiteCMD server. It is off until you connect one, there is no background sync, and an installation that never connects never contacts that host at all.
What travels is a finding's identity, not its source evidence: the check, its severity, the route on your site it fired on, and for a code finding a keyed hash of where it fired. Source files, raw paths, and line numbers have no field in the connected submission. The payload inspector shows the exact serialization of the snapshot it reads. A later sync rebuilds the payload from current local and connected state, so its sequence, deployment, or findings can differ.
Connected CLI commands can make the same bounded calls from a CI runner. A trusted GitHub Actions submission also requests a short-lived workload identity from GitHub's runner-provided *.actions.githubusercontent.com endpoint. SiteCMD sends that identity to the connected service with the site-scoped CI request, never with source files or raw locations.
Ownership verification is service-side. When you ask SiteCMD to verify a site, the service makes either one bounded GET to /.well-known/sitecmd-site-verification on that site or a TXT lookup for _sitecmd through cloudflare-dns.com.
Connecting a site also changes who does the scanning. A connected site can be scanned from SiteCMD's own infrastructure, on a schedule and with the app closed, and those requests leave our network rather than yours. Fixed third-party hosts used by that scan are cloudflare-dns.com for DNS, api.osv.dev for recognizable front-end library advisories, and rdap.org for domain registration expiry. A full scan can also fetch public HTTPS subresources named by the page. Every hosted request crosses the documented method, resource-type, scheme, port, and private-address policy.
What a hosted scan sends to your own site, which no capture on your machine can show you because it never crosses your wire:
- The routes you chose for the scan, fetched as ordinary GETs under the same SiteCMD identity a desktop scan sends, but from Cloudflare's network rather than from anyone's laptop. There is no fixed SiteCMD address to allowlist: the source address varies by the location that ran the scan
- A bounded set of probes about the entry route, each one a GET or a HEAD: the favicon and web app manifest the page declares, /privacy and /terms, a deliberately absent path to see how the site answers a 404, the page again with a foreign Origin header to test CORS reflection, the page again without following its redirects to trace the chain, the www variant of the hostname, a sweep of common redirect parameters on a short list of common paths to test for an open redirect, and a sample of the links the page points at, internal and external, to find the broken ones
- On a full profile, a fresh Cloudflare Browser Run context renders each route and can request public HTTPS scripts, stylesheets, images, fonts, XHR, and fetch resources from any host the page itself names. Chromium can request those resources concurrently. SiteCMD intercepts every request, fetches each bounded response through Cloudflare Workers public egress under the same URL and method policy, and fulfills it into the browser. Target hosts receive the SiteCMD identity, not Browser Run's automatic request headers. SiteCMD retains the resulting bounded browser facts, verdicts, and proxy-adjusted timing samples, not the rendered document or response bodies
And the bounds it runs under, which matter more than usual for the same reason:
- Any caller-selected scan target outside the connected, verified site's environment URL and canonical route scope. Browser subresources are page-controlled rather than caller-supplied and still have to pass the per-request public-HTTPS policy
- Response bodies, rendered DOM, or query strings into any store, log, trace, or error report: only derived verdicts and numeric timing samples survive the page step
- Any method but GET, HEAD, and the browser's own OPTIONS preflights, on your origin or any other, so that scanning your page can never become a way of operating it
- Any request over plain HTTP: the hosted address discipline refuses a non-HTTPS URL before it is fetched, which is why the check that asks whether http:// redirects is reported as unanswered from this vantage rather than graded
Operational calls, named and minimal
A small fixed set of calls keeps the app licensed and up to date and resolves your dependencies. Each sends only what it needs and is named in the table below. APIs for integrations you connect are a user-selected destination class described separately.
Analytics and crash reports, off by default
Both are opt-in and stay off until you turn them on. When enabled, they send only anonymized, sanitized diagnostics, never your scans, source, or credentials. The table below lists exactly what each one carries.
Dynamic destinations are disclosed by class
Some legitimate destinations cannot have one hostname in advance: the site and public subresources being scanned, APIs for integrations or deployment providers you connect, and public HTTPS webhook URLs you configure. Those classes are described here and in the privacy reference. They are not presented as a finite fixed-host list.
Fixed hosts and senders
This table lists SiteCMD infrastructure plus built-in lookup, identity, and delivery hosts, with the data each request carries. Destinations selected through integrations, deployment providers, scan content, or webhook configuration are described by class above. "Sent by" distinguishes traffic from your machine, a CI runner, and SiteCMD's service.
| Call | Sent by | Host | Sends | Never sends |
|---|---|---|---|---|
| License activation | Your machine | api.lemonsqueezy.com | Your license key; A machine-scoped activation identifier: a SHA-256 hash of your device hostname and username encoded as a 16-character hex string prefixed with 'sitecmd-'; the raw hostname and username are never transmitted | Raw hostname or username; Any scan result, source file, project name, or URL |
| License validation | Your machine | api.lemonsqueezy.com | Your license key; The per-activation instance ID issued when you activated | Any scan result, source file, project name, or URL |
| Fix-guide catalog activation | Your machine | activation.sitecmd.com | Your license key; The per-activation instance ID issued when you activated; A random nonce generated for the attempt, so a network retry cannot activate twice | Any scan result, source file, project name, or URL |
| Fix-guide catalog updates | Your machine | catalog.sitecmd.com | The daily manifest request sends an opaque entitlement token issued at catalog activation (not your license key), the app version, and the installed catalog version; the selected channel is part of the request path; A follow-up pack download sends the same opaque token and the content hash named by the manifest, so a publish landing mid-download cannot hand back a different release | Your license key; Any scan result, source file, project name, or URL |
| Domain expiry lookup (RDAP) | Your machine | rdap.org | The scanned site's registrable domain name (in the request URL), to read the public registration record's expiry date; rdap.org redirects to the TLD registry's public RDAP endpoint | Scan results, page content, credentials, or project configuration |
| PageSpeed Insights (web performance) | Your machine | www.googleapis.com | The URL being measured (the scanned site or a project's environment URL) and the strategy (mobile or desktop), when you open Web Vitals or refresh a dashboard's performance signals; Your optional PageSpeed API key as a query parameter, only if you have stored one to raise Google's rate limit | Scan results, source file content, or project configuration |
| Update check | Your machine | releases.sitecmd.com | Current app version; Operating system / platform identifier | Any scan result, source file, project name, or URL |
| Usage analytics | Your machine | telemetry.sitecmd.com | App version and build channel; Operating system family and CPU architecture; Your subscription tier as a plan name only ("free" for the complete local workbench, or the name of an existing subscription's legacy plan; no license key or billing details); Anonymous install identifier (random UUID, not linked to an account); Event name and workflow status; Aggregate counters such as issue totals by severity | Scan targets, project names, source code, credentials, license keys, page content, raw logs |
| Crash and error reports | Your machine | o4511662343127040.ingest.us.sentry.io | Sanitized error message and exception type; Sanitized stack frame function names and filenames; Sanitized breadcrumb trail (last 30 app events, free-form text scrubbed) | URLs, file paths, emails, tokens, license keys, source snippets, request bodies, raw logs, user identity |
| Connected site sync | Your machine | connect.sitecmd.com | The site's URL, and the alias you give it, when you connect it; Schema version, connected site and environment identifiers, submission and event sequence values, and observation and evaluation timestamps; Check identifiers, severity, confidence, and occurrence counts for each finding a scan produced; The routes on your own site that a web finding fired on; Keyed hashes of the code locations a code finding fired on, computed under a key that stays on your device; Commit SHAs, so the service can tell a current scan from a stale one; Detected framework name and version; Engine and check-registry versions, the capability manifest digest, execution profile, detected stack facts, and check coverage; Timing measurements and the route each was measured on; Privacy-preserving correlation pairs between related finding groups; The issue decisions you made locally, once when you connect: dismissals with their policy, and fixes you claimed | Your source code, file paths, or file contents; Line numbers; Page HTML, response bodies, or screenshots; Dependency lists or lockfiles; Integration credentials |
| Connected CI operations | CI runner | connect.sitecmd.com | The connected site identifier and site-scoped CI token; Deployment identifiers, commit SHAs, refs, targets, publication state, and ordering facts supplied by the CI job or connected service; For gate and evidence submission: check identifiers and privacy-preserving code finding identities built from the checkout | Source files or file contents; Raw file paths or line numbers; The encrypted connection export's passphrase or fingerprint key |
| Connected-site ownership verification (DNS) | SiteCMD's service | cloudflare-dns.com | A TXT query for _sitecmd on the domain the user asked SiteCMD to verify | Account identity, findings, source, credentials, or scan results |
| GitHub Actions signature verification | SiteCMD's service | token.actions.githubusercontent.com | One GET for GitHub's public OIDC signing-key set, cached by the service | The workload identity, CI token, findings, source, or account data |
| Connected alert and verification email | SiteCMD's service | api.resend.com | The verified destination email address; The transactional, alert, or digest content selected by the connected notification policy | Source files, file paths, credentials, page content, or local scan history |
| Hosted DNS resolution and domain checks | SiteCMD's service | cloudflare-dns.com | The hostname of every URL the hosted transport or isolated browser is about to fetch, resolved over Cloudflare's public DNS-over-HTTPS resolver before each hop as an A and AAAA lookup, so an address in a blocked range is refused before anything is requested. That is your own site's hostnames, plus redirect targets, external links the transport checks, and public subresource hosts named by the page. The browser never opens a target socket: the Worker fetches the response through public egress and fulfills it into Chromium; For the connected site's registrable domain: A, AAAA, SPF, DMARC, common DKIM selector, MX, DNSKEY, CAA, and www CNAME/address questions used by the hosted domain checks | Any name your own site did not lead the scan to: every hostname resolved here came from your scan scope or your page's own markup; Scan results, page content, or which account the scan belongs to |
| Hosted front-end vulnerability check (OSV) | SiteCMD's service | api.osv.dev | Names and exact versions of recognizable front-end libraries exposed in public script URLs, batched in one OSV query; Advisory IDs returned by that batch, to retrieve severity, references, and fixed-version details | Page HTML, the scanned URL, source files, lockfiles, credentials, scan results, or the connected account identity |
| Hosted domain expiry lookup (RDAP) | SiteCMD's service | rdap.org | The connected site's registrable domain in the request URL; rdap.org redirects to the TLD registry's public RDAP endpoint | Page content, credentials, scan results, project configuration, or the connected account identity |
| Dependency and vulnerability lookups | Your machine | registry.npmjs.orgpypi.orgrepo.packagist.orgcrates.iorubygems.orgproxy.golang.orgapi.wordpress.orgupdates.drupal.orgapi.osv.dev | Package names and versions | Your manifests, lockfiles, or source |
Releases are signed, and you can check them
Desktop updates, the CLI archives, and the CLI installer all verify against one minisign public key before anything runs. The key is published here and on the download page, and each release ships a SHA-256 checksum list next to its installers.
- Minisign public key:
RWTtzNh0gmMU/8O1AJBbQbUEy9oD5lpqL/dV0qRqlpsCldfWNWgxr5kE(key idFF14638274D8CCED) - The desktop updater refuses a bundle whose signature does not verify against this key, so a compromised release server cannot push a tampered build.
install.shdownloads the CLI archive, its checksum, and its signature, verifies both against this key, and confirms the binary reports the requested version before it installs the binary. The installer uses/usr/local/binwhen writable and otherwise uses~/.local/bin; if that directory is not already onPATH, it prints the export command to run in your shell.
Don't trust us. Watch the traffic.
Run a website scan with no integrations or connected site. You will see the site and public subresources it names, your configured DNS resolver, rdap.org for registration expiry, and api.osv.dev for recognizable front-end library advisories. None of that relays source or scan results to SiteCMD. Open Web Vitals afterward and you will also see Google PageSpeed Insights at www.googleapis.com. Run the separate Updates workflow to observe dependency registry and advisory lookups; Code Scan itself reads the checkout without making those calls.
Run your own capture
- macOS: enable Little Snitch alert mode, or run a tcpdump session scoped to the SiteCMD process, then start a scan.
- Any platform: capture with Wireshark and watch the scan's destinations. Wireshark filters by host and port, not by process, so quit other networked apps first, or use Little Snitch or tcpdump to scope the capture to SiteCMD.
- During a website scan you will see the target site and public subresources it loads. You will not see source files sent anywhere, and you will not see
connect.sitecmd.comuntil you connect that site yourself. - The separate Updates workflow reaches dependency and vulnerability registries from the table above. It sends package names and versions, never source files or lockfiles.
- At startup you will see the update check (releases.sitecmd.com), and, if you have activated an existing commercial entitlement, license validation (api.lemonsqueezy.com). Finding these confirms this page.
For the full per-endpoint reference, see Privacy and data.