HomeFeaturesDocumentationContactDownload

Privacy Policy

SiteCMD is built local-first. Desktop data stays on your device by default, and CLI data stays on the machine or CI runner that starts the command. SiteCMD does not upload source files to its service. Connected-site findings and operational identifiers are sent only after you configure the connected service. This policy explains what data exists where.

SiteCMD is operated by Brambleworks LLC, referred to here as "we" and "us", and we are responsible for the limited data this policy describes.

Local data and source handling

The following data is stored locally in a SQLite database on your device. None of it is transmitted to us unless you connect that site to the connected service, described under Connected sites below:

  • Scan results, scores, and issue history
  • Project configurations and URLs
  • Score trends and historical data
  • Report history and export metadata
  • Code scan results and source analysis
  • Event timeline data
  • Scheduled scan configurations

Integration credentials (API keys for Google Analytics, Cloudflare, GitHub, Jira, UptimeRobot, etc.) are stored in your operating system's native keychain (macOS Keychain, Windows Credential Manager), not in the database. The desktop app uses them to call the service they belong to; they are not sent to SiteCMD's servers.

A CLI Code Scan reads the checkout on its execution host. In CI, that host is the runner. SiteCMD does not upload source files or raw locations to the connected service, although report formats you choose to publish, such as SARIF or GitHub annotations, are handled by your CI provider under its own configuration and policies.

Data we collect on this website

Email addresses

If you sign up for launch or release notifications on this website, we store your email address in Cloudflare KV. Signup is double opt-in: the address is held as a pending record for 24 hours and joins the list only when you click the confirmation link. We use it solely to notify you about SiteCMD releases, product updates, and material changes to these documents. We do not sell, share, or use your email for any other purpose. We keep it until you ask to be removed, which you can do by contacting us.

Contact form submissions

When you submit the contact form, your name, email, subject category, and message are forwarded to our support inbox through Resend, our transactional email provider. We do not store contact submissions on this website beyond what Cloudflare captures in standard request logs. Resend's handling of message contents is governed by their privacy policy.

Blog comments

Blog comments use giscus and are stored in public GitHub Discussions. When you sign in with GitHub to comment or react, your contribution and GitHub profile are visible to other readers. We moderate these discussions on GitHub. Loading comments connects your browser to giscus; signing in and posting also uses GitHub. You can manage your comments and account through GitHub under its privacy statement.

Purchases and billing

Connected-service access is free during the beta, and this website does not offer a public purchase during that measurement window. Lemon Squeezy continues to manage payment methods, renewals, cancellations, and license keys for existing subscribers. We do not store payment details on this website.

Web server logs

This website is served by a Cloudflare Worker. Cloudflare collects standard request logs (IP address, user agent, pages visited) as part of their service. This is governed by Cloudflare's privacy policy.

Privacy-friendly analytics

