Security
We have no certifications to show you, so this page shows what Simplytics does, what it deliberately never holds, and what is still wrong with it.
The part that matters most: what is not here
Most analytics breaches hurt because of what the tool kept. Simplytics keeps almost none of it. That is a design choice rather than a security control, but it limits the damage of everything else.
- No passwords. Nothing to hash, leak, reuse or crack. You sign in with Google, GitHub or a link emailed to you.
- No cookies on your visitors, and no identifier reused across sites or days. The daily hash is HMAC-SHA256 over a truncated IP, the user-agent, the domain and the site-local date, under a server-held key. The saved hash can link visits on that site during that day and is deleted with the raw rows, within two nightly runs.
- No raw visit records after the night. Rows exist only to count unique visitors within one day. The nightly job deletes each day once it has ended in the site's own timezone — never more than 48 hours, because the job runs at midnight UTC. Funnel journeys lose their visitor identifier within two nights and are deleted after 90 days.
- No card numbers. Dodo Payments is the merchant of record; we never see them.
- No names, pictures or profiles. Google is asked for
openid emailand GitHub foruser:email. We use the verified address and provider account ID to sign you into the same account.
How the account itself is protected
- Visitors can switch tracking off themselves. The script sends nothing when the browser sends Global Privacy Control or the visitor uses a site's own “don't count my visits” switch; see the opt-out page. A site owner can turn off the Global Privacy Control check, but not its own switch, with
data-honor-gpc="false". - Sessions are opaque 256-bit IDs stored server-side, in an HttpOnly, Secure, SameSite=Lax cookie. Signing out deletes the server record, not just the cookie.
- Emailed sign-in links last 15 minutes, work once, and are stored only as a SHA-256 hash, so a copy of the database is not a set of working keys. Opening one shows which address you are about to sign in as before anything happens. That stops someone mailing you their link.
- Query strings are omitted from request URLs in the site Worker's Cloudflare logs. Sign-in, unsubscribe and checkout links can carry tokens or email addresses there. Cloudflare's automatic request-log URL field included query strings until 2026-09-29 at 14:50 UTC, and a separate cache-error message could still contain a full public-dashboard URL until 15:09 UTC that day. During that time, anyone able to open the operator's Cloudflare account could have seen sign-in links issued in the previous three days; each works once, for 15 minutes. Earlier log entries will age out by the end of 2026-10-02 (UTC). Simplytics keeps no Cloudflare Workers Logs from 2026-10-20.
- Cross-site request forgery has two defences:
SameSite=Laxon the session cookie, and anOrigin/Sec-Fetch-Sitecheck on every request that changes something. The beacons are exempt because they are cross-origin by design, and the webhooks because their HMAC signature proves more than either header could. - Webhooks from the payment provider are checked against an HMAC signature and de-duplicated by event ID before anything is granted or revoked.
- Rate limits per IP protect sign-in, the beacons, the dashboard and the webhooks. Beacons are also limited per site key, so one site cannot use up the account's budget from many addresses.
Transport and headers
- HTTPS is forced at the edge, minimum TLS 1.2, with HSTS for a year including subdomains.
X-Content-Type-Options: nosniff,X-Frame-Options: DENY,Referrer-Policy: strict-origin-when-cross-origin, and aPermissions-Policythat turns off camera, microphone and geolocation.- The two third-party scripts the dashboard loads are pinned to exact versions and checked against Subresource Integrity hashes, so a compromised CDN cannot change them.
Where the data is, and what happens if it is lost
- Analytics live in a Cloudflare D1 database whose primary storage is in the European Union (Warsaw).
- The person who runs it is based in India, so deploys, fault-finding and support mean reaching that EU-hosted database from India. For EU customers' visitor data this raises an international-transfer question that keeping the database in the EU does not settle. The DPA covers it with the EU Standard Contractual Clauses and a published transfer assessment, and names the one case the clauses were not designed for; the privacy policy sets out what limits it.
- Government requests: none. No public authority, in India or elsewhere, has asked for Simplytics data or for access to it, as of 2026-09-23. We update this line at least once a year and would handle a request as the transfer assessment describes.
- Each week a full database export is made through Cloudflare and stored in a private, EU-jurisdiction object store, where a lifecycle rule deletes it 90 days after it is written. The stored copies are in the EU. The job that makes and checks each export runs wherever Cloudflare places it, and Cloudflare does not say where it keeps the temporary files behind the one-hour export link and the database import, so we do not claim those steps stay in the EU. Until 2026-09-23 the export was made on a GitHub-hosted machine; neither the export nor its download link passes through GitHub any more. Each week the new export is loaded into a temporary EU-jurisdiction database, its tables and accounts are counted, and that database is deleted when the check ends, or by a daily cleanup within about two days if the run fails. The verification results we keep are table names, checksums, sizes and counts, not customer-row values. No older backup is read.
- You can export the available analytics reports as CSV at any time, subscribed or not, and delete your account and the analytics it still holds from the Account page. When deletion succeeds, the account record and remaining analytics leave the live database immediately. History already handed to another account stays with that account, along with a minimal record of its source. Backups are the exception, and they expire rather than being purged on request: Cloudflare's point-in-time restore is a rolling window of at most 30 days, and each weekly export is deleted 90 days after it is written, so copies of the data removed by account deletion age out within 90 days. Billing records and an address-level suppression record can remain, as the privacy policy explains. We read backup copies only to recover from a disaster, apart from the weekly restore check above, which loads only the new export into a temporary database.
What is still wrong
These are the open items, in the order we would fix them:
- Our Content Security Policy blocks inline JavaScript and allows scripts only from our own site and three specific, version-pinned library files, which our pages load with integrity checks. Inline styles are still allowed. This reduces the risk from injected scripts; it is not a security guarantee.
- One person builds and runs this. No second pair of eyes on a deploy, no on-call rotation, no separation of duties. The blast radius is small by design, and everything ships through automated tests and a smoke check, but neither replaces a second person. You need not take our word for uptime: an independent monitor outside our infrastructure checks the site every three minutes and publishes the result on a public status page, which stays online when Simplytics does not. There is no uptime guarantee, and nobody is paged at 3am.
- The deploy pipeline can reach the data. Code reaches production through an automated job on GitHub that holds a Cloudflare credential. That credential can replace the main site's code and read and change its database, so a compromised GitHub account, workflow or build dependency could use it to read customer data, including the backups. It has no permission to open the backup storage directly and cannot change the code of the separate backup job. But Cloudflare does not require a separate permission to give the main site's code access to the backup storage, so code deployed with it could read the backups. The job itself never downloads the database or a backup. Moving deploys off GitHub would shrink this risk; that has not been done.
- No SOC 2, no ISO 27001, no third-party penetration test. Each costs more than this product earns. If you need one of them to buy, Simplytics is not the right tool for you yet.
Reporting something
Email nikhil@simplytics.dev. There is no bug bounty and no payout. Reports are read and answered, and /.well-known/security.txt lists what is already known and not worth reporting.
Please do not test against other people's accounts or send traffic that would distort a customer's numbers. A free trial needs no card and gives you a real account of your own to test against.