HomeFeaturesDocumentationContactDownload

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 yourself

Desktop 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.

CallSent byHostSendsNever sends
License activationYour machineapi.lemonsqueezy.comYour 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 transmittedRaw hostname or username; Any scan result, source file, project name, or URL
License validationYour machineapi.lemonsqueezy.comYour license key; The per-activation instance ID issued when you activatedAny scan result, source file, project name, or URL
Fix-guide catalog activationYour machineactivation.sitecmd.comYour license key; The per-activation instance ID issued when you activated; A random nonce generated for the attempt, so a network retry cannot activate twiceAny scan result, source file, project name, or URL
Fix-guide catalog updatesYour machinecatalog.sitecmd.comThe 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 releaseYour license key; Any scan result, source file, project name, or URL
Domain expiry lookup (RDAP)Your machinerdap.orgThe 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 endpointScan results, page content, credentials, or project configuration
PageSpeed Insights (web performance)Your machinewww.googleapis.comThe 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 limitScan results, source file content, or project configuration
Update checkYour machinereleases.sitecmd.comCurrent app version; Operating system / platform identifierAny scan result, source file, project name, or URL
Usage analyticsYour machinetelemetry.sitecmd.comApp 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 severityScan targets, project names, source code, credentials, license keys, page content, raw logs
Crash and error reportsYour machineo4511662343127040.ingest.us.sentry.ioSanitized 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 syncYour machineconnect.sitecmd.comThe 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 claimedYour source code, file paths, or file contents; Line numbers; Page HTML, response bodies, or screenshots; Dependency lists or lockfiles; Integration credentials
Connected CI operationsCI runnerconnect.sitecmd.comThe 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 checkoutSource 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 servicecloudflare-dns.comA TXT query for _sitecmd on the domain the user asked SiteCMD to verifyAccount identity, findings, source, credentials, or scan results
GitHub Actions signature verificationSiteCMD's servicetoken.actions.githubusercontent.comOne GET for GitHub's public OIDC signing-key set, cached by the serviceThe workload identity, CI token, findings, source, or account data
Connected alert and verification emailSiteCMD's serviceapi.resend.comThe verified destination email address; The transactional, alert, or digest content selected by the connected notification policySource files, file paths, credentials, page content, or local scan history
Hosted DNS resolution and domain checksSiteCMD's servicecloudflare-dns.comThe 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 checksAny 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 serviceapi.osv.devNames 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 detailsPage HTML, the scanned URL, source files, lockfiles, credentials, scan results, or the connected account identity
Hosted domain expiry lookup (RDAP)SiteCMD's servicerdap.orgThe connected site's registrable domain in the request URL; rdap.org redirects to the TLD registry's public RDAP endpointPage content, credentials, scan results, project configuration, or the connected account identity
Dependency and vulnerability lookupsYour machineregistry.npmjs.orgpypi.orgrepo.packagist.orgcrates.iorubygems.orgproxy.golang.orgapi.wordpress.orgupdates.drupal.orgapi.osv.devPackage names and versionsYour 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 id FF14638274D8CCED)
  • 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.sh downloads 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/bin when writable and otherwise uses ~/.local/bin; if that directory is not already on PATH, 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.com until 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.