This website uses Plausible Analytics to understand aggregate page views and referrals. Plausible does not use cookies and does not build personal profiles. This marketing website does not use Google Analytics, Facebook Pixel, advertising pixels, fingerprinting, or cross-site tracking. (That is separate from the desktop app's optional, read-only Google Analytics integration, which is described below.)

Data SiteCMD transmits

Connected sites

Connecting a site is the one feature that sends your findings to a SiteCMD server, and it is off until you set it up in Settings. There is no background sync: an installation that never connects a site never contacts connect.sitecmd.com, and one that does contacts it when you perform a connected operation. Hosted schedules and deployment integrations can continue operating after you explicitly configure them.

Cloudflare D1 Time Travel keeps provider-managed point-in-time recovery data for its plan-defined window. Before each service deploy, the pipeline also writes a pre-migration database snapshot to R2 in the same Cloudflare account and deletes it after 30 days. These recovery copies are not used for normal product reads and expire under those retention controls.

A connected submission is a versioned snapshot. Its field categories include the site and environment identifiers; schema, submission, and event ordering values; observation and evaluation timestamps; finding checks, severity, confidence, and routes; engine and check-registry versions; execution profile, stack facts, and check coverage; timing measurements; privacy-preserving correlation pairs; and the commit SHA the code side was observed against. When you first connect, it also sends the issue decisions you already made locally, so a site you have been triaging for months does not arrive as a fresh list of problems.

A code finding travels as a keyed hash of where it fired, computed under a per-project key that stays on your device. That is what lets the service recognise the same finding across two scans without ever holding anything that resolves to a file. Your source code, file paths, file contents, line numbers, page HTML, response bodies, screenshots, dependency lists, and integration credentials have no field in that payload. The app's payload inspector shows the exact serialization of the snapshot it reads. A later sync rebuilds the payload from then-current local and connected state, so its sequence, deployment, or findings may differ from the earlier inspection.

When you ask SiteCMD to verify ownership, the connected service performs either one bounded GET to /.well-known/sitecmd-site-verification on the site or a TXT query for _sitecmd through cloudflare-dns.com. The request carries the verification target needed to read the published challenge, not account identity, findings, source, or credentials.

Connecting a site also lets SiteCMD scan it from our own infrastructure, on a schedule and with the app closed. Those requests leave Cloudflare's network rather than your machine. There is no fixed SiteCMD address to allowlist and none to publish: outbound requests from Cloudflare Workers leave the anycast network, and the source address varies by the location that ran the scan. They identify themselves with the same SiteCMD/<version> (+https://sitecmd.com/scanner) string a desktop scan sends, and the scanner page explains what is and is not provable about that.

A hosted scan also contacts Cloudflare's public DNS-over-HTTPS resolver (cloudflare-dns.com). It receives each hostname the transport scanner or isolated browser is about to fetch as an A and AAAA lookup so an address in a blocked range is refused before the request. That includes public subresource hosts named by the page. For the connected site's registrable domain, it also queries A, AAAA, SPF, DMARC, common DKIM selectors, MX, DNSKEY, CAA, and the www CNAME/address posture. The resolver is not told which account caused the query.

Hosted scans send recognizable front-end library names and exact versions found in public script URLs to api.osv.dev, then retrieve details for advisory IDs OSV returns. They send the registrable domain to rdap.org, which redirects to the TLD registry's public RDAP endpoint for the registration-expiry check. Neither request includes page HTML, source files, credentials, scan results, or connected account identity.

The browser-analysis half loads each selected route in a fresh isolated browser context. Like any browser visit, it may request public scripts, stylesheets, images, fonts, and read-only fetches from hosts named by that page. SiteCMD intercepts those requests, fetches each bounded response through Cloudflare Workers public egress, and fulfills it into the browser. Target hosts may see the requested URL, request headers, and any cookies the page set during that isolated load. SiteCMD blocks unsafe request methods, service workers, WebSockets, media streams, downloads, popups, non-web schemes, and targets in blocked address ranges. The context has none of your personal browser cookies or saved sessions and is destroyed after the route is evaluated.

Page bodies, rendered DOM, query strings, screenshots, and browser storage are never written to a SiteCMD store, log, trace, or error report. Only derived verdicts and timing measurements survive the hosted scan.

The SiteCMD CLI uses one site-scoped CI token for exactly four connected operations: reading the deployment ordering cursor, gate, deploy, and connected --submit. The ordering cursor contains only the site's current deployment identity, whether that credential supports GitHub OIDC attestation, and, when the credential owns the site's selected publish authority, that authority's kind, id, epoch, activation time, and current publish sequence. It contains no findings or other account data. gate sends a code-side candidate from the CI runner but stores nothing: it answers which findings are new against the site's baseline and changes nothing about what the site is known to be. deploy records deployment history, while connected --submit records or converges the deployment and its privacy-preserving code findings.

In a trusted GitHub Actions job, the CLI also requests a short-lived workload identity from the runner-provided *.actions.githubusercontent.com endpoint. That request sends GitHub's runner-provided request token and the connected-service origin as the audience. It does not send source, findings, file locations, or SiteCMD credentials to GitHub. The connected service verifies that identity by fetching GitHub's public signing keys from token.actions.githubusercontent.com; that key request contains no workload identity or account data.

If you authorize a connected Vercel or Netlify deployment provider, the connected service exchanges the provider's authorization code, stores the resulting credential encrypted, and uses it only for the selected provider's project, deployment, domain, and deploy-webhook APIs. This is separate from desktop integration credentials, which remain in your OS keychain and are sent only to their owning service.

Connected alert email is delivered through api.resend.com. Resend receives the verified destination address and the transactional, alert, or digest content selected by your notification privacy mode. A connected webhook sends a signed alert or report payload to the public HTTPS URL you configured. Neither delivery includes source files, raw paths, credentials, page content, or local scan history.

What a connected site sends us is aged out on a schedule, not kept indefinitely: the site's event stream, deployment history, and timing measurements are deleted after 90 days. If you disconnect a site, its remaining state is deleted 30 days later. Request receipts are deleted after 7 days. Erasing a site removes everything at once and leaves only a receipt naming the site identifier and domain, kept for one year so you can prove the erasure happened. A site's current findings and your decisions about them are kept as long as the site stays connected, because they are the baseline the service grades against.

Connected account data

Besides the per-site data above, the connected service keeps a small set of account-level records so that it can tell who may act on a site and where to send what you asked for:

  • Your account and the installations on it: opaque identifiers, the plan tier, which installations hold admin authority, and an event log of account changes. Kept for the life of the account.
  • Alert destinations: each email address you add, whether it has confirmed, and whether deliveries to it have bounced or been reported as spam. An address receives mail only after it confirms through a link we send it, and every alert and digest email carries a one-click unsubscribe that stops mail to that address. Kept until you delete the destination or the account.
  • Webhook URLs and a hash of each webhook secret, CI tokens stored as hashes with their site scope, and notification settings. Kept for the life of the connected site.
  • The alert history for a site, what was raised and how each destination was notified. Deleted after 90 days.
  • Provider connections for Vercel or Netlify: the encrypted provider credential and the project and deployment identifiers it watches. Kept until you revoke the connection.
  • Report links: which report each signed link opens and its expiry or revocation. The record lasts for the life of the site; the link itself stops working at its own expiry.
  • Account recovery requests, made when the last admin device is lost: the request, its status, and the security notices sent to your verified destinations. Kept for the life of the account.

Alert, digest, verification, and security email is sent from alerts@sitecmd.com through Resend. Queued email content is purged once the provider gives a final answer, and the delivery record itself is deleted 7 days later.

Erasing every site does not erase the account. To erase the account itself, with its destinations, installations, and recovery records, contact us; the service performs that erasure as one operation. We can also produce a machine-readable export of everything the service holds for an account or a site on request.

Update checks

SiteCMD periodically checks for application updates by contacting releases.sitecmd.com. This request includes your current app version and operating system platform identifier. No personal data, scan results, or project information is included. We keep an aggregate count of these update checks, and of installer downloads, broken down only by app version and platform, so we can see how many installs are active and how many downloads each release gets. These counts contain no identifier for you or your device.

License activation and validation

When you activate an existing license, SiteCMD sends your license key and a machine-scoped activation identifier to LemonSqueezy's API at api.lemonsqueezy.com. The activation identifier is a SHA-256 hash of your device hostname and username encoded as a 16-character hex string - your raw hostname and username are never transmitted. Ongoing validation requests send your license key and the per-activation instance ID returned at activation. No scan data or project information is included. LemonSqueezy's handling of this data is governed by their privacy policy.

Fix-guide catalog

Eligible connected-service and existing-license entitlements receive maintained guidance as a signed catalog the app downloads in the background. Activating such an entitlement also registers this installation with the catalog service at activation.sitecmd.com, sending your license key, the same per-activation instance ID described above, and a random single-use nonce. The service returns an opaque access token; your license key is never sent again after that exchange. Deactivating the license sends the same identifiers to release this installation.

The app checks catalog.sitecmd.com about once a day. The manifest request uses the selected channel in its URL and carries the opaque token, app version, and installed catalog version. If an update is available, a follow-up pack download carries the same token and the content hash named by the manifest. No scan data, project information, or source accompanies either request.

Dependency update checks

The dependency update check queries public package registries for the latest version of each package found in your project: registry.npmjs.org (npm), pypi.org (Python), repo.packagist.org (PHP/Composer), crates.io (Rust), rubygems.org (Ruby), proxy.golang.org (Go), api.wordpress.org (WordPress plugins and core), and updates.drupal.org (Drupal modules). These requests send only the package name in the request URL or as a query parameter. They do not send your lockfiles or any source file content.

SiteCMD also queries the OSV vulnerability database (api.osv.dev) to check for known security advisories. This is a single batched POST request that sends the package names and currently installed versions of packages found in your project. Web scans use the same database to check well-known front-end libraries (jQuery, Bootstrap, and similar) whose names and versions appear in the scanned page's script URLs. No source file content, lockfiles, or credentials are included.

PageSpeed Insights (web performance)

Web Vitals uses Google's PageSpeed Insights service (www.googleapis.com). This call is made on demand from the desktop app, when you open the Web Vitals detail or refresh a project dashboard's performance signals; it does not run on a background schedule. The request sends the URL being measured and the strategy (mobile or desktop). If you add an optional PageSpeed API key under Settings, it is stored in your OS keychain and appended to these requests to raise Google's rate limit; without one the call is made without a key. No scan results, source file content, or project configuration are sent.

Browser analysis during web scans

To measure Core Web Vitals, and to run axe-core when accessibility analysis is on, SiteCMD loads the page in a hidden webview. That window is private: it shares no cookies, storage, or cache with your browser or with earlier scans, it cannot open windows or start downloads, and every top-level navigation it attempts, including redirects and meta refreshes, is re-checked against the same network policy gate, so a public page cannot redirect the analyzer to an internal address. The hidden browser keeps a narrower boundary than the target you named: it loads public and localhost targets only, so a scan of an address on your own network reports Core Web Vitals and accessibility analysis as unavailable and keeps every other check.

The page's own subresources, its images, scripts, stylesheets, fonts, and fetch calls, are issued by the platform's web engine to the hosts the page names. SiteCMD does not choose them, but it does fence them. On macOS and Windows it installs private-network rules in the webview before the page loads: any subresource request to a loopback, private, link-local, carrier-grade NAT, or otherwise reserved address, or to a local hostname, is blocked, and if those rules fail to install the browser layer does not run at all. A scan of your own localhost dev server still loads that server's assets. The WebRTC and WebTransport interfaces are removed from every frame before the page's scripts run, so a page cannot open a connection around the rules. What the rules cannot see is a public hostname that resolves to a private address; a request like that is in the same position it would be in your own browser. On Linux the platform webview offers no subresource filter yet, so the browser layer does not run there: Linux web scans report Core Web Vitals and accessibility results as unavailable and keep every other check.

Nothing from those requests reaches SiteCMD; the measurements are stored locally with the rest of the scan. Worth knowing because scheduled scans run this layer too, so a site that starts serving something hostile does so with nobody watching. If that matters for a particular site, run its scans manually rather than on a schedule.

Domain checks during web scans

The web scan's domain checks look up the scanned site's public DNS records (SPF, DMARC, DKIM, MX, DNSKEY, CAA, and a CNAME/address lookup for the www subdomain) through your machine's own configured DNS resolver, the same resolver every other application on your computer uses. SiteCMD never routes DNS queries to its own or any hardcoded third-party DNS service. To read the domain's public registration expiry date, SiteCMD queries the RDAP redirect service (rdap.org), which forwards to the TLD registry's public RDAP endpoint. These requests contain only the domain name being scanned (and, for the www alias check, the hostname its CNAME record points at).

Optional usage analytics

The desktop app can send anonymous product usage events to telemetry.sitecmd.com, a SiteCMD-controlled Cloudflare Worker, if you opt in. These events help us understand which workflows are used and where scans or app flows fail. They include app version, build channel, operating system family, anonymous install identifier, event name, your subscription tier as a plan name only ("free" for the complete local workbench, or the name of an existing subscription's legacy plan; never a license key or billing details), and small counters such as issue totals by severity. Raw event rows are retained for no more than 90 days before scheduled deletion. Each accepted event also increments a de-identified aggregate counter (event name, app version, build channel, operating system family, architecture, and tier) that carries no install identifier. Because nothing links those counts back to an individual install, a deletion request cannot single them out; they are not retained beyond three months. They do not include scan URLs, website content, source code, local file paths, project names, credentials, license keys, raw logs, request bodies, or integration data.

Optional crash and error reports

SiteCMD sends sanitized frontend errors and failed app-command diagnostics to Sentry (o4511662343127040.ingest.us.sentry.io) only if you opt in through the consent prompt or under Settings → Privacy. Session replay, broad performance tracing, autocapture, and default personal data collection are disabled. Error payloads are scrubbed before sending to remove URLs, filesystem paths, email addresses, secrets, license keys, source snippets, request bodies, and provider responses.

Website scanning

When you scan a URL, SiteCMD makes HTTP requests directly from your machine to the target website. These requests are visible to the website's server in their access logs, like any other browser visit. SiteCMD identifies itself in the User-Agent header. No data from these requests is sent to us.

Third-party integrations

When you connect integrations (GA4, Cloudflare, GitHub, etc.), SiteCMD makes API calls directly from your machine to those services using credentials stored in your OS keychain. The data returned is cached locally. We do not proxy these requests and have no access to the data exchanged.

Google Analytics and Search Console data

When you connect Google Analytics or Google Search Console, SiteCMD uses Google OAuth to request read-only access to your own account data: the Google Analytics read-only scope to display your traffic metrics, and the Search Console read-only scope to display your search performance. These requests are made directly from your machine to Google's APIs, and the returned data is cached locally on your device. SiteCMD's servers never receive, proxy, store, or have access to your Google Analytics or Search Console data, and we never use it for advertising or sell it. You can revoke this access at any time from your Google Account permissions page or by disconnecting the integration in SiteCMD.

SiteCMD's use and transfer of information received from Google APIs to any other app will adhere to the Google API Services User Data Policy, including the Limited Use requirements.

Other desktop integrations follow the same transport boundary: the app calls the third-party service directly from your machine using the credential you supplied. That provider receives the request and any issue or report content you explicitly choose to send through an integration action. SiteCMD's servers do not proxy the credential or the provider response.

How we protect your data

Because SiteCMD is local-first, the strongest protection for your sensitive data is that it stays on your device: your Google Analytics and Search Console data are never transmitted to, proxied by, or stored on SiteCMD's servers, and neither are your scan results or project configuration unless you connect that site. The specific safeguards are:

  • Encryption in transit: all requests to Google's APIs (and every other connected integration) are made over HTTPS/TLS with full certificate validation. SiteCMD does not accept invalid or self-signed certificates on these connections.
  • Secure credential storage: Google OAuth access and refresh tokens are kept in your operating system's encrypted credential store (macOS Keychain, Windows Credential Manager, or the Linux Secret Service / libsecret), never in the SiteCMD database and never in plaintext on disk. The database only records that an integration is connected, not the token itself.
  • No central copy: data returned from Google is held on your device, in a short-lived in-memory cache and, where needed for correlation, in the local SQLite database. There is no SiteCMD-hosted copy, so there is no central store of your Google data for us to lose or for an attacker to breach.
  • Revocation and deletion: disconnecting the integration deletes its OAuth tokens from your operating system's credential store. You can also revoke SiteCMD's access at any time from your Google Account permissions page, and permanently delete all locally stored data by removing SiteCMD's data directory.

Data boundaries that always apply

SiteCMD's service never receives:

  • Your source files and file contents
  • Raw file paths and line numbers in connected submissions
  • Your desktop integration API keys or tokens; connected deployment-provider credentials are the explicit exception described above
  • Your analytics, uptime, or search data

The hosted scanner transiently receives and processes bounded public response bodies to derive scan facts. It does not retain page HTML, response bodies, rendered DOM, or screenshots in storage, logs, traces, error reports, or scan reports.

Desktop scans run on your device. CLI scans run on their execution host, which can be a CI runner. If you publish a CLI report or annotation, your chosen CI provider receives that output under its own configuration; SiteCMD does not relay it to the connected service.

Unless you connect that site, in which case what we hold is listed under Connected sites above:

  • Your scan results or scores
  • The websites you scan
  • Your project configurations
  • Your fix history or dismissed issues

Data export and deletion

You can export the desktop database through Settings and delete local scan history, individual scans, projects, or the entire local database. Deleting the application and its data directory removes local SiteCMD data, but it does not erase data for a connected site.

To erase a connected site's remote state immediately, use Settings → Connected → Erase Site Data. The app shows the erasure receipt once so you can retain proof. Disconnecting without immediate erasure starts the 30-day deletion period described above. For a broader account export or privacy request, contact us.

The desktop app also lets you disable telemetry, delete unsent local telemetry, reset the anonymous telemetry identifier, and request deletion of uploaded SiteCMD-hosted telemetry tied to that anonymous identifier. Sentry diagnostic retention and deletion are governed by Sentry's service controls, and we keep those reports limited to sanitized error data.

Service providers

We use a small number of providers to run the services described above. Each processes data only to provide its service to us:

  • Cloudflare: hosting for this website and every SiteCMD service, including Workers, D1, KV, R2, and the isolated browser that runs hosted scans
  • Resend: delivery of contact-form, subscription, and connected alert email
  • Sentry: opt-in crash and error reports from the desktop app
  • Lemon Squeezy: payments, license keys, and billing records for existing subscriptions
  • Plausible: cookie-free aggregate analytics for this website
  • giscus and GitHub: public blog comments and reactions

We are based in the United States and these providers process data there. If you use SiteCMD from elsewhere, the data this policy describes is transferred to and processed in the United States.

Your rights

Depending on where you live, you may have the right to access the personal data we hold about you, to correct or delete it, to receive a copy in a portable format, to object to or restrict certain processing, and to withdraw consent you have given. You also have the right to complain to your local data protection authority. Because most SiteCMD data never reaches us, most of these rights are things you exercise directly on your device; for data we do hold, the controls above and a request to contact us or support@sitecmd.com cover them. We answer within 30 days.

Where a legal basis is required, we process connected-service and billing data to perform our agreement with you; optional analytics, crash reports, and mailing-list data on the basis of your consent; and request logs, rate limiting, and security records on the basis of our legitimate interest in running the service safely. We do not sell personal information and do not share it for cross-context behavioral advertising.

Children

SiteCMD is not directed at children under 16, and the hosted services require you to be at least 18. We do not knowingly collect personal information from children.

Changes

We may update this policy. Changes will be posted on this page with an updated date. Material changes will be communicated through the application and to the verified alert addresses on a connected account.

Contact

Privacy questions: contact us or email support@sitecmd.com. Brambleworks LLC is the controller for the data this policy describes.